• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import fs from 'fs';
17import path from 'path';
18
19import {
20  HASH_FILE_NAME,
21  IS_CACHE_INVALID,
22  GEN_ABC_PLUGIN_NAME,
23  GEN_ABC_SCRIPT,
24  blue,
25  reset,
26  ES2ABC,
27  TS2ABC
28} from './ark_define';
29import { initArkConfig } from './process_ark_config';
30import {
31  nodeLargeOrEqualTargetVersion,
32  mkdirsSync,
33  validateFilePathLength
34} from '../../../utils';
35import {
36  isEs2Abc,
37  isOhModules,
38  isTs2Abc
39} from '../../../ark_utils';
40import {
41  genTemporaryModuleCacheDirectoryForBundle
42} from '../utils';
43
44export abstract class CommonMode {
45  projectConfig: Object;
46  arkConfig: Object;
47  cmdArgs: string[] = [];
48  logger: Object;
49  throwArkTsCompilerError: Object;
50  hashJsonFilePath: string;
51  genAbcScriptPath: string;
52  triggerAsync: Object;
53  triggerEndSignal: Object;
54
55  constructor(rollupObject: Object) {
56    this.projectConfig = Object.assign(rollupObject.share.arkProjectConfig, rollupObject.share.projectConfig);
57    this.arkConfig = initArkConfig(this.projectConfig);
58    this.cmdArgs = this.initCmdEnv();
59    this.logger = rollupObject.share.getLogger(GEN_ABC_PLUGIN_NAME);
60    this.throwArkTsCompilerError = rollupObject.share.throwArkTsCompilerError;
61    this.hashJsonFilePath = this.genHashJsonFilePath();
62    this.genAbcScriptPath = path.resolve(__dirname, GEN_ABC_SCRIPT);
63    // Each time triggerAsync() was called, IDE will wait for asynchronous operation to finish before continue excuting.
64    // The finish signal was passed to IDE by calling triggerEndSignal() in the child process created by triggerAsync()
65    // When multiple workers were invoked by triggerAsync(), IDE will wait until the times of calling
66    // triggerEndSignal() matches the number of workers invoked.
67    // If the child process throws an error by calling throwArkTsCompilerError(), IDE will reset the counting state.
68    this.triggerAsync = rollupObject.async;
69    this.triggerEndSignal = rollupObject.signal;
70  }
71
72  initCmdEnv() {
73    let args: string[] = [];
74
75    if (isTs2Abc(this.projectConfig)) {
76      let ts2abc: string = this.arkConfig.ts2abcPath;
77      validateFilePathLength(ts2abc, this.logger);
78
79      ts2abc = '"' + ts2abc + '"';
80      args = [`${this.arkConfig.nodePath}`, '--expose-gc', ts2abc];
81      if (this.arkConfig.isDebug) {
82        args.push('--debug');
83      }
84      if (isOhModules(this.projectConfig)) {
85        args.push('--oh-modules');
86      }
87    } else if (isEs2Abc(this.projectConfig)) {
88      const es2abc: string = this.arkConfig.es2abcPath;
89      validateFilePathLength(es2abc, this.logger);
90
91      args = ['"' + es2abc + '"'];
92      if (this.arkConfig.isDebug) {
93        args.push('--debug-info');
94      }
95      if (this.arkConfig.isBranchElimination) {
96        args.push('--branch-elimination');
97      }
98    } else {
99      this.throwArkTsCompilerError(`ArkTS:INTERNAL ERROR: Invalid compilation mode.`);
100    }
101
102    return args;
103  }
104
105  private genHashJsonFilePath() {
106    if (this.projectConfig.cachePath) {
107      if (!fs.existsSync(this.projectConfig.cachePath) || !fs.statSync(this.projectConfig.cachePath).isDirectory()) {
108        this.logger.debug(blue, `ArkTS:WARN cache path does bit exist or is not directory`, reset);
109        return '';
110      }
111      const hashJsonPath: string = path.join(genTemporaryModuleCacheDirectoryForBundle(this.projectConfig), HASH_FILE_NAME);
112      validateFilePathLength(hashJsonPath, this.logger);
113      mkdirsSync(path.dirname(hashJsonPath));
114      return hashJsonPath;
115    } else {
116      this.logger.debug(blue, `ArkTS:WARN cache path not specified`, reset);
117      return '';
118    }
119  }
120
121  setupCluster(cluster: Object): void {
122    cluster.removeAllListeners('exit');
123    if (nodeLargeOrEqualTargetVersion(16)) {
124      cluster.setupPrimary({
125        exec: this.genAbcScriptPath,
126        windowsHide: true
127      });
128    } else {
129      cluster.setupMaster({
130        exec: this.genAbcScriptPath,
131        windowsHide: true
132      });
133    }
134  }
135
136  protected needRemoveCacheInfo(rollupObject: Object): boolean {
137    return rollupObject.cache.get(IS_CACHE_INVALID) || rollupObject.cache.get(IS_CACHE_INVALID) === undefined;
138  }
139
140  protected removeCacheInfo(rollupObject: Object): void {
141    if (this.needRemoveCacheInfo(rollupObject)) {
142      this.removeCompilationCache();
143    }
144    rollupObject.cache.set(IS_CACHE_INVALID, false);
145  }
146
147  abstract removeCompilationCache(): void;
148}
149