• 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} from './ark_define';
27import { initArkConfig } from './process_ark_config';
28import {
29  nodeLargeOrEqualTargetVersion,
30  mkdirsSync,
31  validateFilePathLength
32} from '../../../utils';
33import {
34  isEs2Abc,
35  isOhModules,
36  isTs2Abc
37} from '../../../ark_utils';
38import {
39  genTemporaryModuleCacheDirectoryForBundle
40} from '../utils';
41
42export abstract class CommonMode {
43  projectConfig: Object;
44  arkConfig: Object;
45  cmdArgs: string[] = [];
46  logger: Object;
47  throwArkTsCompilerError: Object;
48  hashJsonFilePath: string;
49  genAbcScriptPath: string;
50  triggerAsync: Object;
51  triggerEndSignal: Object;
52
53  constructor(rollupObject: Object) {
54    this.projectConfig = Object.assign(rollupObject.share.arkProjectConfig, rollupObject.share.projectConfig);
55    this.arkConfig = initArkConfig(this.projectConfig);
56    this.cmdArgs = this.initCmdEnv();
57    this.logger = rollupObject.share.getLogger(GEN_ABC_PLUGIN_NAME);
58    this.throwArkTsCompilerError = rollupObject.share.throwArkTsCompilerError;
59    this.hashJsonFilePath = this.genHashJsonFilePath();
60    this.genAbcScriptPath = path.resolve(__dirname, GEN_ABC_SCRIPT);
61    // Each time triggerAsync() was called, IDE will wait for asynchronous operation to finish before continue excuting.
62    // The finish signal was passed to IDE by calling triggerEndSignal() in the child process created by triggerAsync()
63    // When multiple workers were invoked by triggerAsync(), IDE will wait until the times of calling
64    // triggerEndSignal() matches the number of workers invoked.
65    // If the child process throws an error by calling throwArkTsCompilerError(), IDE will reset the counting state.
66    this.triggerAsync = rollupObject.async;
67    this.triggerEndSignal = rollupObject.signal;
68  }
69
70  initCmdEnv() {
71    let args: string[] = [];
72
73    if (isTs2Abc(this.projectConfig)) {
74      let ts2abc: string = this.arkConfig.ts2abcPath;
75      validateFilePathLength(ts2abc, this.logger);
76
77      ts2abc = '"' + ts2abc + '"';
78      args = [`${this.arkConfig.nodePath}`, '--expose-gc', ts2abc];
79      if (this.arkConfig.isDebug) {
80        args.push('--debug');
81      }
82      if (isOhModules(this.projectConfig)) {
83        args.push('--oh-modules');
84      }
85    } else if (isEs2Abc(this.projectConfig)) {
86      const es2abc: string = this.arkConfig.es2abcPath;
87      validateFilePathLength(es2abc, this.logger);
88
89      args = ['"' + es2abc + '"'];
90      if (this.arkConfig.isDebug) {
91        args.push('--debug-info');
92      }
93    } else {
94      this.throwArkTsCompilerError('ArkTS:ERROR please set panda mode');
95    }
96
97    return args;
98  }
99
100  private genHashJsonFilePath() {
101    if (this.projectConfig.cachePath) {
102      if (!fs.existsSync(this.projectConfig.cachePath) || !fs.statSync(this.projectConfig.cachePath).isDirectory()) {
103        this.logger.debug(blue, `ArkTS:WARN cache path does bit exist or is not directory`, reset);
104        return '';
105      }
106      const hashJsonPath: string = path.join(genTemporaryModuleCacheDirectoryForBundle(this.projectConfig), HASH_FILE_NAME);
107      validateFilePathLength(hashJsonPath, this.logger);
108      mkdirsSync(path.dirname(hashJsonPath));
109      return hashJsonPath;
110    } else {
111      this.logger.debug(blue, `ArkTS:WARN cache path not specified`, reset);
112      return '';
113    }
114  }
115
116  setupCluster(cluster: Object): void {
117    cluster.removeAllListeners('exit');
118    if (nodeLargeOrEqualTargetVersion(16)) {
119      cluster.setupPrimary({
120        exec: this.genAbcScriptPath,
121        windowsHide: true
122      });
123    } else {
124      cluster.setupMaster({
125        exec: this.genAbcScriptPath,
126        windowsHide: true
127      });
128    }
129  }
130
131  protected needRemoveCacheInfo(rollupObject: Object): boolean {
132    return rollupObject.cache.get(IS_CACHE_INVALID) || rollupObject.cache.get(IS_CACHE_INVALID) === undefined;
133  }
134
135  protected removeCacheInfo(rollupObject: Object): void {
136    if (this.needRemoveCacheInfo(rollupObject)) {
137      this.removeCompilationCache();
138    }
139    rollupObject.cache.set(IS_CACHE_INVALID, false);
140  }
141
142  abstract removeCompilationCache(): void;
143}
144