• 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 path from 'path';
17import ts from 'typescript';
18import fs from 'fs';
19
20import { newSourceMaps as rollupNewSourceMaps } from './fast_build/ark_compiler/transform';
21import {
22  EXTNAME_JS,
23  EXTNAME_TS,
24  EXTNAME_ETS,
25  TS_NOCHECK
26} from './pre_define';
27import {
28  genTemporaryPath,
29  mkdirsSync,
30  toUnixPath,
31} from './utils';
32import {
33  genSourceMapFileName,
34  newSourceMaps as webpackNewSourceMaps,
35  transformModuleSpecifier,
36  getBuildModeInLowerCase
37} from './ark_utils';
38import { processSystemApi } from './validate_ui_syntax';
39import { DEBUG } from './fast_build/ark_compiler/common/ark_define';
40
41export const SRC_MAIN: string = 'src/main';
42
43export function writeFileSyncByNode(node: ts.SourceFile, toTsFile: boolean, projectConfig: any): void {
44  if (toTsFile) {
45    const newStatements: ts.Node[] = [];
46    const tsIgnoreNode: ts.Node = ts.factory.createExpressionStatement(ts.factory.createIdentifier(TS_NOCHECK));
47    newStatements.push(tsIgnoreNode);
48    if (node.statements && node.statements.length) {
49      newStatements.push(...node.statements);
50    }
51
52    node = ts.factory.updateSourceFile(node, newStatements);
53  }
54  const mixedInfo: {content: string, sourceMapJson: any} = genContentAndSourceMapInfo(node, toTsFile, projectConfig);
55  let temporaryFile: string = genTemporaryPath(node.fileName, projectConfig.projectPath, process.env.cachePath,
56    projectConfig);
57  if (temporaryFile.length === 0) {
58    return;
59  }
60  let temporarySourceMapFile: string = '';
61  if (temporaryFile.endsWith(EXTNAME_ETS)) {
62    if (toTsFile) {
63      temporaryFile = temporaryFile.replace(/\.ets$/, EXTNAME_TS);
64    } else {
65      temporaryFile = temporaryFile.replace(/\.ets$/, EXTNAME_JS);
66    }
67    temporarySourceMapFile = genSourceMapFileName(temporaryFile);
68  } else {
69    if (!toTsFile) {
70      temporaryFile = temporaryFile.replace(/\.ts$/, EXTNAME_JS);
71      temporarySourceMapFile = genSourceMapFileName(temporaryFile);
72    }
73  }
74  mkdirsSync(path.dirname(temporaryFile));
75  if (temporarySourceMapFile.length > 0 && getBuildModeInLowerCase(projectConfig) === DEBUG) {
76    let source = toUnixPath(node.fileName).replace(toUnixPath(projectConfig.projectRootPath) + '/', '');
77    process.env.compileTool === 'rollup' ? rollupNewSourceMaps[source] = mixedInfo.sourceMapJson :
78                                           webpackNewSourceMaps[source] = mixedInfo.sourceMapJson;
79  }
80  fs.writeFileSync(temporaryFile, mixedInfo.content);
81}
82
83function genContentAndSourceMapInfo(node: ts.SourceFile, toTsFile: boolean, projectConfig: any): any {
84  const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
85  const options: ts.CompilerOptions = {
86    sourceMap: true
87  };
88  const mapOpions: any = {
89    sourceMap: true,
90    inlineSourceMap: false,
91    inlineSources: false,
92    sourceRoot: '',
93    mapRoot: '',
94    extendedDiagnostics: false
95  };
96  const host: ts.CompilerHost = ts.createCompilerHost(options);
97  const fileName: string = node.fileName;
98  // @ts-ignore
99  const sourceMapGenerator: any = ts.createSourceMapGenerator(
100    host,
101    // @ts-ignore
102    ts.getBaseFileName(fileName),
103    '',
104    '',
105    mapOpions
106  );
107  // @ts-ignore
108  const writer: any = ts.createTextWriter(
109    // @ts-ignore
110    ts.getNewLineCharacter({newLine: ts.NewLineKind.LineFeed, removeComments: false}));
111  printer['writeFile'](node, writer, sourceMapGenerator);
112  const sourceMapJson: any = sourceMapGenerator.toJSON();
113  sourceMapJson['sources'] = [fileName.replace(toUnixPath(projectConfig.projectRootPath) + '/', '')];
114  let content: string = writer.getText();
115  if (toTsFile) {
116    content = content.replace(`${TS_NOCHECK};`, TS_NOCHECK);
117  }
118  if (process.env.compileTool !== 'rollup') {
119    content = transformModuleSpecifier(fileName, processSystemApi(content, true), projectConfig);
120  }
121
122  return {
123    content: content,
124    sourceMapJson: sourceMapJson
125  };
126}
127