merge main.js

Signed-off-by: houhaoyu <houhaoyu@huawei.com>
Change-Id: Id07d606203adc85051ab66ae218280f669f9855a
This commit is contained in:
houhaoyu
2022-06-07 21:51:37 +08:00
33 changed files with 1980 additions and 291 deletions
+1 -1
View File
@@ -19,6 +19,6 @@
"accessibilityImportance", "onAccessibility", "grayscale", "brightness", "contrast",
"saturate", "geometryTransition",
"bindPopup", "colorBlend", "invert", "sepia", "hueRotate", "bindMenu", "bindContextMenu",
"onFocus", "onBlur", "onFocusMove", "focusable", "responseRegion"
"onFocus", "onBlur", "onFocusMove", "focusable", "tabIndex", "responseRegion", "alignRules"
]
}
@@ -0,0 +1,4 @@
{
"name": "RelativeContainer",
"attrs": []
}
+1 -1
View File
@@ -3,6 +3,6 @@
"atomic": true,
"attrs": [
"searchButton", "placeholderColor", "placeholderFont", "textFont", "onSubmit", "onChange",
"onCopy", "OnCut", "OnPaste"
"onCopy", "OnCut", "OnPaste", "copyOption"
]
}
+1 -1
View File
@@ -4,6 +4,6 @@
"attrs": [
"placeholderColor", "placeholderFont", "textAlign", "caretColor", "onChange",
"onCopy", "OnCut", "OnPaste", "fontSize", "fontColor", "fontStyle", "fontWeight", "fontFamily",
"inputFilter"
"inputFilter", "copyOption"
]
}
+2 -1
View File
@@ -4,6 +4,7 @@
"attrs": [
"type", "placeholderColor", "placeholderFont", "enterKeyType", "caretColor", "maxLength",
"onEditChanged", "onSubmit", "onChange", "onCopy", "OnCut", "OnPaste", "fontSize",
"fontColor", "fontStyle", "fontWeight", "fontFamily", "inputFilter", "onEditChange"
"fontColor", "fontStyle", "fontWeight", "fontFamily", "inputFilter", "onEditChange",
"copyOption"
]
}
+21 -6
View File
@@ -158,7 +158,7 @@ function setAbilityPages(projectConfig) {
let abilityPages = [];
if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) {
const moduleJson = JSON.parse(fs.readFileSync(projectConfig.aceModuleJsonPath).toString());
abilityPages = readAbilityEntrance(moduleJson, projectConfig);
abilityPages = readAbilityEntrance(moduleJson);
setAbilityFile(projectConfig, abilityPages);
setBundleModuleInfo(projectConfig, moduleJson);
}
@@ -211,7 +211,7 @@ function setAbilityFile(projectConfig, abilityPages) {
if (path.isAbsolute(abilityPath)) {
abilityPath = '.' + abilityPath.slice(projectConfig.projectPath.length);
}
const entryPageKey = abilityPath.replace(/^\.\/ets\//, './').replace(/\.ts$/, '');
const entryPageKey = abilityPath.replace(/^\.\/ets\//, './').replace(/\.ts$/, '').replace(/\.ets$/, '');
if (fs.existsSync(projectAbilityPath)) {
abilityConfig.projectAbilityPath.push(projectAbilityPath);
projectConfig.entryObj[entryPageKey] = projectAbilityPath + '?entry';
@@ -221,23 +221,23 @@ function setAbilityFile(projectConfig, abilityPages) {
});
}
function readAbilityEntrance(moduleJson, projectConfig) {
function readAbilityEntrance(moduleJson) {
let abilityPages = [];
if (moduleJson.module) {
if (moduleJson.module.srcEntrance) {
abilityPages.push(moduleJson.module.srcEntrance);
}
if (moduleJson.module.abilities && moduleJson.module.abilities.length > 0) {
setEntrance(moduleJson.module.abilities, abilityPages, projectConfig);
setEntrance(moduleJson.module.abilities, abilityPages);
}
if (moduleJson.module.extensionAbilities && moduleJson.module.extensionAbilities.length > 0) {
setEntrance(moduleJson.module.extensionAbilities, abilityPages, projectConfig);
setEntrance(moduleJson.module.extensionAbilities, abilityPages);
}
}
return abilityPages;
}
function setEntrance(abilityConfig, abilityPages, projectConfig) {
function setEntrance(abilityConfig, abilityPages) {
if (abilityConfig && abilityConfig.length > 0) {
abilityConfig.forEach(ability => {
if (ability.srcEntrance) {
@@ -345,6 +345,20 @@ function hashProjectPath(projectPath) {
return process.env.hashProjectPath;
}
function loadModuleInfo(projectConfig, envArgs) {
if (projectConfig.aceBuildJson && fs.existsSync(projectConfig.aceBuildJson)) {
const buildJsonInfo = JSON.parse(fs.readFileSync(projectConfig.aceBuildJson).toString());
projectConfig.compileMode = buildJsonInfo.compileMode;
projectConfig.projectRootPath = buildJsonInfo.projectRootPath;
projectConfig.modulePathMap = buildJsonInfo.modulePathMap;
projectConfig.processTs = false;
projectConfig.buildArkMode = envArgs.buildMode;
if (buildJsonInfo.compileMode === 'esmodule') {
projectConfig.nodeModulesPath = buildJsonInfo.nodeModulesPath;
}
}
}
const globalProgram = {
program: null,
watchProgram: null
@@ -359,3 +373,4 @@ exports.loadWorker = loadWorker;
exports.abilityConfig = abilityConfig;
exports.readWorkerFile = readWorkerFile;
exports.abilityPagesFullPath = abilityPagesFullPath;
exports.loadModuleInfo = loadModuleInfo;
+1 -1
View File
@@ -220,7 +220,7 @@ export class ResultStates {
if (lastModuleCollection && lastModuleCollection !== 'NULL') {
lastModuleCollection.split(',').forEach(item => {
moduleCollection.add(item);
})
});
}
}
const moduleContent: string =
+22 -4
View File
@@ -36,6 +36,7 @@ import { JS_BIND_COMPONENTS } from './component_map';
import { getName } from './process_component_build';
import { INNER_COMPONENT_NAMES } from './component_map';
import { props } from './compile_info';
import { resolveSourceFile } from './resolve_ohm_url';
function readDeaclareFiles(): string[] {
const declarationsFileNames: string[] = [];
@@ -90,7 +91,7 @@ export function createLanguageService(rootFileNames: string[]): ts.LanguageServi
return undefined;
}
if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
const content: string = processContent(fs.readFileSync(fileName).toString());
const content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
checkUISyntax(content, fileName);
return ts.ScriptSnapshot.fromString(content);
}
@@ -109,6 +110,16 @@ export function createLanguageService(rootFileNames: string[]): ts.LanguageServi
return ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
}
function getOhmUrlFile(moduleName: string): {modulePath: string, suffix: string} {
const modulePath: string = resolveSourceFile(moduleName);
let suffix: string = path.extname(modulePath);
if (suffix === 'ts' && modulePath.endsWith('.d.ts')) {
suffix = '.d.ts';
}
return {modulePath, suffix};
}
function resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] {
const resolvedModules: ts.ResolvedModuleFull[] = [];
for (const moduleName of moduleNames) {
@@ -122,6 +133,13 @@ function resolveModuleNames(moduleNames: string[], containingFile: string): ts.R
});
if (result.resolvedModule) {
resolvedModules.push(result.resolvedModule);
} else if (/^@bundle:/.test(moduleName.trim())) {
const module: {modulePath: string, suffix: string} = getOhmUrlFile(moduleName.trim());
if (ts.sys.fileExists(module.modulePath)) {
resolvedModules.push(getResolveModule(module.modulePath, module.suffix));
} else {
resolvedModules.push(null);
}
} else if (/^@(system|ohos)/.test(moduleName.trim())) {
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
if (ts.sys.fileExists(modulePath)) {
@@ -175,7 +193,7 @@ export function createWatchCompilerHost(rootFileNames: string[],
return undefined;
}
if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
const content: string = processContent(fs.readFileSync(fileName).toString());
const content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
checkUISyntax(content, fileName);
return content;
}
@@ -352,8 +370,8 @@ function processDraw(source: string): string {
});
}
function processContent(source: string): string {
source = processSystemApi(source);
function processContent(source: string, sourcePath: string): string {
source = processSystemApi(source, false, sourcePath);
source = preprocessExtend(source, extendCollection);
source = preprocessNewExtend(source, extendCollection);
source = processDraw(source);
+3 -3
View File
@@ -23,10 +23,10 @@ const red: string = '\u001b[31m';
const reset: string = '\u001b[39m';
function js2abcByWorkers(jsonInput: string, cmd: string): Promise<void> {
const inputPaths = JSON.parse(jsonInput);
const inputPaths: any = JSON.parse(jsonInput);
for (let i = 0; i < inputPaths.length; ++i) {
const input = inputPaths[i].path;
const singleCmd = `${cmd} "${input}"`;
const input: string = inputPaths[i].path;
const singleCmd: any = `${cmd} "${input}"`;
logger.debug('gen abc cmd is: ', singleCmd, ' ,file size is:', inputPaths[i].size, ' byte');
try {
childProcess.execSync(singleCmd);
+457 -44
View File
@@ -19,10 +19,34 @@ import cluster from 'cluster';
import process from 'process';
import Compiler from 'webpack/lib/Compiler';
import { logger } from './compile_info';
import { toUnixPath, toHashData } from './utils';
import {
toUnixPath,
toHashData,
genTemporaryPath,
genBuildPath,
genAbcFileName,
mkdirsSync,
genSourceMapFileName,
checkNodeModulesFile
} from './utils';
import { projectConfig } from '../main';
import {
ESMODULE,
JSBUNDLE,
NODE_MODULES,
ENTRY_TXT,
EXTNAME_ETS,
EXTNAME_JS,
EXTNAME_TS,
EXTNAME_MJS,
EXTNAME_CJS,
EXTNAME_D_TS,
EXTNAME_ABC
} from './pre_define';
const firstFileEXT: string = '_.js';
const genAbcScript = 'gen_abc.js';
const genAbcScript: string = 'gen_abc.js';
const genModuleAbcScript: string = 'gen_module_abc.js';
let output: string;
let isWin: boolean = false;
let isMac: boolean = false;
@@ -36,13 +60,49 @@ interface File {
}
const intermediateJsBundle: Array<File> = [];
let fileterIntermediateJsBundle: Array<File> = [];
const moduleInfos: Array<ModuleInfo> = [];
let filterModuleInfos: Array<ModuleInfo> = [];
const commonJsModuleInfos: Array<ModuleInfo> = [];
const ESMModuleInfos: Array<ModuleInfo> = [];
const entryInfos: Map<string, EntryInfo> = new Map<string, EntryInfo>();
let hashJsonObject = {};
let buildPathInfo = '';
let moduleHashJsonObject = {};
let buildPathInfo: string = '';
const red: string = '\u001b[31m';
const reset: string = '\u001b[39m';
const hashFile = 'gen_hash.json';
const ARK = '/ark/';
const hashFile: string = 'gen_hash.json';
const ARK: string = '/ark/';
class ModuleInfo {
filePath: string;
tempFilePath: string;
buildFilePath: string;
abcFilePath: string;
isCommonJs: boolean;
constructor(filePath: string, tempFilePath: string, buildFilePath: string, abcFilePath: string, isCommonJs: boolean) {
this.filePath = filePath;
this.tempFilePath = tempFilePath;
this.buildFilePath = buildFilePath;
this.abcFilePath = abcFilePath;
this.isCommonJs = isCommonJs;
}
}
class EntryInfo {
npmInfo: string;
abcFileName: string;
buildPath: string;
entry: string;
constructor(npmInfo: string, abcFileName: string, buildPath: string, entry: string) {
this.npmInfo = npmInfo;
this.abcFileName = abcFileName;
this.buildPath = buildPath;
this.entry = entry;
}
}
export class GenAbcPlugin {
constructor(output_, arkDir_, nodeJs_, isDebug_) {
@@ -65,10 +125,34 @@ export class GenAbcPlugin {
}
}
compiler.hooks.compilation.tap('GenAbcPlugin', (compilation) => {
if (projectConfig.compileMode === JSBUNDLE || projectConfig.compileMode === undefined) {
return;
}
buildPathInfo = output;
compilation.hooks.finishModules.tap('finishModules', handleFinishModules.bind(this));
});
compiler.hooks.compilation.tap('GenAbcPlugin', (compilation) => {
compilation.hooks.processAssets.tap('processAssets', (assets) => {
if (projectConfig.compileMode === JSBUNDLE || projectConfig.compileMode === undefined) {
return;
}
Object.keys(compilation.assets).forEach(key => {
if (path.extname(key) === EXTNAME_JS) {
delete assets[key];
}
});
});
});
compiler.hooks.emit.tap('GenAbcPlugin', (compilation) => {
if (projectConfig.compileMode === ESMODULE) {
return;
}
Object.keys(compilation.assets).forEach(key => {
// choose *.js
if (output && path.extname(key) === '.js') {
if (output && path.extname(key) === EXTNAME_JS) {
const newContent: string = compilation.assets[key].source();
const keyPath: string = key.replace(/\.js$/, firstFileEXT);
writeFileSync(newContent, path.resolve(output, keyPath), key);
@@ -77,12 +161,163 @@ export class GenAbcPlugin {
});
compiler.hooks.afterEmit.tap('GenAbcPluginMultiThread', () => {
if (projectConfig.compileMode === ESMODULE) {
return;
}
buildPathInfo = output;
invokeWorkersToGenAbc();
});
}
}
function getEntryInfo(tempFilePath: string, resourceResolveData: any): void {
if (!resourceResolveData.descriptionFilePath) {
return;
}
const packageName: string = resourceResolveData.descriptionFileData['name'];
const packageJsonPath: string = resourceResolveData.descriptionFilePath;
let npmInfoPath: string = path.resolve(packageJsonPath, '..');
const fakeEntryPath: string = path.resolve(npmInfoPath, 'fake.js');
const tempFakeEntryPath: string = genTemporaryPath(fakeEntryPath, projectConfig.projectPath, process.env.cachePath);
const buildFakeEntryPath: string = genBuildPath(fakeEntryPath, projectConfig.projectPath, projectConfig.buildPath);
npmInfoPath = toUnixPath(path.resolve(tempFakeEntryPath, '..'));
const buildNpmInfoPath: string = toUnixPath(path.resolve(buildFakeEntryPath, '..'));
if (entryInfos.has(npmInfoPath)) {
return;
}
let abcFileName: string = genAbcFileName(tempFilePath);
const abcFilePaths: string[] = abcFileName.split(NODE_MODULES);
abcFileName = [NODE_MODULES, abcFilePaths[abcFilePaths.length - 1]].join(path.sep);
abcFileName = toUnixPath(abcFileName);
const packagePaths: string[] = tempFilePath.split(NODE_MODULES);
const entryPaths: string[] = packagePaths[packagePaths.length - 1].split(packageName);
let entry: string = toUnixPath(entryPaths[entryPaths.length - 1]);
if (entry.startsWith('/')) {
entry = entry.slice(1, entry.length);
}
const entryInfo: EntryInfo = new EntryInfo(npmInfoPath, abcFileName, buildNpmInfoPath, entry);
entryInfos.set(npmInfoPath, entryInfo);
}
function processNodeModulesFile(filePath: string, tempFilePath: string, buildFilePath: string, abcFilePath: string, nodeModulesFile: Array<string>, module: any): void {
getEntryInfo(tempFilePath, module.resourceResolveData);
const descriptionFileData: any = module.resourceResolveData.descriptionFileData;
if (descriptionFileData && descriptionFileData['type'] && descriptionFileData['type'] === 'module') {
const tempModuleInfo: ModuleInfo = new ModuleInfo(filePath, tempFilePath, buildFilePath, abcFilePath, false);
moduleInfos.push(tempModuleInfo);
nodeModulesFile.push(tempFilePath);
} else if (filePath.endsWith(EXTNAME_MJS)) {
const tempModuleInfo: ModuleInfo = new ModuleInfo(filePath, tempFilePath, buildFilePath, abcFilePath, false);
moduleInfos.push(tempModuleInfo);
nodeModulesFile.push(tempFilePath);
} else {
const tempModuleInfo: ModuleInfo = new ModuleInfo(filePath, tempFilePath, buildFilePath, abcFilePath, true);
moduleInfos.push(tempModuleInfo);
nodeModulesFile.push(tempFilePath);
}
return;
}
function processEtsModule(filePath: string, tempFilePath: string, buildFilePath: string, nodeModulesFile: Array<string>, module: any): void {
if (projectConfig.processTs === true) {
tempFilePath = tempFilePath.replace(/\.ets$/, EXTNAME_TS);
buildFilePath = buildFilePath.replace(/\.ets$/, EXTNAME_TS);
} else {
tempFilePath = tempFilePath.replace(/\.ets$/, EXTNAME_JS);
buildFilePath = buildFilePath.replace(/\.ets$/, EXTNAME_JS);
}
const abcFilePath: string = genAbcFileName(tempFilePath);
if (checkNodeModulesFile(filePath, projectConfig.projectPath)) {
processNodeModulesFile(filePath, tempFilePath, buildFilePath, abcFilePath, nodeModulesFile, module);
} else {
const tempModuleInfo: ModuleInfo = new ModuleInfo(filePath, tempFilePath, buildFilePath, abcFilePath, false);
moduleInfos.push(tempModuleInfo);
}
}
function processDtsModule(filePath: string, tempFilePath: string, buildFilePath: string, nodeModulesFile: Array<string>, module: any): void {
return;
}
function processTsModule(filePath: string, tempFilePath: string, buildFilePath: string, nodeModulesFile: Array<string>, module: any): void {
if (projectConfig.processTs === false) {
tempFilePath = tempFilePath.replace(/\.ts$/, EXTNAME_JS);
buildFilePath = buildFilePath.replace(/\.ts$/, EXTNAME_JS);
}
const abcFilePath: string = genAbcFileName(tempFilePath);
if (checkNodeModulesFile(filePath, projectConfig.projectPath)) {
processNodeModulesFile(filePath, tempFilePath, buildFilePath, abcFilePath, nodeModulesFile, module);
} else {
const tempModuleInfo: ModuleInfo = new ModuleInfo(filePath, tempFilePath, buildFilePath, abcFilePath, false);
moduleInfos.push(tempModuleInfo);
}
}
function processJsModule(filePath: string, tempFilePath: string, buildFilePath: string, nodeModulesFile: Array<string>, module: any): void {
const parent: string = path.join(tempFilePath, '..');
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
mkDir(parent);
}
if (filePath.endsWith(EXTNAME_MJS) || filePath.endsWith(EXTNAME_CJS)) {
fs.copyFileSync(filePath, tempFilePath);
}
const abcFilePath: string = genAbcFileName(tempFilePath);
if (checkNodeModulesFile(filePath, projectConfig.projectPath)) {
processNodeModulesFile(filePath, tempFilePath, buildFilePath, abcFilePath, nodeModulesFile, module);
} else {
const tempModuleInfo: ModuleInfo = new ModuleInfo(filePath, tempFilePath, buildFilePath, abcFilePath, false);
moduleInfos.push(tempModuleInfo);
}
}
function handleFinishModules(modules, callback): any {
const nodeModulesFile: Array<string> = [];
modules.forEach(module => {
if (module !== undefined && module.resourceResolveData !== undefined) {
const filePath: string = module.resourceResolveData.path;
let tempFilePath = genTemporaryPath(filePath, projectConfig.projectPath, process.env.cachePath);
if (tempFilePath.length === 0) {
return;
}
let buildFilePath: string = genBuildPath(filePath, projectConfig.projectPath, projectConfig.buildPath);
tempFilePath = toUnixPath(tempFilePath);
buildFilePath = toUnixPath(buildFilePath);
if (filePath.endsWith(EXTNAME_ETS)) {
processEtsModule(filePath, tempFilePath, buildFilePath, nodeModulesFile, module);
} else if (filePath.endsWith(EXTNAME_D_TS)) {
processDtsModule(filePath, tempFilePath, buildFilePath, nodeModulesFile, module);
} else if (filePath.endsWith(EXTNAME_TS)) {
processTsModule(filePath, tempFilePath, buildFilePath, nodeModulesFile, module);
} else if (filePath.endsWith(EXTNAME_JS) || filePath.endsWith(EXTNAME_MJS) || filePath.endsWith(EXTNAME_CJS)) {
processJsModule(filePath, tempFilePath, buildFilePath, nodeModulesFile, module);
} else {
logger.error(red, `ETS:ERROR Cannot find resolve this file path: ${filePath}`, reset);
}
}
});
invokeWorkersModuleToGenAbc(moduleInfos);
processEntryToGenAbc(entryInfos);
}
function processEntryToGenAbc(entryInfos: Map<string, EntryInfo>): void {
for (const value of entryInfos.values()) {
const tempAbcFilePath: string = toUnixPath(path.resolve(value.npmInfo, ENTRY_TXT));
const buildAbcFilePath: string = toUnixPath(path.resolve(value.buildPath, ENTRY_TXT));
fs.writeFileSync(tempAbcFilePath, value.entry, 'utf-8');
if (!fs.existsSync(buildAbcFilePath)) {
const parent: string = path.join(buildAbcFilePath, '..');
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
mkDir(parent);
}
}
fs.copyFileSync(tempAbcFilePath, buildAbcFilePath);
}
}
function writeFileSync(inputString: string, output: string, jsBundleFile: string): void {
const parent: string = path.join(output, '..');
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
@@ -90,7 +325,7 @@ function writeFileSync(inputString: string, output: string, jsBundleFile: string
}
fs.writeFileSync(output, inputString);
if (fs.existsSync(output)) {
const fileSize = fs.statSync(output).size;
const fileSize: any = fs.statSync(output).size;
intermediateJsBundle.push({path: output, size: fileSize});
} else {
logger.error(red, `ETS:ERROR Failed to convert file ${jsBundleFile} to bin. ${output} is lost`, reset);
@@ -105,16 +340,16 @@ function mkDir(path_: string): void {
fs.mkdirSync(path_);
}
function getSmallestSizeGroup(groupSize: Map<number, number>) {
const groupSizeArray = Array.from(groupSize);
function getSmallestSizeGroup(groupSize: Map<number, number>): any {
const groupSizeArray: any = Array.from(groupSize);
groupSizeArray.sort(function(g1, g2) {
return g1[1] - g2[1]; // sort by size
});
return groupSizeArray[0][0];
}
function splitJsBundlesBySize(bundleArray: Array<File>, groupNumber: number) {
const result = [];
function splitJsBundlesBySize(bundleArray: Array<File>, groupNumber: number): any {
const result: any = [];
if (bundleArray.length < groupNumber) {
result.push(bundleArray);
return result;
@@ -123,7 +358,7 @@ function splitJsBundlesBySize(bundleArray: Array<File>, groupNumber: number) {
bundleArray.sort(function(f1: File, f2: File) {
return f2.size - f1.size;
});
const groupFileSize = new Map();
const groupFileSize: any = new Map();
for (let i = 0; i < groupNumber; ++i) {
result.push([]);
groupFileSize.set(i, 0);
@@ -131,16 +366,122 @@ function splitJsBundlesBySize(bundleArray: Array<File>, groupNumber: number) {
let index = 0;
while (index < bundleArray.length) {
const smallestGroup = getSmallestSizeGroup(groupFileSize);
const smallestGroup: any = getSmallestSizeGroup(groupFileSize);
result[smallestGroup].push(bundleArray[index]);
const sizeUpdate = groupFileSize.get(smallestGroup) + bundleArray[index].size;
const sizeUpdate: any = groupFileSize.get(smallestGroup) + bundleArray[index].size;
groupFileSize.set(smallestGroup, sizeUpdate);
index++;
}
return result;
}
function invokeWorkersToGenAbc() {
function invokeWorkersModuleToGenAbc(moduleInfos: Array<ModuleInfo>): void {
if (fs.existsSync(buildPathInfo)) {
fs.rmdirSync(buildPathInfo, { recursive: true});
}
if (fs.existsSync(projectConfig.nodeModulesPath)) {
fs.rmdirSync(projectConfig.nodeModulesPath, { recursive: true});
}
filterIntermediateModuleByHashJson(buildPathInfo, moduleInfos);
filterModuleInfos.forEach(moduleInfo => {
if (moduleInfo.isCommonJs) {
commonJsModuleInfos.push(moduleInfo);
} else {
ESMModuleInfos.push(moduleInfo);
}
});
invokeCluterModuleToAbc();
}
function initAbcEnv() : string[] {
let js2abc: string = path.join(arkDir, 'build', 'src', 'index.js');
if (isWin) {
js2abc = path.join(arkDir, 'build-win', 'src', 'index.js');
} else if (isMac) {
js2abc = path.join(arkDir, 'build-mac', 'src', 'index.js');
}
const args: string[] = [
'--expose-gc',
js2abc
];
if (isDebug) {
args.push('--debug');
}
return args;
}
function invokeCluterModuleToAbc(): void {
const abcArgs: string[] = initAbcEnv();
const clusterNewApiVersion: number = 16;
const currentNodeVersion: number = parseInt(process.version.split('.')[0]);
const useNewApi: boolean = currentNodeVersion >= clusterNewApiVersion;
if (useNewApi && cluster.isPrimary || !useNewApi && cluster.isMaster) {
if (useNewApi) {
cluster.setupPrimary({
exec: path.resolve(__dirname, genModuleAbcScript)
});
} else {
cluster.setupMaster({
exec: path.resolve(__dirname, genModuleAbcScript)
});
}
if (commonJsModuleInfos.length > 0) {
const tempAbcArgs: string[] = abcArgs.slice(0);
tempAbcArgs.push('-c');
const commonJsCmdPrefix: any = `${nodeJs} ${tempAbcArgs.join(' ')}`;
const chunkSize: number = 50;
const splitedModules: any[] = splitModulesByNumber(commonJsModuleInfos, chunkSize);
const workerNumber: number = splitedModules.length;
for (let i = 0; i < workerNumber; i++) {
const workerData: any = {
'inputs': JSON.stringify(splitedModules[i]),
'cmd': commonJsCmdPrefix
};
cluster.fork(workerData);
}
}
if (ESMModuleInfos.length > 0) {
const tempAbcArgs: string[] = abcArgs.slice(0);
tempAbcArgs.push('-m');
const ESMCmdPrefix: any = `${nodeJs} ${tempAbcArgs.join(' ')}`;
const chunkSize: number = 50;
const splitedModules: any[] = splitModulesByNumber(ESMModuleInfos, chunkSize);
const workerNumber: number = splitedModules.length;
for (let i = 0; i < workerNumber; i++) {
const workerData: any = {
'inputs': JSON.stringify(splitedModules[i]),
'cmd': ESMCmdPrefix
};
cluster.fork(workerData);
}
}
cluster.on('exit', (worker, code, signal) => {
logger.debug(`worker ${worker.process.pid} finished`);
});
process.on('exit', (code) => {
writeModuleHashJson();
});
}
}
function splitModulesByNumber(moduleInfos: Array<ModuleInfo>, chunkSize: number): any[] {
const result: any[] = [];
for (let i = 0; i < moduleInfos.length; i += chunkSize) {
result.push(moduleInfos.slice(i, i + chunkSize));
}
return result;
}
function invokeWorkersToGenAbc(): void {
let param: string = '';
if (isDebug) {
param += ' --debug';
@@ -154,14 +495,14 @@ function invokeWorkersToGenAbc() {
}
filterIntermediateJsBundleByHashJson(buildPathInfo, intermediateJsBundle);
const maxWorkerNumber = 3;
const splitedBundles = splitJsBundlesBySize(fileterIntermediateJsBundle, maxWorkerNumber);
const workerNumber = maxWorkerNumber < splitedBundles.length ? maxWorkerNumber : splitedBundles.length;
const maxWorkerNumber: number = 3;
const splitedBundles: any[] = splitJsBundlesBySize(fileterIntermediateJsBundle, maxWorkerNumber);
const workerNumber: number = maxWorkerNumber < splitedBundles.length ? maxWorkerNumber : splitedBundles.length;
const cmdPrefix: string = `${nodeJs} --expose-gc "${js2abc}" ${param} `;
const clusterNewApiVersion = 16;
const currentNodeVersion = parseInt(process.version.split('.')[0]);
const useNewApi = currentNodeVersion >= clusterNewApiVersion;
const clusterNewApiVersion: number = 16;
const currentNodeVersion: number = parseInt(process.version.split('.')[0]);
const useNewApi: boolean = currentNodeVersion >= clusterNewApiVersion;
if (useNewApi && cluster.isPrimary || !useNewApi && cluster.isMaster) {
if (useNewApi) {
@@ -175,7 +516,7 @@ function invokeWorkersToGenAbc() {
}
for (let i = 0; i < workerNumber; ++i) {
const workerData = {
const workerData: any = {
'inputs': JSON.stringify(splitedBundles[i]),
'cmd': cmdPrefix
};
@@ -192,31 +533,103 @@ function invokeWorkersToGenAbc() {
}
}
function filterIntermediateJsBundleByHashJson(buildPath: string, inputPaths: File[]) {
for (let i = 0; i < inputPaths.length; ++i) {
fileterIntermediateJsBundle.push(inputPaths[i]);
function filterIntermediateModuleByHashJson(buildPath: string, moduleInfos: Array<ModuleInfo>): void {
for (let i = 0; i < moduleInfos.length; ++i) {
filterModuleInfos.push(moduleInfos[i]);
}
const hashFilePath = genHashJsonPath(buildPath);
const hashFilePath: string = genHashJsonPath(buildPath);
if (hashFilePath.length === 0) {
return;
}
const updateJsonObject = {};
let jsonObject = {};
let jsonFile = '';
const updateJsonObject: any = {};
let jsonObject: any = {};
let jsonFile: string = '';
if (fs.existsSync(hashFilePath)) {
jsonFile = fs.readFileSync(hashFilePath).toString();
jsonObject = JSON.parse(jsonFile);
fileterIntermediateJsBundle = [];
for (let i = 0; i < inputPaths.length; ++i) {
const input = inputPaths[i].path;
const abcPath = input.replace(/_.js$/, '.abc');
filterModuleInfos = [];
for (let i = 0; i < moduleInfos.length; ++i) {
const input: string = moduleInfos[i].tempFilePath;
const abcPath: string = moduleInfos[i].abcFilePath;
if (!fs.existsSync(input)) {
logger.error(red, `ETS:ERROR ${input} is lost`, reset);
continue;
}
if (fs.existsSync(abcPath)) {
const hashInputContentData = toHashData(input);
const hashAbcContentData = toHashData(abcPath);
const hashInputContentData: any = toHashData(input);
const hashAbcContentData: any = toHashData(abcPath);
if (jsonObject[input] === hashInputContentData && jsonObject[abcPath] === hashAbcContentData) {
updateJsonObject[input] = hashInputContentData;
updateJsonObject[abcPath] = hashAbcContentData;
mkdirsSync(path.dirname(moduleInfos[i].buildFilePath));
fs.copyFileSync(moduleInfos[i].tempFilePath, moduleInfos[i].buildFilePath);
fs.copyFileSync(genAbcFileName(moduleInfos[i].tempFilePath), genAbcFileName(moduleInfos[i].buildFilePath));
if (projectConfig.buildArkMode === 'debug' && fs.existsSync(genSourceMapFileName(moduleInfos[i].tempFilePath))) {
fs.copyFileSync(genSourceMapFileName(moduleInfos[i].tempFilePath), genSourceMapFileName(moduleInfos[i].buildFilePath));
}
} else {
filterModuleInfos.push(moduleInfos[i]);
}
} else {
filterModuleInfos.push(moduleInfos[i]);
}
}
}
moduleHashJsonObject = updateJsonObject;
}
function writeModuleHashJson(): void {
for (let i = 0; i < filterModuleInfos.length; ++i) {
const input: string = filterModuleInfos[i].tempFilePath;
const abcPath: string = filterModuleInfos[i].abcFilePath;
if (!fs.existsSync(input) || !fs.existsSync(abcPath)) {
logger.error(red, `ETS:ERROR ${input} is lost`, reset);
continue;
}
const hashInputContentData: any = toHashData(input);
const hashAbcContentData: any = toHashData(abcPath);
moduleHashJsonObject[input] = hashInputContentData;
moduleHashJsonObject[abcPath] = hashAbcContentData;
mkdirsSync(path.dirname(filterModuleInfos[i].buildFilePath));
fs.copyFileSync(filterModuleInfos[i].tempFilePath, filterModuleInfos[i].buildFilePath);
fs.copyFileSync(genAbcFileName(filterModuleInfos[i].tempFilePath), genAbcFileName(filterModuleInfos[i].buildFilePath));
if (projectConfig.buildArkMode === 'debug' && fs.existsSync(genSourceMapFileName(moduleInfos[i].tempFilePath))) {
fs.copyFileSync(genSourceMapFileName(moduleInfos[i].tempFilePath), genSourceMapFileName(moduleInfos[i].buildFilePath));
}
}
const hashFilePath: string = genHashJsonPath(buildPathInfo);
if (hashFilePath.length === 0) {
return;
}
fs.writeFileSync(hashFilePath, JSON.stringify(moduleHashJsonObject));
}
function filterIntermediateJsBundleByHashJson(buildPath: string, inputPaths: File[]): void {
for (let i = 0; i < inputPaths.length; ++i) {
fileterIntermediateJsBundle.push(inputPaths[i]);
}
const hashFilePath: string = genHashJsonPath(buildPath);
if (hashFilePath.length === 0) {
return;
}
const updateJsonObject: any = {};
let jsonObject: any = {};
let jsonFile: string = '';
if (fs.existsSync(hashFilePath)) {
jsonFile = fs.readFileSync(hashFilePath).toString();
jsonObject = JSON.parse(jsonFile);
fileterIntermediateJsBundle = [];
for (let i = 0; i < inputPaths.length; ++i) {
const input: string = inputPaths[i].path;
const abcPath: string = input.replace(/_.js$/, EXTNAME_ABC);
if (!fs.existsSync(input)) {
logger.error(red, `ETS:ERROR ${input} is lost`, reset);
continue;
}
if (fs.existsSync(abcPath)) {
const hashInputContentData: any = toHashData(input);
const hashAbcContentData: any = toHashData(abcPath);
if (jsonObject[input] === hashInputContentData && jsonObject[abcPath] === hashAbcContentData) {
updateJsonObject[input] = hashInputContentData;
updateJsonObject[abcPath] = hashAbcContentData;
@@ -233,28 +646,28 @@ function filterIntermediateJsBundleByHashJson(buildPath: string, inputPaths: Fil
hashJsonObject = updateJsonObject;
}
function writeHashJson() {
function writeHashJson(): void {
for (let i = 0; i < fileterIntermediateJsBundle.length; ++i) {
const input = fileterIntermediateJsBundle[i].path;
const abcPath = input.replace(/_.js$/, '.abc');
const input:string = fileterIntermediateJsBundle[i].path;
const abcPath: string = input.replace(/_.js$/, EXTNAME_ABC);
if (!fs.existsSync(input) || !fs.existsSync(abcPath)) {
logger.error(red, `ETS:ERROR ${input} is lost`, reset);
continue;
}
const hashInputContentData = toHashData(input);
const hashAbcContentData = toHashData(abcPath);
const hashInputContentData: any = toHashData(input);
const hashAbcContentData: any = toHashData(abcPath);
hashJsonObject[input] = hashInputContentData;
hashJsonObject[abcPath] = hashAbcContentData;
fs.unlinkSync(input);
}
const hashFilePath = genHashJsonPath(buildPathInfo);
const hashFilePath: string = genHashJsonPath(buildPathInfo);
if (hashFilePath.length === 0) {
return;
}
fs.writeFileSync(hashFilePath, JSON.stringify(hashJsonObject));
}
function genHashJsonPath(buildPath: string) {
function genHashJsonPath(buildPath: string): string {
buildPath = toUnixPath(buildPath);
if (process.env.cachePath) {
if (!fs.existsSync(process.env.cachePath) || !fs.statSync(process.env.cachePath).isDirectory()) {
@@ -263,8 +676,8 @@ function genHashJsonPath(buildPath: string) {
}
return path.join(process.env.cachePath, hashFile);
} else if (buildPath.indexOf(ARK) >= 0) {
const dataTmps = buildPath.split(ARK);
const hashPath = path.join(dataTmps[0], ARK);
const dataTmps: string[] = buildPath.split(ARK);
const hashPath: string = path.join(dataTmps[0], ARK);
if (!fs.existsSync(hashPath) || !fs.statSync(hashPath).isDirectory()) {
logger.error(red, `ETS:ERROR hash path does not exist`, reset);
return '';
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as childProcess from 'child_process';
import * as process from 'process';
import cluster from 'cluster';
import { logger } from './compile_info';
const red: string = '\u001b[31m';
const reset: string = '\u001b[39m';
function js2abcByWorkers(jsonInput: string, cmd: string): Promise<void> {
const inputPaths: any = JSON.parse(jsonInput);
const inputs: string[] = [];
for (let i = 0; i < inputPaths.length; ++i) {
const input: string = inputPaths[i].tempFilePath;
inputs.push('"' + input + '"');
}
const inputsStr: string = inputs.join(' ');
const singleCmd: any = `${cmd} ${inputsStr}`;
logger.debug('gen abc cmd is: ', singleCmd);
try {
childProcess.execSync(singleCmd);
} catch (e) {
logger.error(red, `ETS:ERROR Failed to convert file ${inputsStr} to abc `, reset);
return;
}
return;
}
logger.debug('worker data is: ', JSON.stringify(process.env));
logger.debug('gen_abc isWorker is: ', cluster.isWorker);
if (cluster.isWorker && process.env['inputs'] !== undefined && process.env['cmd'] !== undefined) {
logger.debug('==>worker #', cluster.worker.id, 'started!');
js2abcByWorkers(process.env['inputs'], process.env['cmd']);
process.exit();
}
+17
View File
@@ -235,3 +235,20 @@ export const COMPONENT_TOGGLE: string = 'Toggle';
export const TTOGGLE_CHECKBOX: string = 'Checkbox';
export const TOGGLE_SWITCH: string = 'Switch';
export const ESMODULE: string = 'esmodule';
export const JSBUNDLE: string = 'jsbundle';
export const ENTRY_TXT: string = 'entry.txt';
export const ARK: string = 'ark';
export const TEMPRARY: string = 'temprary';
export const MAIN: string = 'main';
export const AUXILIARY: string = 'auxiliary';
export const ZERO: string = '0';
export const ONE: string = '1';
export const EXTNAME_JS: string = '.js';
export const EXTNAME_TS: string = '.ts';
export const EXTNAME_JS_MAP: string = '.js.map';
export const EXTNAME_TS_MAP: string = '.ts.map';
export const EXTNAME_MJS: string = '.mjs';
export const EXTNAME_CJS: string = '.cjs';
export const EXTNAME_D_TS: string = '.d.ts';
export const EXTNAME_ABC: string = '.abc';
+4 -2
View File
@@ -76,7 +76,10 @@ import {
COMMON_ATTRS,
CUSTOM_BUILDER_PROPERTIES
} from './component_map';
import { componentCollection } from './validate_ui_syntax';
import {
componentCollection,
builderParamObjectCollection
} from './validate_ui_syntax';
import { processCustomComponent } from './process_custom_component';
import {
LogType,
@@ -84,7 +87,6 @@ import {
componentInfo,
createFunction
} from './utils';
import { builderParamObjectCollection } from './process_component_member';
import { projectConfig } from '../main';
import { transformLog, contextGlobal } from './process_ui_syntax';
import { props } from './compile_info';
+2 -14
View File
@@ -115,8 +115,6 @@ export const decoratorParamSet: Set<string> = new Set();
export const stateObjectCollection: Set<string> = new Set();
export const builderParamObjectCollection: Map<string, Set<string>> = new Map();
export class UpdateResult {
private itemUpdate: boolean = false;
private ctorUpdate: boolean = false;
@@ -420,21 +418,12 @@ function createUpdateParams(name: ts.Identifier, decorator: string): ts.Statemen
updateParamsNode = createUpdateParamsWithIf(name);
break;
case COMPONENT_PROP_DECORATOR:
case COMPONENT_BUILDERPARAM_DECORATOR:
updateParamsNode = createUpdateParamsWithoutIf(name);
break;
case COMPONENT_OBJECT_LINK_DECORATOR:
updateParamsNode = createUpdateParamsWithSet(name);
break;
case COMPONENT_BUILDERPARAM_DECORATOR:
if (decorator === COMPONENT_BUILDERPARAM_DECORATOR) {
if (!builderParamObjectCollection.get(componentCollection.currentClassName)) {
builderParamObjectCollection.set(componentCollection.currentClassName, new Set([]));
}
builderParamObjectCollection.get(componentCollection.currentClassName)
.add(name.escapedText.toString());
}
updateParamsNode = createUpdateParamsWithoutIf(name);
break;
}
return updateParamsNode;
}
@@ -512,14 +501,13 @@ function updateSynchedPropertyOneWay(nameIdentifier: ts.Identifier, type: ts.Typ
function updateStoragePropAndLinkProperty(node: ts.PropertyDeclaration, name: ts.Identifier,
setFuncName: string, log: LogInfo[]): ts.ExpressionStatement {
if (isSingleKey(node)) {
const key: string = getDecoratorKey(node);
return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(
createPropertyAccessExpressionWithThis(`__${name.getText()}`),
ts.factory.createToken(ts.SyntaxKind.EqualsToken), ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(APP_STORAGE),
ts.factory.createIdentifier(APP_STORAGE_GET_OR_SET)), undefined, []),
ts.factory.createIdentifier(setFuncName)), undefined, [ts.factory.createStringLiteral(key),
ts.factory.createIdentifier(setFuncName)), undefined, [node.decorators[0].expression.arguments[0],
node.initializer, ts.factory.createThis()])));
} else {
validateAppStorageDecoractorsNonSingleKey(node, log);
+2 -2
View File
@@ -43,7 +43,8 @@ import {
provideCollection,
consumeCollection,
objectLinkCollection,
isStaticViewCollection
isStaticViewCollection,
builderParamObjectCollection
} from './validate_ui_syntax';
import {
propAndLinkDecorators,
@@ -52,7 +53,6 @@ import {
createViewCreate,
createCustomComponentNewExpression
} from './process_component_member';
import { builderParamObjectCollection } from './process_component_member';
import {
LogType,
LogInfo,
+98 -31
View File
@@ -41,29 +41,37 @@ import {
observedClassCollection,
enumCollection,
getComponentSet,
IComponentSet
IComponentSet,
builderParamObjectCollection
} from './validate_ui_syntax';
import { LogInfo, LogType } from './utils';
import { projectConfig } from '../main';
import { isOhmUrl, resolveSourceFile } from './resolve_ohm_url';
export default function processImport(node: ts.ImportDeclaration | ts.ImportEqualsDeclaration |
ts.ExportDeclaration, pagesDir: string, log: LogInfo[]): void {
ts.ExportDeclaration, pagesDir: string, log: LogInfo[], asName: Map<string, string> = new Map(),
isEntryPage: boolean = true): void {
let filePath: string;
let defaultName: string;
const asName: Map<string, string> = new Map();
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
filePath = node.moduleSpecifier.getText().replace(/'|"/g, '');
if (ts.isImportDeclaration(node) && node.importClause && node.importClause.name &&
ts.isIdentifier(node.importClause.name)) {
defaultName = node.importClause.name.escapedText.toString();
if (isEntryPage) {
asName.set(defaultName, defaultName);
}
}
if (ts.isImportDeclaration(node) && node.importClause && node.importClause.namedBindings &&
ts.isNamedImports(node.importClause.namedBindings) &&
node.importClause.namedBindings.elements) {
node.importClause.namedBindings.elements && isEntryPage) {
node.importClause.namedBindings.elements.forEach(item => {
if (item.name && item.propertyName && ts.isIdentifier(item.name) &&
ts.isIdentifier(item.propertyName)) {
asName.set(item.propertyName.escapedText.toString(), item.name.escapedText.toString());
if (item.name && ts.isIdentifier(item.name)) {
if (item.propertyName && ts.isIdentifier(item.propertyName) && asName) {
asName.set(item.propertyName.escapedText.toString(), item.name.escapedText.toString());
} else {
asName.set(item.name.escapedText.toString(), item.name.escapedText.toString());
}
}
});
}
@@ -72,14 +80,20 @@ export default function processImport(node: ts.ImportDeclaration | ts.ImportEqua
node.moduleReference.expression && ts.isStringLiteral(node.moduleReference.expression)) {
filePath = node.moduleReference.expression.text;
defaultName = node.name.escapedText.toString();
if (isEntryPage) {
asName.set(defaultName, defaultName);
}
}
}
if (filePath && path.extname(filePath) !== EXTNAME_ETS && !isModule(filePath)) {
if (filePath && path.extname(filePath) !== EXTNAME_ETS && !isModule(filePath) && !isOhmUrl(filePath)) {
filePath += EXTNAME_ETS;
}
try {
let fileResolvePath: string;
if (/^(\.|\.\.)\//.test(filePath) && filePath.indexOf(NODE_MODULES) < 0) {
if (isOhmUrl(filePath) && filePath.indexOf(NODE_MODULES) < 0) {
fileResolvePath = resolveSourceFile(filePath);
} else if (/^(\.|\.\.)\//.test(filePath) && filePath.indexOf(NODE_MODULES) < 0) {
fileResolvePath = path.resolve(pagesDir, filePath);
} else if (/^\//.test(filePath) && filePath.indexOf(NODE_MODULES) < 0) {
fileResolvePath = filePath;
@@ -94,7 +108,8 @@ export default function processImport(node: ts.ImportDeclaration | ts.ImportEqua
}))));
const sourceFile: ts.SourceFile = ts.createSourceFile(filePath, content,
ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
visitAllNode(sourceFile, defaultName, asName, path.dirname(fileResolvePath), log, new Set(), new Set());
visitAllNode(sourceFile, defaultName, asName, path.dirname(fileResolvePath), log, new Set(),
new Set(), new Set(), new Map());
}
} catch (e) {
// ignore
@@ -102,7 +117,8 @@ export default function processImport(node: ts.ImportDeclaration | ts.ImportEqua
}
function visitAllNode(node: ts.Node, defaultNameFromParent: string, asNameFromParent: Map<string, string>,
pagesDir: string, log: LogInfo[], entryCollection: Set<string>, exportCollection: Set<string>) {
pagesDir: string, log: LogInfo[], entryCollection: Set<string>, exportCollection: Set<string>,
defaultCollection: Set<string>, asExportCollection: Map<string, string>) {
if (isObservedClass(node)) {
// @ts-ignore
observedClassCollection.add(node.name.getText());
@@ -117,12 +133,18 @@ function visitAllNode(node: ts.Node, defaultNameFromParent: string, asNameFromPa
if (ts.isClassDeclaration(node) && ts.isIdentifier(node.name) && isCustomComponent(node)) {
addDependencies(node, defaultNameFromParent, asNameFromParent);
isExportEntry(node, log, entryCollection, exportCollection);
if (asExportCollection.has(node.name.getText())) {
componentCollection.customComponents.add(asExportCollection.get(node.name.getText()));
}
if (!defaultNameFromParent && node.modifiers && node.modifiers.length >= 2 &&
node.modifiers[0] && node.modifiers[0].kind === ts.SyntaxKind.ExportKeyword &&
node.modifiers[1] && node.modifiers[1].kind === ts.SyntaxKind.DefaultKeyword &&
hasCollection(node.name)) {
addDefaultExport(node);
}
if (defaultCollection.has(node.name.getText())) {
componentCollection.customComponents.add('default');
}
}
if (ts.isExportAssignment(node) && node.expression && ts.isIdentifier(node.expression) &&
hasCollection(node.expression)) {
@@ -133,10 +155,17 @@ function visitAllNode(node: ts.Node, defaultNameFromParent: string, asNameFromPa
setDependencies(defaultNameFromParent,
linkCollection.get(node.expression.escapedText.toString()),
propertyCollection.get(node.expression.escapedText.toString()),
propCollection.get(node.expression.escapedText.toString()));
propCollection.get(node.expression.escapedText.toString()),
builderParamObjectCollection.get(node.expression.escapedText.toString()));
}
addDefaultExport(node);
}
if (ts.isExportAssignment(node) && node.expression && ts.isIdentifier(node.expression)) {
if (defaultNameFromParent) {
asNameFromParent.set(node.expression.getText(), asNameFromParent.get(defaultNameFromParent));
}
defaultCollection.add(node.expression.getText());
}
if (ts.isExportDeclaration(node) && node.exportClause &&
ts.isNamedExports(node.exportClause) && node.exportClause.elements) {
node.exportClause.elements.forEach(item => {
@@ -145,15 +174,24 @@ function visitAllNode(node: ts.Node, defaultNameFromParent: string, asNameFromPa
remindExportEntryComponent(node, log);
}
if (item.name && item.propertyName && ts.isIdentifier(item.name) &&
ts.isIdentifier(item.propertyName) && hasCollection(item.propertyName)) {
let asExportName: string = item.name.escapedText.toString();
const asExportPropertyName: string = item.propertyName.escapedText.toString();
if (asNameFromParent.has(asExportName)) {
asExportName = asNameFromParent.get(asExportName);
ts.isIdentifier(item.propertyName)) {
if (hasCollection(item.propertyName)) {
let asExportName: string = item.name.escapedText.toString();
const asExportPropertyName: string = item.propertyName.escapedText.toString();
if (asNameFromParent.has(asExportName)) {
asExportName = asNameFromParent.get(asExportName);
}
setDependencies(asExportName, linkCollection.get(asExportPropertyName),
propertyCollection.get(asExportPropertyName),
propCollection.get(asExportPropertyName),
builderParamObjectCollection.get(asExportPropertyName));
}
setDependencies(asExportName, linkCollection.get(asExportPropertyName),
propertyCollection.get(asExportPropertyName),
propCollection.get(asExportPropertyName));
asExportCollection.set(item.propertyName.escapedText.toString(), item.name.escapedText.toString());
}
if (item.name && ts.isIdentifier(item.name) && asNameFromParent.has(item.name.escapedText.toString()) &&
item.propertyName && ts.isIdentifier(item.propertyName)) {
asNameFromParent.set(item.propertyName.escapedText.toString(),
asNameFromParent.get(item.name.escapedText.toString()));
}
});
}
@@ -163,12 +201,34 @@ function visitAllNode(node: ts.Node, defaultNameFromParent: string, asNameFromPa
node.exportClause.elements) {
node.exportClause.elements.forEach(item => {
exportCollection.add((item.propertyName ? item.propertyName : item.name).escapedText.toString());
if (item.propertyName && ts.isIdentifier(item.propertyName) && item.name &&
ts.isIdentifier(item.name) && asNameFromParent.has(item.name.escapedText.toString())) {
asNameFromParent.set(item.propertyName.escapedText.toString(),
asNameFromParent.get(item.name.escapedText.toString()));
defaultCollection.add(item.name.escapedText.toString());
}
});
}
processImport(node, pagesDir, log);
processImport(node, pagesDir, log, asNameFromParent);
}
node.getChildren().forEach((item: ts.Node) => visitAllNode(item, defaultNameFromParent,
asNameFromParent, pagesDir, log, entryCollection, exportCollection));
if (ts.isImportDeclaration(node)) {
if (node.importClause && node.importClause.name && ts.isIdentifier(node.importClause.name)) {
processImport(node, pagesDir, log, asNameFromParent, false);
} else if (node.importClause && node.importClause.namedBindings &&
ts.isNamedImports(node.importClause.namedBindings) && node.importClause.namedBindings.elements) {
node.importClause.namedBindings.elements.forEach(item => {
if (item.name && ts.isIdentifier(item.name) && asNameFromParent.has(item.name.escapedText.toString())) {
if (item.propertyName && ts.isIdentifier(item.propertyName)) {
asNameFromParent.set(item.propertyName.escapedText.toString(),
asNameFromParent.get(item.name.escapedText.toString()));
}
}
});
processImport(node, pagesDir, log, asNameFromParent, false);
}
}
node.getChildren().reverse().forEach((item: ts.Node) => visitAllNode(item, defaultNameFromParent,
asNameFromParent, pagesDir, log, entryCollection, exportCollection, defaultCollection, asExportCollection));
}
function isExportEntry(node: ts.ClassDeclaration, log: LogInfo[], entryCollection: Set<string>,
@@ -214,12 +274,13 @@ function addDependencies(node: ts.ClassDeclaration, defaultNameFromParent: strin
node.modifiers[1] && node.modifiers[0].kind === ts.SyntaxKind.ExportKeyword &&
node.modifiers[1].kind === ts.SyntaxKind.DefaultKeyword) {
setDependencies(defaultNameFromParent, ComponentSet.links, ComponentSet.properties,
ComponentSet.props);
ComponentSet.props, ComponentSet.builderParams);
} else if (asNameFromParent.has(componentName)) {
setDependencies(asNameFromParent.get(componentName), ComponentSet.links, ComponentSet.properties,
ComponentSet.props);
ComponentSet.props, ComponentSet.builderParams);
} else {
setDependencies(componentName, ComponentSet.links, ComponentSet.properties, ComponentSet.props);
setDependencies(componentName, ComponentSet.links, ComponentSet.properties, ComponentSet.props,
ComponentSet.builderParams);
}
}
@@ -235,18 +296,24 @@ function addDefaultExport(node: ts.ClassDeclaration | ts.ExportAssignment): void
setDependencies(CUSTOM_COMPONENT_DEFAULT,
linkCollection.has(CUSTOM_COMPONENT_DEFAULT) ?
new Set([...linkCollection.get(CUSTOM_COMPONENT_DEFAULT), ...linkCollection.get(name)]) :
linkCollection.get(name), propertyCollection.has(CUSTOM_COMPONENT_DEFAULT) ?
new Set([...propertyCollection.get(CUSTOM_COMPONENT_DEFAULT), ...propertyCollection.get(name)]) :
propertyCollection.get(name), propCollection.has(CUSTOM_COMPONENT_DEFAULT) ?
linkCollection.get(name),
propertyCollection.has(CUSTOM_COMPONENT_DEFAULT) ?
new Set([...propertyCollection.get(CUSTOM_COMPONENT_DEFAULT),
...propertyCollection.get(name)]) : propertyCollection.get(name),
propCollection.has(CUSTOM_COMPONENT_DEFAULT) ?
new Set([...propCollection.get(CUSTOM_COMPONENT_DEFAULT), ...propCollection.get(name)]) :
propCollection.get(name));
propCollection.get(name),
builderParamObjectCollection.has(CUSTOM_COMPONENT_DEFAULT) ?
new Set([...builderParamObjectCollection.get(CUSTOM_COMPONENT_DEFAULT),
...builderParamObjectCollection.get(name)]) : builderParamObjectCollection.get(name));
}
function setDependencies(component: string, linkArray: Set<string>, propertyArray: Set<string>,
propArray: Set<string>): void {
propArray: Set<string>, builderParamArray: Set<string>): void {
linkCollection.set(component, linkArray);
propertyCollection.set(component, propertyArray);
propCollection.set(component, propArray);
builderParamObjectCollection.set(component, builderParamArray);
componentCollection.customComponents.add(component);
}
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import ts from 'typescript';
import {
BUILD_ON
} from './pre_define';
import { writeFileSyncByNode } from './utils';
export function processJs(program: ts.Program, ut = false): Function {
return (context: ts.TransformationContext) => {
return (node: ts.SourceFile) => {
if (process.env.compiler === BUILD_ON) {
writeFileSyncByNode(node, false);
return node;
} else {
return node;
}
};
};
}
+14
View File
@@ -0,0 +1,14 @@
import { writeFileSyncByString } from './utils';
import { projectConfig } from '../main';
import {
ESMODULE,
ARK
} from './pre_define';
module.exports = function processjs2file(source: string): string {
if (projectConfig.compileMode === ESMODULE && projectConfig.processTs === false
&& process.env.compilerType && process.env.compilerType === ARK) {
writeFileSyncByString(this.resourcePath, source, false);
}
return source;
};
+17 -3
View File
@@ -42,14 +42,17 @@ import {
SET_CONTROLLER_CTR_TYPE,
SET_CONTROLLER_METHOD,
JS_DIALOG,
CUSTOM_DIALOG_CONTROLLER_BUILDER
CUSTOM_DIALOG_CONTROLLER_BUILDER,
ESMODULE,
ARK
} from './pre_define';
import {
componentInfo,
LogInfo,
LogType,
hasDecorator,
FileLog
FileLog,
writeFileSyncByNode
} from './utils';
import {
processComponentBlock,
@@ -67,7 +70,10 @@ import {
localStorageLinkCollection,
localStoragePropCollection
} from './validate_ui_syntax';
import { projectConfig, resources } from '../main';
import {
resources,
projectConfig
} from '../main';
import { createCustomComponentNewExpression, createViewCreate } from './process_component_member';
export const transformLog: FileLog = new FileLog();
@@ -82,6 +88,10 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
if (process.env.compiler === BUILD_ON) {
if (!ut && (path.basename(node.fileName) === 'app.ets' || /\.ts$/.test(node.fileName))) {
node = ts.visitEachChild(node, processResourceNode, context);
if (projectConfig.compileMode === ESMODULE && projectConfig.processTs === true
&& process.env.compilerType && process.env.compilerType === ARK) {
writeFileSyncByNode(node, true);
}
return node;
}
transformLog.sourceFile = node;
@@ -97,6 +107,10 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
});
node = ts.factory.updateSourceFile(node, statements);
INTERFACE_NODE_SET.clear();
if (projectConfig.compileMode === ESMODULE && projectConfig.processTs === true
&& process.env.compilerType && process.env.compilerType === ARK) {
writeFileSyncByNode(node, true);
}
return node;
} else {
return node;
+84
View File
@@ -0,0 +1,84 @@
import * as fs from 'fs';
import * as path from 'path';
import { logger } from './compile_info';
const { projectConfig } = require('../main');
const red: string = '\u001b[31m';
const reset: string = '\u001b[39m';
const REG_OHM_URL: RegExp = /^@bundle:(\S+)\/(\S+)\/(ets|js)\/(\S+)$/;
export class OHMResolverPlugin {
private source: any;
private target: any;
constructor(source = 'resolve', target = 'resolve') {
this.source = source;
this.target = target;
}
apply(resolver) {
const target: any = resolver.ensureHook(this.target);
resolver.getHook(this.source).tapAsync('OHMResolverPlugin', (request, resolveContext, callback) => {
if (isOhmUrl(request.request)) {
const resolvedSourceFile: string = resolveSourceFile(request.request);
const obj = Object.assign({}, request, {
request: resolvedSourceFile
});
return resolver.doResolve(target, obj, null, resolveContext, callback);
}
callback();
});
}
}
export function isOhmUrl(moduleRequest: string): boolean {
return !!/^@(\S+):/.test(moduleRequest);
}
function addExtension(file: string, srcPath: string): string {
if (path.extname(file) !== '') {
return file;
}
let extension: string = '.d.ts';
if (fs.existsSync(file + '.ets') && fs.statSync(file + '.ets').isFile()) {
extension = '.ets';
}
if (fs.existsSync(file + '.ts') && fs.statSync(file + '.ts').isFile()) {
if (extension !== '.d.ts') {
logger.error(red, `ETS:ERROR Failed to compile with files with same name ${srcPath} in the same directory`, reset);
}
extension = '.ts';
}
if (fs.existsSync(file + '.js') && fs.statSync(file + '.js').isFile()) {
if (extension !== '.d.ts') {
logger.error(red, `ETS:ERROR Failed to compile with files with same name ${srcPath} in the same directory`, reset);
}
extension = '.js';
}
return file + extension;
}
export function resolveSourceFile(ohmUrl: string): string {
const result: RegExpMatchArray = ohmUrl.match(REG_OHM_URL);
const moduleName: string = result[2];
const srcKind: string = result[3];
let file: string = '';
if (projectConfig.aceBuildJson) {
const modulePath: string = projectConfig.modulePathMap[moduleName];
file = path.join(modulePath, 'src/main', srcKind, result[4]);
} else {
logger.error(red, `ETS:ERROR Failed to resolve OhmUrl because of aceBuildJson not existing `, reset);
}
file = addExtension(file, result[4]);
if (!fs.existsSync(file) || !fs.statSync(file).isFile()) {
logger.error(red, `ETS:ERROR Failed to resolve existed file by this ohm url ${ohmUrl} `, reset);
}
return file;
}
+243 -4
View File
@@ -13,16 +13,38 @@
* limitations under the License.
*/
import ts from 'typescript';
import path from 'path';
import ts from 'typescript';
import fs from 'fs';
import { projectConfig } from '../main';
import { createHash } from 'crypto';
import { processSystemApi } from './validate_ui_syntax';
import {
NODE_MODULES,
TEMPRARY,
MAIN,
AUXILIARY,
ZERO,
ONE,
EXTNAME_JS,
EXTNAME_TS,
EXTNAME_MJS,
EXTNAME_CJS,
EXTNAME_ABC,
EXTNAME_ETS,
EXTNAME_TS_MAP,
EXTNAME_JS_MAP
} from './pre_define';
export enum LogType {
ERROR = 'ERROR',
WARN = 'WARN',
NOTE = 'NOTE'
}
export const TEMPORARYS: string = 'temporarys';
export const BUILD: string = 'build';
export const SRC_MAIN: string = 'src/main';
const TS_NOCHECK: string = '// @ts-nocheck';
export interface LogInfo {
type: LogType,
@@ -217,9 +239,9 @@ export function toUnixPath(data: string): string {
return data;
}
export function toHashData(path: string) {
const content = fs.readFileSync(path);
const hash = createHash('sha256');
export function toHashData(path: string): any {
const content: string = fs.readFileSync(path).toString();
const hash: any = createHash('sha256');
hash.update(content);
return hash.digest('hex');
}
@@ -234,3 +256,220 @@ export function writeFileSync(filePath: string, content: string): void {
fs.writeFileSync(filePath, content);
}
export function genTemporaryPath(filePath: string, projectPath: string, buildPath: string, toTsFile: boolean = true): string {
filePath = toUnixPath(filePath);
if (filePath.endsWith(EXTNAME_MJS)) {
filePath = filePath.replace(/\.mjs$/, EXTNAME_JS);
}
if (filePath.endsWith(EXTNAME_CJS)) {
filePath = filePath.replace(/\.cjs$/, EXTNAME_JS);
}
projectPath = toUnixPath(projectPath);
const hapPath: string = toUnixPath(projectConfig.projectRootPath);
const tempFilePath: string = filePath.replace(hapPath, '');
if (checkNodeModulesFile(filePath, projectPath)) {
const fakeNodeModulesPath: string = toUnixPath(path.resolve(projectConfig.projectRootPath, NODE_MODULES));
const dataTmps: string[] = tempFilePath.split(NODE_MODULES);
let output: string = '';
if (filePath.indexOf(fakeNodeModulesPath) === -1) {
const sufStr: string = dataTmps[dataTmps.length - 1];
output = path.join(buildPath, TEMPRARY, NODE_MODULES, MAIN, sufStr);
} else {
const sufStr: string = dataTmps[dataTmps.length - 1];
output = path.join(buildPath, TEMPRARY, NODE_MODULES, AUXILIARY, sufStr);
}
return output;
}
if (filePath.indexOf(projectPath) !== -1) {
const sufStr: string = filePath.replace(projectPath, '');
const output: string = path.join(buildPath, TEMPRARY, sufStr);
return output;
}
return '';
}
export function genBuildPath(filePath: string, projectPath: string, buildPath: string, toTsFile: boolean = true): string {
filePath = toUnixPath(filePath);
if (filePath.endsWith(EXTNAME_MJS)) {
filePath = filePath.replace(/\.mjs$/, EXTNAME_JS);
}
if (filePath.endsWith(EXTNAME_CJS)) {
filePath = filePath.replace(/\.cjs$/, EXTNAME_JS);
}
projectPath = toUnixPath(projectPath);
const hapPath: string = toUnixPath(projectConfig.projectRootPath);
const tempFilePath: string = filePath.replace(hapPath, '');
if (checkNodeModulesFile(filePath, projectPath)) {
filePath = toUnixPath(filePath);
const fakeNodeModulesPath: string = toUnixPath(path.resolve(projectConfig.projectRootPath, NODE_MODULES));
const dataTmps: string[] = tempFilePath.split(NODE_MODULES);
let output: string = '';
if (filePath.indexOf(fakeNodeModulesPath) === -1) {
const sufStr: string = dataTmps[dataTmps.length - 1];
output = path.join(projectConfig.nodeModulesPath, ZERO, sufStr);
} else {
const sufStr: string = dataTmps[dataTmps.length - 1];
output = path.join(projectConfig.nodeModulesPath, ONE, sufStr);
}
return output;
}
if (filePath.indexOf(projectPath) !== -1) {
const sufStr: string = filePath.replace(projectPath, '');
const output: string = path.join(buildPath, sufStr);
return output;
}
return '';
}
export function checkNodeModulesFile(filePath: string, projectPath: string): boolean {
filePath = toUnixPath(filePath);
projectPath = toUnixPath(projectPath);
const hapPath: string = toUnixPath(projectConfig.projectRootPath);
const tempFilePath: string = filePath.replace(hapPath, '');
if (tempFilePath.indexOf(NODE_MODULES) !== -1) {
const fakeNodeModulesPath: string = toUnixPath(path.resolve(projectConfig.projectRootPath, NODE_MODULES));
if (filePath.indexOf(fakeNodeModulesPath) !== -1) {
return true;
}
if (projectConfig.modulePathMap) {
for (const key in projectConfig.modulePathMap) {
const value: string = projectConfig.modulePathMap[key];
const fakeModuleNodeModulesPath: string = toUnixPath(path.resolve(value, NODE_MODULES));
if (filePath.indexOf(fakeModuleNodeModulesPath) !== -1) {
return true;
}
}
}
}
return false;
}
export function mkdirsSync(dirname: string): boolean {
if (fs.existsSync(dirname)) {
return true;
} else if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
return false;
}
export function writeFileSyncByString(sourcePath: string, sourceCode: string, toTsFile: boolean): void {
const temporaryFile: string = genTemporaryPath(sourcePath, projectConfig.projectPath, process.env.cachePath, toTsFile);
if (temporaryFile.length === 0) {
return;
}
mkdirsSync(path.dirname(temporaryFile));
fs.writeFileSync(temporaryFile, sourceCode);
return;
}
export function writeFileSyncByNode(node: ts.SourceFile, toTsFile: boolean): void {
if (toTsFile) {
const newStatements: ts.Node[] = [];
const tsIgnoreNode: ts.Node = ts.factory.createExpressionStatement(ts.factory.createIdentifier(TS_NOCHECK));
newStatements.push(tsIgnoreNode);
if (node.statements && node.statements.length) {
newStatements.push(...node.statements);
}
node = ts.factory.updateSourceFile(node, newStatements);
}
const mixedInfo: {content: string, sourceMapContent: string} = genContentAndSourceMapInfo(node, toTsFile);
let temporaryFile: string = genTemporaryPath(node.fileName, projectConfig.projectPath, process.env.cachePath, toTsFile);
if (temporaryFile.length === 0) {
return;
}
let temporarySourceMapFile: string = '';
if (temporaryFile.endsWith(EXTNAME_ETS)) {
if (toTsFile) {
temporaryFile = temporaryFile.replace(/\.ets$/, EXTNAME_TS);
} else {
temporaryFile = temporaryFile.replace(/\.ets$/, EXTNAME_JS);
}
temporarySourceMapFile = genSourceMapFileName(temporaryFile);
} else {
if (!toTsFile) {
temporaryFile = temporaryFile.replace(/\.ts$/, EXTNAME_JS);
temporarySourceMapFile = genSourceMapFileName(temporaryFile);
}
}
mkdirsSync(path.dirname(temporaryFile));
fs.writeFileSync(temporaryFile, mixedInfo.content);
if (temporarySourceMapFile.length > 0 && projectConfig.buildArkMode === 'debug') {
fs.writeFileSync(temporarySourceMapFile, mixedInfo.sourceMapContent);
}
}
function genContentAndSourceMapInfo(node: ts.SourceFile, toTsFile: boolean): any {
const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
const options: ts.CompilerOptions = {
sourceMap: true
};
const mapOpions: any = {
sourceMap: true,
inlineSourceMap: false,
inlineSources: false,
sourceRoot: '',
mapRoot: '',
extendedDiagnostics: false
};
const host: ts.CompilerHost = ts.createCompilerHost(options);
const fileName: string = node.fileName;
// @ts-ignore
const sourceMapGenerator: any = ts.createSourceMapGenerator(
host,
// @ts-ignore
ts.getBaseFileName(fileName),
'',
'',
mapOpions
);
// @ts-ignore
const writer: any = ts.createTextWriter(
// @ts-ignore
ts.getNewLineCharacter({newLine: ts.NewLineKind.LineFeed, removeComments: false}));
printer['writeFile'](node, writer, sourceMapGenerator);
const sourceMapJson: any = sourceMapGenerator.toJSON();
sourceMapJson['sources'] = [fileName];
const result: string = writer.getText();
let content: string = result;
content = processSystemApi(content, true);
if (toTsFile) {
content = result.replace(`${TS_NOCHECK};`, TS_NOCHECK);
}
const sourceMapContent: string = JSON.stringify(sourceMapJson);
return {
content: content,
sourceMapContent: sourceMapContent
};
}
export function genAbcFileName(temporaryFile: string): string {
let abcFile: string = temporaryFile;
if (temporaryFile.endsWith(EXTNAME_TS)) {
abcFile = temporaryFile.replace(/\.ts$/, EXTNAME_ABC);
} else {
abcFile = temporaryFile.replace(/\.js$/, EXTNAME_ABC);
}
return abcFile;
}
export function genSourceMapFileName(temporaryFile: string): string {
let abcFile: string = temporaryFile;
if (temporaryFile.endsWith(EXTNAME_TS)) {
abcFile = temporaryFile.replace(/\.ts$/, EXTNAME_TS_MAP);
} else {
abcFile = temporaryFile.replace(/\.js$/, EXTNAME_JS_MAP);
}
return abcFile;
}
+199 -65
View File
@@ -15,6 +15,7 @@
import ts from 'typescript';
import path from 'path';
import fs from 'fs';
import {
INNER_COMPONENT_DECORATORS,
@@ -46,7 +47,8 @@ import {
TTOGGLE_CHECKBOX,
TOGGLE_SWITCH,
COMPONENT_BUTTON,
COMPONENT_TOGGLE
COMPONENT_TOGGLE,
COMPONENT_BUILDERPARAM_DECORATOR
} from './pre_define';
import {
INNER_COMPONENT_NAMES,
@@ -57,19 +59,21 @@ import {
EXTEND_ATTRIBUTE,
GLOBAL_STYLE_FUNCTION,
STYLES_ATTRIBUTE,
CUSTOM_BUILDER_METHOD,
CUSTOM_BUILDER_METHOD
} from './component_map';
import {
LogType,
LogInfo,
componentInfo,
addLog,
hasDecorator
hasDecorator,
toUnixPath
} from './utils';
import { projectConfig, abilityPagesFullPath } from '../main';
import { collectExtend } from './process_ui_syntax';
import { importModuleCollection } from './ets_checker';
import { isExtendFunction } from './process_ui_syntax';
import { isOhmUrl } from './resolve_ohm_url';
import { logger } from './compile_info';
export interface ComponentCollection {
localStorageName: string;
@@ -94,6 +98,7 @@ export interface IComponentSet {
objectLinks: Set<string>;
localStorageLink: Map<string, Set<string>>;
localStorageProp: Map<string, Set<string>>;
builderParams: Set<string>;
}
export const componentCollection: ComponentCollection = {
@@ -121,11 +126,13 @@ export const storageLinkCollection: Map<string, Set<string>> = new Map();
export const provideCollection: Map<string, Set<string>> = new Map();
export const consumeCollection: Map<string, Set<string>> = new Map();
export const objectLinkCollection: Map<string, Set<string>> = new Map();
export const builderParamObjectCollection: Map<string, Set<string>> = new Map();
export const localStorageLinkCollection: Map<string, Map<string, Set<string>>> = new Map();
export const localStoragePropCollection: Map<string, Map<string, Set<string>>> = new Map();
export const isStaticViewCollection: Map<string, boolean> = new Map();
export const packageCollection: Map<string, Array<string>> = new Map();
export const moduleCollection: Set<string> = new Set();
export const useOSFiles: Set<string> = new Set();
@@ -331,7 +338,8 @@ function visitAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, allComponent
if (ts.isStructDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
collectComponentProps(node);
}
if (ts.isMethodDeclaration(node) && hasDecorator(node, COMPONENT_BUILDER_DECORATOR)) {
if ((ts.isMethodDeclaration(node) || ts.isFunctionDeclaration(node)) &&
hasDecorator(node, COMPONENT_BUILDER_DECORATOR)) {
CUSTOM_BUILDER_METHOD.add(node.name.getText());
}
if (ts.isFunctionDeclaration(node) && isExtendFunction(node)) {
@@ -683,6 +691,7 @@ function collectComponentProps(node: ts.StructDeclaration): void {
objectLinkCollection.set(componentName, ComponentSet.objectLinks);
localStorageLinkCollection.set(componentName, ComponentSet.localStorageLink);
localStoragePropCollection.set(componentName, ComponentSet.localStorageProp);
builderParamObjectCollection.set(componentName, ComponentSet.builderParams);
}
export function getComponentSet(node: ts.StructDeclaration): IComponentSet {
@@ -696,13 +705,14 @@ export function getComponentSet(node: ts.StructDeclaration): IComponentSet {
const provides: Set<string> = new Set();
const consumes: Set<string> = new Set();
const objectLinks: Set<string> = new Set();
const builderParams: Set<string> = new Set();
const localStorageLink: Map<string, Set<string>> = new Map();
const localStorageProp: Map<string, Set<string>> = new Map();
traversalComponentProps(node, properties, regulars, states, links, props, storageProps,
storageLinks, provides, consumes, objectLinks, localStorageLink, localStorageProp);
storageLinks, provides, consumes, objectLinks, localStorageLink, localStorageProp, builderParams);
return {
properties, regulars, states, links, props, storageProps, storageLinks, provides,
consumes, objectLinks, localStorageLink, localStorageProp
consumes, objectLinks, localStorageLink, localStorageProp, builderParams
};
}
@@ -710,7 +720,8 @@ function traversalComponentProps(node: ts.StructDeclaration, properties: Set<str
regulars: Set<string>, states: Set<string>, links: Set<string>, props: Set<string>,
storageProps: Set<string>, storageLinks: Set<string>, provides: Set<string>,
consumes: Set<string>, objectLinks: Set<string>,
localStorageLink: Map<string, Set<string>>, localStorageProp: Map<string, Set<string>>): void {
localStorageLink: Map<string, Set<string>>, localStorageProp: Map<string, Set<string>>,
builderParams: Set<string>): void {
let isStatic: boolean = true;
if (node.members) {
const currentMethodCollection: Set<string> = new Set();
@@ -727,7 +738,8 @@ function traversalComponentProps(node: ts.StructDeclaration, properties: Set<str
if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName)) {
dollarCollection.add('$' + propertyName);
collectionStates(item.decorators[i], decoratorName, propertyName, states, links, props, storageProps,
storageLinks, provides, consumes, objectLinks, localStorageLink, localStorageProp);
storageLinks, provides, consumes, objectLinks, localStorageLink, localStorageProp,
builderParams);
}
}
}
@@ -744,7 +756,8 @@ function traversalComponentProps(node: ts.StructDeclaration, properties: Set<str
function collectionStates(node: ts.Decorator, decorator: string, name: string,
states: Set<string>, links: Set<string>, props: Set<string>, storageProps: Set<string>,
storageLinks: Set<string>, provides: Set<string>, consumes: Set<string>, objectLinks: Set<string>,
localStorageLink: Map<string, Set<string>>, localStorageProp: Map<string, Set<string>>): void {
localStorageLink: Map<string, Set<string>>, localStorageProp: Map<string, Set<string>>,
builderParams: Set<string>): void {
switch (decorator) {
case COMPONENT_STATE_DECORATOR:
states.add(name);
@@ -770,6 +783,9 @@ function collectionStates(node: ts.Decorator, decorator: string, name: string,
case COMPONENT_OBJECT_LINK_DECORATOR:
objectLinks.add(name);
break;
case COMPONENT_BUILDERPARAM_DECORATOR:
builderParams.add(name);
break;
case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR :
collectionlocalStorageParam(node, name, localStorageLink);
break;
@@ -830,66 +846,184 @@ export function preprocessNewExtend(content: string, extendCollection?: Set<stri
});
}
export function processSystemApi(content: string, isProcessAllowList: boolean = false,
sourcePath: string = null, isSystemModule: boolean = false): string {
let REG_SYSTEM: RegExp;
if (isProcessAllowList) {
REG_SYSTEM =
/(import|const)\s+(.+)\s*=\s*(\_\_importDefault\()?require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)(\))?/g;
} else {
REG_SYSTEM =
/import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)/g;
function getPackageInfo(configFile: string): Array<string> {
if (packageCollection.has(configFile)) {
return packageCollection.get(configFile);
}
const REG_LIB_SO: RegExp =
/import\s+(.+)\s+from\s+['"]lib(\S+)\.so['"]|import\s+(.+)\s*=\s*require\(\s*['"]lib(\S+)\.so['"]\s*\)/g;
const systemValueCollection: Set<string> = new Set();
const newContent: string = content.replace(REG_LIB_SO, (_, item1, item2, item3, item4) => {
const libSoValue: string = item1 || item3;
const libSoKey: string = item2 || item4;
if (sourcePath) {
useOSFiles.add(sourcePath);
}
return `var ${libSoValue} = globalThis.requireNapi("${libSoKey}", true);`;
}).replace(REG_SYSTEM, (item, item1, item2, item3, item4, item5, item6, item7) => {
let moduleType: string = item2 || item5;
let systemKey: string = item3 || item6;
let systemValue: string = item1 || item4;
if (!VALIDATE_MODULE.includes(systemValue)) {
importModuleCollection.add(systemValue);
}
if (!isProcessAllowList && !isSystemModule) {
return item;
} else if (isProcessAllowList) {
systemValue = item2;
moduleType = item4;
systemKey = item5;
systemValueCollection.add(systemValue);
}
moduleCollection.add(`${moduleType}.${systemKey}`);
if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) {
item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`;
} else if (moduleType === SYSTEM_PLUGIN) {
item = `var ${systemValue} = isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ? ` +
`globalThis.systemplugin.${systemKey} : globalThis.requireNapi('${systemKey}')`;
} else if (moduleType === OHOS_PLUGIN) {
item = `var ${systemValue} = globalThis.requireNapi('${systemKey}') || ` +
`(isSystemplugin('${systemKey}', '${OHOS_PLUGIN}') ? ` +
`globalThis.ohosplugin.${systemKey} : isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ` +
`? globalThis.systemplugin.${systemKey} : undefined)`;
}
return item;
});
return processInnerModule(newContent, systemValueCollection);
const data: any = JSON.parse(fs.readFileSync(configFile).toString());
const bundleName: string = data.app.bundleName;
const moduleName: string = data.module.name;
packageCollection.set(configFile, [bundleName, moduleName]);
return [bundleName, moduleName];
}
function processInnerModule(content: string, systemValueCollection: Set<string>): string {
systemValueCollection.forEach(element => {
const target: string = element.trim() + '.default';
while (content.includes(target)) {
content = content.replace(target, element.trim());
function replaceSystemApi(item: string, systemValue: string, moduleType: string, systemKey: string): string {
moduleCollection.add(`${moduleType}.${systemKey}`);
if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) {
item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`;
} else if (moduleType === SYSTEM_PLUGIN) {
item = `var ${systemValue} = isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ? ` +
`globalThis.systemplugin.${systemKey} : globalThis.requireNapi('${systemKey}')`;
} else if (moduleType === OHOS_PLUGIN) {
item = `var ${systemValue} = globalThis.requireNapi('${systemKey}') || ` +
`(isSystemplugin('${systemKey}', '${OHOS_PLUGIN}') ? ` +
`globalThis.ohosplugin.${systemKey} : isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ` +
`? globalThis.systemplugin.${systemKey} : undefined)`;
}
return item;
}
function replaceLibSo(importValue: string, libSoKey: string, sourcePath: string = null): string {
if (sourcePath) {
useOSFiles.add(sourcePath);
}
return `var ${importValue} = globalThis.requireNapi("${libSoKey}", true);`;
}
function replaceOhmStartsWithBundle(url: string, item: string, importValue: string, moduleRequest: string, sourcePath: string): string {
const urlResult: RegExpMatchArray | null = url.match(/^(\S+)\/(\S+)\/(\S+)\/(\S+)$/);
if (urlResult) {
const moduleKind: string = urlResult[3];
if (moduleKind === 'lib') {
const libSoKey: string = urlResult[4];
item = replaceLibSo(importValue, libSoKey, sourcePath);
}
}
return item;
}
function replaceOhmStartsWithModule(url: string, item: string, importValue: string, moduleRequest: string, sourcePath: string): string {
const urlResult: RegExpMatchArray | null = url.match(/^(\S+)\/(\S+)\/(\S+)$/);
if (urlResult && projectConfig.aceModuleJsonPath) {
const moduleName: string = urlResult[1];
const moduleKind: string = urlResult[2];
const modulePath: string = urlResult[3];
const bundleName: string = getPackageInfo(projectConfig.aceModuleJsonPath)[0];
moduleRequest = `@bundle:${bundleName}/${moduleName}/${moduleKind}/${modulePath}`;
item = moduleKind === 'lib' ? replaceLibSo(importValue, modulePath, sourcePath) :
item.replace(/['"](\S+)['"]/, '\"' + moduleRequest + '\"');
}
return item;
}
function replaceOhmStartsWithOhos(url: string, item: string, importValue:string, moduleRequest: string, isSystemModule: boolean): string {
url = url.replace('/', '.');
const urlResult: RegExpMatchArray | null = url.match(/^system\.(\S+)/);
moduleRequest = urlResult ? `@${url}` : `@ohos.${url}`;
if (!isSystemModule) {
item = item.replace(/['"](\S+)['"]/, '\"' + moduleRequest + '\"');
} else {
const moduleType: string = urlResult ? 'system' : 'ohos';
const systemKey: string = urlResult ? url.substring(7) : url;
item = replaceSystemApi(item, importValue, moduleType, systemKey);
}
return item;
}
function replaceOhmStartsWithLocal(url: string, item: string, importValue: string, moduleRequest: string, sourcePath: string): string {
const result: RegExpMatchArray | null = sourcePath.match(/(\S+)(\/|\\)src(\/|\\)main(\/|\\)(ets|js)(\/|\\)(\S+)/);
if (result && projectConfig.aceModuleJsonPath) {
const packageInfo: string[] = getPackageInfo(projectConfig.aceModuleJsonPath);
const urlResult: RegExpMatchArray | null = url.match(/^\/(ets|js|lib|node_modules)\/(\S+)$/);
if (urlResult) {
const moduleKind: string = urlResult[1];
const modulePath: string = urlResult[2];
if (moduleKind === 'lib') {
item = replaceLibSo(importValue, modulePath, sourcePath);
} else if (moduleKind === 'node_modules') {
moduleRequest = `${modulePath}`;
item = item.replace(/['"](\S+)['"]/, '\"' + moduleRequest + '\"');
} else {
moduleRequest = `@bundle:${packageInfo[0]}/${packageInfo[1]}/${moduleKind}/${modulePath}`;
item = item.replace(/['"](\S+)['"]/, '\"' + moduleRequest + '\"');
}
}
}
return item;
}
function replaceOhmUrl(isSystemModule: boolean, item: string, importValue: string, moduleRequest: string, sourcePath: string = null): string {
const result: RegExpMatchArray = moduleRequest.match(/^@(\S+):(\S+)$/);
const urlType: string = result[1];
const url: string = result[2];
switch (urlType) {
case 'bundle': {
item = replaceOhmStartsWithBundle(url, item, importValue, moduleRequest, sourcePath);
break;
}
case 'module': {
item = replaceOhmStartsWithModule(url, item, importValue, moduleRequest, sourcePath);
break;
}
case 'ohos': {
item = replaceOhmStartsWithOhos(url, item, importValue, moduleRequest, isSystemModule);
break;
}
case 'lib': {
item = replaceLibSo(importValue, url, sourcePath);
break;
}
case 'local': {
item = replaceOhmStartsWithLocal(url, item, importValue, moduleRequest, sourcePath);
break;
}
default:
logger.error('\u001b[31m', `ETS:ERROR Incorrect OpenHarmony module kind: ${urlType}`, '\u001b[39m');
}
return item;
}
function replaceRelativePath(item:string, moduleRequest: string, sourcePath: string): string {
// Do not replace relativePath to ohmUrl when building bundle
if (sourcePath && projectConfig.compileMode === 'esmodule') {
const filePath: string = path.resolve(path.dirname(sourcePath), moduleRequest);
const result: RegExpMatchArray | null = filePath.match(/(\S+)(\/|\\)src(\/|\\)main(\/|\\)(ets|js)(\/|\\)(\S+)/);
if (result && projectConfig.aceModuleJsonPath) {
const packageInfo: string[] = getPackageInfo(projectConfig.aceModuleJsonPath);
const bundleName: string = packageInfo[0];
const moduleName: string = packageInfo[1];
moduleRequest = `@bundle:${bundleName}/${moduleName}/${result[5]}/${toUnixPath(result[7])}`;
item = item.replace(/['"](\S+)['"]/, '\"' + moduleRequest + '\"');
}
}
return item;
}
export function processSystemApi(content: string, isProcessAllowList: boolean = false,
sourcePath: string = null, isSystemModule: boolean = false): string {
const REG_IMPORT_DECL: RegExp = isProcessAllowList ? /import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]/g :
/(import|export)\s+(.+)\s+from\s+['"](\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"](\S+)['"]\s*\)/g;
const processedContent: string = content.replace(REG_IMPORT_DECL, (item, item1, item2, item3, item4, item5) => {
const importValue: string = isProcessAllowList ? item1 : item2 || item4;
if (isProcessAllowList) {
return replaceSystemApi(item, importValue, item2, item3);
}
const moduleRequest: string = item3 || item5;
if (isOhmUrl(moduleRequest)) { // ohmURL
return replaceOhmUrl(isSystemModule, item, importValue, moduleRequest, sourcePath);
} else if (/^@(system|ohos)\./.test(moduleRequest)) { // ohos/system.api
// ets & ts file need compile with .d.ts, so do not replace at the phase of pre_process
if (!isSystemModule) {
return item;
}
const result: RegExpMatchArray = moduleRequest.match(/^@(system|ohos)\.(\S+)$/);
const moduleType: string = result[1];
const apiName: string = result[2];
return replaceSystemApi(item, importValue, moduleType, apiName);
} else if (/^(\.|\.\.)\//.test(moduleRequest)) { // relativePath
return replaceRelativePath(item, moduleRequest, sourcePath);
} else if (/^lib(\S+)\.so$/.test(moduleRequest)) { // libxxx.so
const result: RegExpMatchArray = moduleRequest.match(/^lib(\S+)\.so$/);
const libSoKey: string = result[1];
return replaceLibSo(importValue, libSoKey, sourcePath);
}
// node_modules
return item;
});
return content;
return processedContent;
}
const VALIDATE_MODULE_REG: RegExp = new RegExp('^(' + VALIDATE_MODULE.join('|') + ')');
+13
View File
@@ -23,4 +23,17 @@ export struct TestComponent {
.fontSize(32)
}
}
}
@Component
export struct CustomContainerExport {
header: string = "";
@BuilderParam closer: () => void;
build() {
Column() {
Text(this.header)
.fontSize(50)
this.closer()
}
}
}
+3 -27
View File
@@ -49,36 +49,12 @@ struct ImportTest {
`
exports.expectResult =
`"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const AllComponent = __importStar(require("./test/pages/NamespaceComponent"));
const TsModule_1 = __importDefault(require("./test/pages/TsModule"));
`import * as AllComponent from './test/pages/NamespaceComponent';
import TsModule from './test/pages/TsModule';
class ImportTest extends View {
constructor(compilerAssignedUniqueChildId, parent, params) {
super(compilerAssignedUniqueChildId, parent);
this.__myState1 = new ObservedPropertyObject(new TsModule_1.default(1).method(), this, "myState1");
this.__myState1 = new ObservedPropertyObject(new TsModule(1).method(), this, "myState1");
this.__myState2 = new ObservedPropertySimple(0, this, "myState2");
this.__myState3 = new ObservedPropertySimple(false, this, "myState3");
this.__myState4 = new ObservedPropertySimple('ImportTest', this, "myState4");
+11 -35
View File
@@ -21,7 +21,7 @@ LinkComponentDefault, {
LinkComponent3
} from './test/pages/LinkComponent'
import DefaultComponent from "./test/pages/DefaultComponent"
import AMDComponentDefault = require('./test/pages/AMDComponent')
import AMDComponentDefault from "./test/pages/AMDComponent"
import TsModule from './test/pages/TsModule'
@Entry
@@ -99,38 +99,14 @@ struct ImportTest {
`
exports.expectResult =
`"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const LinkComponent_1 = __importStar(require("./test/pages/LinkComponent"));
const DefaultComponent_1 = __importDefault(require("./test/pages/DefaultComponent"));
const AMDComponentDefault = require("./test/pages/AMDComponent");
const TsModule_1 = __importDefault(require("./test/pages/TsModule"));
`import LinkComponentDefault, { LinkComponent as LinkComponent1Ref, LinkComponent2 as LinkComponent2Ref, LinkComponent3 } from './test/pages/LinkComponent';
import DefaultComponent from "./test/pages/DefaultComponent";
import AMDComponentDefault from "./test/pages/AMDComponent";
import TsModule from './test/pages/TsModule';
class ImportTest extends View {
constructor(compilerAssignedUniqueChildId, parent, params) {
super(compilerAssignedUniqueChildId, parent);
this.__myState1 = new ObservedPropertyObject(new TsModule_1.default(1).method(), this, "myState1");
this.__myState1 = new ObservedPropertyObject(new TsModule(1).method(), this, "myState1");
this.__myState2 = new ObservedPropertySimple(0, this, "myState2");
this.__myState3 = new ObservedPropertySimple(false, this, "myState3");
this.__myState4 = new ObservedPropertySimple('ImportTest', this, "myState4");
@@ -185,7 +161,7 @@ class ImportTest extends View {
Column.create();
let earlierCreatedChild_2 = this.findChildById("2");
if (earlierCreatedChild_2 == undefined) {
View.create(new LinkComponent_1.LinkComponent2("2", this, {
View.create(new LinkComponent2Ref("2", this, {
LinkComponent2Link1: this.__myState1,
LinkComponent2Link2: this.__myState2,
LinkComponent2Link3: this.__myState3,
@@ -211,7 +187,7 @@ class ImportTest extends View {
Text.pop();
let earlierCreatedChild_3 = this.findChildById("3");
if (earlierCreatedChild_3 == undefined) {
View.create(new LinkComponent_1.LinkComponent("3", this, {
View.create(new LinkComponent1Ref("3", this, {
LinkComponent1Link1: this.__myState1,
LinkComponent1Link2: this.__myState2,
LinkComponent1Link3: this.__myState3,
@@ -233,7 +209,7 @@ class ImportTest extends View {
}
let earlierCreatedChild_4 = this.findChildById("4");
if (earlierCreatedChild_4 == undefined) {
View.create(new DefaultComponent_1.default("4", this, {
View.create(new DefaultComponent("4", this, {
DefaultComponentLink1: this.__myState1,
DefaultComponentLink2: this.__myState2,
DefaultComponentLink3: this.__myState3,
@@ -251,7 +227,7 @@ class ImportTest extends View {
}
let earlierCreatedChild_5 = this.findChildById("5");
if (earlierCreatedChild_5 == undefined) {
View.create(new LinkComponent_1.default("5", this, {
View.create(new LinkComponentDefault("5", this, {
LinkComponent3Link1: this.__myState1,
LinkComponent3Link2: this.__myState2,
LinkComponent3Link3: this.__myState3,
@@ -291,7 +267,7 @@ class ImportTest extends View {
}
let earlierCreatedChild_7 = this.findChildById("7");
if (earlierCreatedChild_7 == undefined) {
View.create(new LinkComponent_1.LinkComponent3("7", this, {
View.create(new LinkComponent3("7", this, {
LinkComponent3Link1: this.__myState1,
LinkComponent3Link2: this.__myState2,
LinkComponent3Link3: this.__myState3,
+5 -10
View File
@@ -53,17 +53,12 @@ struct ImportTest {
`
exports.expectResult =
`"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ExportStarComponent_1 = require("./test/pages/ExportStarComponent");
const TsModule_1 = __importDefault(require("./test/pages/TsModule"));
`import { AllStarComponent } from './test/pages/ExportStarComponent';
import TsModule from './test/pages/TsModule';
class ImportTest extends View {
constructor(compilerAssignedUniqueChildId, parent, params) {
super(compilerAssignedUniqueChildId, parent);
this.__myState1 = new ObservedPropertyObject(new TsModule_1.default(1).method(), this, "myState1");
this.__myState1 = new ObservedPropertyObject(new TsModule(1).method(), this, "myState1");
this.__myState2 = new ObservedPropertySimple(0, this, "myState2");
this.__myState3 = new ObservedPropertySimple(false, this, "myState3");
this.__myState4 = new ObservedPropertySimple('ImportTest', this, "myState4");
@@ -118,7 +113,7 @@ class ImportTest extends View {
Column.create();
let earlierCreatedChild_2 = this.findChildById("2");
if (earlierCreatedChild_2 == undefined) {
View.create(new ExportStarComponent_1.AllStarComponent.ExportComponent("2", this, {
View.create(new AllStarComponent.ExportComponent("2", this, {
ExportComponent1Link1: this.__myState1,
ExportComponent1Link2: this.__myState2,
ExportComponent1Link3: this.__myState3,
@@ -140,7 +135,7 @@ class ImportTest extends View {
}
let earlierCreatedChild_3 = this.findChildById("3");
if (earlierCreatedChild_3 == undefined) {
View.create(new ExportStarComponent_1.AllStarComponent.default("3", this, {
View.create(new AllStarComponent.default("3", this, {
ExportComponent4Link1: this.__myState1,
ExportComponent4Link2: this.__myState2,
ExportComponent4Link3: this.__myState3,
+5 -10
View File
@@ -53,17 +53,12 @@ struct ImportTest {
`
exports.expectResult =
`"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ExportStarComponent_1 = require("./test/pages/ExportStarComponent");
const TsModule_1 = __importDefault(require("./test/pages/TsModule"));
`import { AllStarComponent } from './test/pages/ExportStarComponent';
import TsModule from './test/pages/TsModule';
class ImportTest extends View {
constructor(compilerAssignedUniqueChildId, parent, params) {
super(compilerAssignedUniqueChildId, parent);
this.__myState1 = new ObservedPropertyObject(new TsModule_1.default(1).method(), this, "myState1");
this.__myState1 = new ObservedPropertyObject(new TsModule(1).method(), this, "myState1");
this.__myState2 = new ObservedPropertySimple(0, this, "myState2");
this.__myState3 = new ObservedPropertySimple(false, this, "myState3");
this.__myState4 = new ObservedPropertySimple('ImportTest', this, "myState4");
@@ -118,7 +113,7 @@ class ImportTest extends View {
Column.create();
let earlierCreatedChild_2 = this.findChildById("2");
if (earlierCreatedChild_2 == undefined) {
View.create(new ExportStarComponent_1.AllStarComponent.ExportComponent("2", this, {
View.create(new AllStarComponent.ExportComponent("2", this, {
ExportComponent1Link1: this.__myState1,
ExportComponent1Link2: this.__myState2,
ExportComponent1Link3: this.__myState3,
@@ -140,7 +135,7 @@ class ImportTest extends View {
}
let earlierCreatedChild_3 = this.findChildById("3");
if (earlierCreatedChild_3 == undefined) {
View.create(new ExportStarComponent_1.AllStarComponent.default("3", this, {
View.create(new AllStarComponent.default("3", this, {
ExportComponent4Link1: this.__myState1,
ExportComponent4Link2: this.__myState2,
ExportComponent4Link3: this.__myState3,
@@ -52,10 +52,8 @@ struct MyComponent {
`
exports.expectResult =
`"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const TestComponent_1 = require("./test/pages/TestComponent");
const TsModule_1 = require("./test/pages/TsModule");
`import { TestComponent } from './test/pages/TestComponent';
import { Animal } from './test/pages/TsModule';
class MyComponent extends View {
constructor(compilerAssignedUniqueChildId, parent, params) {
super(compilerAssignedUniqueChildId, parent);
@@ -110,11 +108,11 @@ class MyComponent extends View {
}
If.pop();
If.create();
if (TsModule_1.Animal.Dog) {
if (Animal.Dog) {
If.branchId(0);
let earlierCreatedChild_2 = this.findChildById("2");
if (earlierCreatedChild_2 == undefined) {
View.create(new TestComponent_1.TestComponent("2", this, { content: 'if (import enum)' }));
View.create(new TestComponent("2", this, { content: 'if (import enum)' }));
}
else {
earlierCreatedChild_2.updateWithValueParams({
@@ -14,6 +14,7 @@
*/
exports.source = `
import { CustomContainerExport } from './test/pages/TestComponent';
@Component
struct CustomContainer {
header: string = "";
@@ -60,6 +61,15 @@ struct CustomContainerUser {
build() {
Column() {
CustomContainerExport({
header: this.text,
}){
Column(){
specificParam("111", "22")
}.onClick(()=>{
this.text = "changeHeader"
})
}
Row(){
CustomContainer({
header: this.text,
@@ -84,7 +94,10 @@ struct CustomContainerUser {
}
`
exports.expectResult =
`class CustomContainer extends View {
`"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const TestComponent_1 = require("./test/pages/TestComponent");
class CustomContainer extends View {
constructor(compilerAssignedUniqueChildId, parent, params) {
super(compilerAssignedUniqueChildId, parent);
this.header = "";
@@ -178,10 +191,38 @@ class CustomContainerUser extends View {
}
render() {
Column.create();
Row.create();
let earlierCreatedChild_2 = this.findChildById("2");
if (earlierCreatedChild_2 == undefined) {
View.create(new CustomContainer("2", this, {
View.create(new TestComponent_1.CustomContainerExport("2", this, {
header: this.text,
closer: () => {
Column.create();
Column.onClick(() => {
this.text = "changeHeader";
});
specificParam("111", "22");
Column.pop();
}
}));
}
else {
earlierCreatedChild_2.updateWithValueParams({
header: this.text,
closer: () => {
Column.create();
Column.onClick(() => {
this.text = "changeHeader";
});
specificParam("111", "22");
Column.pop();
}
});
View.create(earlierCreatedChild_2);
}
Row.create();
let earlierCreatedChild_3 = this.findChildById("3");
if (earlierCreatedChild_3 == undefined) {
View.create(new CustomContainer("3", this, {
header: this.text,
content: this.specificParam,
callContent: this.callSpecificParam("callContent1", 'callContent2'),
@@ -189,19 +230,19 @@ class CustomContainerUser extends View {
}));
}
else {
earlierCreatedChild_2.updateWithValueParams({
earlierCreatedChild_3.updateWithValueParams({
header: this.text,
content: this.specificParam,
callContent: this.callSpecificParam("callContent1", 'callContent2'),
footer: "Footer"
});
View.create(earlierCreatedChild_2);
View.create(earlierCreatedChild_3);
}
Row.pop();
Row.create();
let earlierCreatedChild_3 = this.findChildById("3");
if (earlierCreatedChild_3 == undefined) {
View.create(new CustomContainer2("3", this, {
let earlierCreatedChild_4 = this.findChildById("4");
if (earlierCreatedChild_4 == undefined) {
View.create(new CustomContainer2("4", this, {
header: this.text,
content: () => {
Column.create();
@@ -214,7 +255,7 @@ class CustomContainerUser extends View {
}));
}
else {
earlierCreatedChild_3.updateWithValueParams({
earlierCreatedChild_4.updateWithValueParams({
header: this.text,
content: () => {
Column.create();
@@ -225,7 +266,7 @@ class CustomContainerUser extends View {
Column.pop();
}
});
View.create(earlierCreatedChild_3);
View.create(earlierCreatedChild_4);
}
Row.pop();
Column.pop();
@@ -55,10 +55,7 @@ export struct FancyUseExp {
`
exports.expectResult =
`"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FancyUseExp = void 0;
class FancyUseExp extends View {
`export class FancyUseExp extends View {
constructor(compilerAssignedUniqueChildId, parent, params) {
super(compilerAssignedUniqueChildId, parent);
this.__enable = new ObservedPropertySimple(true, this, "enable");
@@ -109,6 +106,5 @@ class FancyUseExp extends View {
Column.pop();
}
}
exports.FancyUseExp = FancyUseExp;
loadDocument(new FancyUseExp("1", undefined, {}));
`
+571
View File
@@ -0,0 +1,571 @@
{
"compileOnSave": false,
"compilerOptions": {
"ets": {
"render": {
"method": ["build", "pageTransition"],
"decorator": "Builder"
},
"components": [
"AbilityComponent",
"AlphabetIndexer",
"Animator",
"Badge",
"Blank",
"Button",
"Calendar",
"Camera",
"Canvas",
"Checkbox",
"CheckboxGroup",
"Circle",
"ColorPicker",
"ColorPickerDialog",
"Column",
"ColumnSplit",
"Counter",
"DataPanel",
"DatePicker",
"Divider",
"Ellipse",
"Flex",
"FormComponent",
"Gauge",
"GeometryView",
"Grid",
"GridItem",
"GridContainer",
"Hyperlink",
"Image",
"ImageAnimator",
"Line",
"List",
"ListItem",
"LoadingProgress",
"Marquee",
"Menu",
"Navigation",
"Navigator",
"Option",
"PageTransitionEnter",
"PageTransitionExit",
"Panel",
"Path",
"PatternLock",
"Piece",
"PluginComponent",
"Polygon",
"Polyline",
"Progress",
"QRCode",
"Radio",
"Rating",
"Rect",
"Refresh",
"RelativeContainer",
"RemoteWindow",
"Row",
"RowSplit",
"RichText",
"Scroll",
"ScrollBar",
"Search",
"Section",
"Select",
"Shape",
"Sheet",
"SideBarContainer",
"Slider",
"Span",
"Stack",
"Stepper",
"StepperItem",
"Swiper",
"TabContent",
"Tabs",
"Text",
"TextPicker",
"TextClock",
"TextArea",
"TextInput",
"TextTimer",
"TimePicker",
"Toggle",
"Video",
"Web",
"XComponent"
],
"extend": {
"decorator": "Extend",
"components": [
{
"name": "AbilityComponent",
"type": "AbilityComponentAttribute",
"instance": "AbilityComponentInstance"
},
{
"name": "AlphabetIndexer",
"type": "AlphabetIndexerAttribute",
"instance": "AlphabetIndexerInstance"
},
{
"name": "Animator",
"type": "AnimatorAttribute",
"instance": "AnimatorInstance"
},
{
"name": "Badge",
"type": "BadgeAttribute",
"instance": "BadgeInstance"
},
{
"name": "Blank",
"type": "BlankAttribute",
"instance": "BlankInstance"
},
{
"name": "Button",
"type": "ButtonAttribute",
"instance": "ButtonInstance"
},
{
"name": "Calendar",
"type": "CalendarAttribute",
"instance": "CalendarInstance"
},
{
"name": "Camera",
"type": "CameraAttribute",
"instance": "CameraInstance"
},
{
"name": "Canvas",
"type": "CanvasAttribute",
"instance": "CanvasInstance"
},
{
"name": "Checkbox",
"type": "CheckboxAttribute",
"instance": "CheckboxInstance"
},
{
"name": "CheckboxGroup",
"type": "CheckboxGroupAttribute",
"instance": "CheckboxGroupInstance"
},
{
"name": "Circle",
"type": "CircleAttribute",
"instance": "CircleInstance"
},
{
"name": "ColorPicker",
"type": "ColorPickerAttribute",
"instance": "ColorPickerInstance"
},
{
"name": "ColorPickerDialog",
"type": "ColorPickerDialogAttribute",
"instance": "ColorPickerDialogInstance"
},
{
"name": "Column",
"type": "ColumnAttribute",
"instance": "ColumnInstance"
},
{
"name": "ColumnSplit",
"type": "ColumnSplitAttribute",
"instance": "ColumnSplitInstance"
},
{
"name": "Counter",
"type": "CounterAttribute",
"instance": "CounterInstance"
},
{
"name": "DataPanel",
"type": "DataPanelAttribute",
"instance": "DataPanelInstance"
},
{
"name": "DatePicker",
"type": "DatePickerAttribute",
"instance": "DatePickerInstance"
},
{
"name": "Divider",
"type": "DividerAttribute",
"instance": "DividerInstance"
},
{
"name": "Ellipse",
"type": "EllipseAttribute",
"instance": "EllipseInstance"
},
{
"name": "Flex",
"type": "FlexAttribute",
"instance": "FlexInstance"
},
{
"name": "FormComponent",
"type": "FormComponentAttribute",
"instance": "FormComponentInstance"
},
{
"name": "Gauge",
"type": "GaugeAttribute",
"instance": "GaugeInstance"
},
{
"name": "GeometryView",
"type": "GeometryViewAttribute",
"instance": "GeometryViewInstance"
},
{
"name": "Grid",
"type": "GridAttribute",
"instance": "GridInstance"
},
{
"name": "GridItem",
"type": "GridItemAttribute",
"instance": "GridItemInstance"
},
{
"name": "GridContainer",
"type": "GridContainerAttribute",
"instance": "GridContainerInstance"
},
{
"name": "Hyperlink",
"type": "HyperlinkAttribute",
"instance": "HyperlinkInstance"
},
{
"name": "Image",
"type": "ImageAttribute",
"instance": "ImageInstance"
},
{
"name": "ImageAnimator",
"type": "ImageAnimatorAttribute",
"instance": "ImageAnimatorInstance"
},
{
"name": "Line",
"type": "LineAttribute",
"instance": "LineInstance"
},
{
"name": "List",
"type": "ListAttribute",
"instance": "ListInstance"
},
{
"name": "ListItem",
"type": "ListItemAttribute",
"instance": "ListItemInstance"
},
{
"name": "LoadingProgress",
"type": "LoadingProgressAttribute",
"instance": "LoadingProgressInstance"
},
{
"name": "Marquee",
"type": "MarqueeAttribute",
"instance": "MarqueeInstance"
},
{
"name": "Menu",
"type": "MenuAttribute",
"instance": "MenuInstance"
},
{
"name": "Navigation",
"type": "NavigationAttribute",
"instance": "NavigationInstance"
},
{
"name": "Navigator",
"type": "NavigatorAttribute",
"instance": "NavigatorInstance"
},
{
"name": "Option",
"type": "OptionAttribute",
"instance": "OptionInstance"
},
{
"name": "PageTransitionEnter",
"type": "PageTransitionEnterAttribute",
"instance": "PageTransitionEnterInstance"
},
{
"name": "PageTransitionExit",
"type": "PageTransitionExitAttribute",
"instance": "PageTransitionExitInstance"
},
{
"name": "Panel",
"type": "PanelAttribute",
"instance": "PanelInstance"
},
{
"name": "Path",
"type": "PathAttribute",
"instance": "PathInstance"
},
{
"name": "PatternLock",
"type": "PatternLockAttribute",
"instance": "PatternLockInstance"
},
{
"name": "Piece",
"type": "PieceAttribute",
"instance": "PieceInstance"
},
{
"name": "PluginComponent",
"type": "PluginComponentAttribute",
"instance": "PluginComponentInstance"
},
{
"name": "Polygon",
"type": "PolygonAttribute",
"instance": "PolygonInstance"
},
{
"name": "Polyline",
"type": "PolylineAttribute",
"instance": "PolylineInstance"
},
{
"name": "Progress",
"type": "ProgressAttribute",
"instance": "ProgressInstance"
},
{
"name": "QRCode",
"type": "QRCodeAttribute",
"instance": "QRCodeInstance"
},
{
"name": "Radio",
"type": "RadioAttribute",
"instance": "RadioInstance"
},
{
"name": "Rating",
"type": "RatingAttribute",
"instance": "RatingInstance"
},
{
"name": "Rect",
"type": "RectAttribute",
"instance": "RectInstance"
},
{
"name": "RelativeContainer",
"type": "RelativeContainerAttribute",
"instance": "RelativeContainerInstance"
},
{
"name": "Refresh",
"type": "RefreshAttribute",
"instance": "RefreshInstance"
},
{
"name": "RemoteWindow",
"type": "RemoteWindowAttribute",
"instance": "RemoteWindowInstance"
},
{
"name": "Row",
"type": "RowAttribute",
"instance": "RowInstance"
},
{
"name": "RowSplit",
"type": "RowSplitAttribute",
"instance": "RowSplitInstance"
},
{
"name": "RichText",
"type": "RichTextAttribute",
"instance": "RichTextInstance"
},
{
"name": "Scroll",
"type": "ScrollAttribute",
"instance": "ScrollInstance"
},
{
"name": "ScrollBar",
"type": "ScrollBarAttribute",
"instance": "ScrollBarInstance"
},
{
"name": "Search",
"type": "SearchAttribute",
"instance": "SearchInstance"
},
{
"name": "Section",
"type": "SectionAttribute",
"instance": "SectionInstance"
},
{
"name": "Select",
"type": "SelectAttribute",
"instance": "SelectInstance"
},
{
"name": "Shape",
"type": "ShapeAttribute",
"instance": "ShapeInstance"
},
{
"name": "Sheet",
"type": "SheetAttribute",
"instance": "SheetInstance"
},
{
"name": "SideBarContainer",
"type": "SideBarContainerAttribute",
"instance": "SideBarContainerInstance"
},
{
"name": "Slider",
"type": "SliderAttribute",
"instance": "SliderInstance"
},
{
"name": "Span",
"type": "SpanAttribute",
"instance": "SpanInstance"
},
{
"name": "Stack",
"type": "StackAttribute",
"instance": "StackInstance"
},
{
"name": "Stepper",
"type": "StepperAttribute",
"instance": "StepperInstance"
},
{
"name": "StepperItem",
"type": "StepperItemAttribute",
"instance": "StepperItemInstance"
},
{
"name": "Swiper",
"type": "SwiperAttribute",
"instance": "SwiperInstance"
},
{
"name": "TabContent",
"type": "TabContentAttribute",
"instance": "TabContentInstance"
},
{
"name": "Tabs",
"type": "TabsAttribute",
"instance": "TabsInstance"
},
{
"name": "Text",
"type": "TextAttribute",
"instance": "TextInstance"
},
{
"name": "TextPicker",
"type": "TextPickerAttribute",
"instance": "TextPickerInstance"
},
{
"name": "TextClock",
"type": "TextClockAttribute",
"instance": "TextClockInstance"
},
{
"name": "TextArea",
"type": "TextAreaAttribute",
"instance": "TextAreaInstance"
},
{
"name": "TextInput",
"type": "TextInputAttribute",
"instance": "TextInputInstance"
},
{
"name": "TextTimer",
"type": "TextTimerAttribute",
"instance": "TextTimerInstance"
},
{
"name": "TimePicker",
"type": "TimePickerAttribute",
"instance": "TimePickerInstance"
},
{
"name": "Toggle",
"type": "ToggleAttribute",
"instance": "ToggleInstance"
},
{
"name": "Video",
"type": "VideoAttribute",
"instance": "VideoInstance"
},
{
"name": "Web",
"type": "WebAttribute",
"instance": "WebInstance"
},
{
"name": "XComponent",
"type": "XComponentAttribute",
"instance": "XComponentInstance"
},
]
},
"styles": {
"decorator": "Styles",
"component": {
"name": "Common",
"type": "T",
"instance": "CommonInstance"
},
"property": "stateStyles"
},
},
"allowJs": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"importsNotUsedAsValues": "preserve",
"noImplicitAny": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"experimentalDecorators": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"module": "commonjs",
"target": "es2017",
"types": [],
"typeRoots": [],
"lib": [
"es2020"
]
},
"exclude": [
"node_modules"
]
}
+7 -1
View File
@@ -62,6 +62,7 @@
"Rating",
"Rect",
"Refresh",
"RelativeContainer",
"RemoteWindow",
"Row",
"RowSplit",
@@ -367,6 +368,11 @@
"type": "RectAttribute",
"instance": "RectInstance"
},
{
"name": "RelativeContainer",
"type": "RelativeContainerAttribute",
"instance": "RelativeContainerInstance"
},
{
"name": "Refresh",
"type": "RefreshAttribute",
@@ -551,7 +557,7 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"module": "commonjs",
"module": "es2020",
"target": "es2017",
"types": [],
"typeRoots": [],
+33 -4
View File
@@ -18,6 +18,7 @@ const fs = require('fs');
const CopyPlugin = require('copy-webpack-plugin');
const Webpack = require('webpack');
const { GenAbcPlugin } = require('./lib/gen_abc_plugin');
const { OHMResolverPlugin } = require('./lib/resolve_ohm_url');
const buildPipeServer = require('./server/build_pipe_server');
const {
@@ -27,13 +28,14 @@ const {
resources,
loadWorker,
abilityConfig,
readWorkerFile
readWorkerFile,
loadModuleInfo
} = require('./main');
const { ResultStates } = require('./lib/compile_info');
const { processUISyntax } = require('./lib/process_ui_syntax');
const { IGNORE_ERROR_CODE } = require('./lib/utils');
const { BUILD_SHARE_PATH } = require('./lib/pre_define');
const { processJs } = require('./lib/process_js_ast');
process.env.watchMode = (process.env.watchMode && process.env.watchMode === 'true') || 'false';
function initConfig(config) {
@@ -77,10 +79,16 @@ function initConfig(config) {
transpileOnly: true,
configFile: path.resolve(__dirname, 'tsconfig.json'),
getCustomTransformers(program) {
return {
let transformerOperation = {
before: [processUISyntax(program)],
after: []
};
if (projectConfig.compileMode === 'esmodule' && projectConfig.processTs === false
&& process.env.compilerType && process.env.compilerType === 'ark') {
transformerOperation.after.push(processJs(program));
}
return transformerOperation;
},
ignoreDiagnostics: IGNORE_ERROR_CODE
}
@@ -91,6 +99,7 @@ function initConfig(config) {
{
test: /\.js$/,
use: [
{ loader: path.resolve(__dirname, 'lib/process_js_file.js')},
{ loader: path.resolve(__dirname, 'lib/process_system_module.js') }
]
}
@@ -100,6 +109,7 @@ function initConfig(config) {
global: false
},
resolve: {
plugins: [new OHMResolverPlugin()],
extensions: ['.js', '.ets', '.ts', '.d.ts'],
modules: [
projectPath,
@@ -285,17 +295,36 @@ function setOptimizationConfig(config, workerFile) {
}
}
function setTsConfigFile() {
let tsconfigTemplate =
path.resolve(__dirname, projectConfig.compileMode === 'esmodule' ? 'tsconfig.esm.json' : 'tsconfig.cjs.json');
if (fs.existsSync(tsconfigTemplate) && fs.statSync(tsconfigTemplate).isFile()) {
let currentTsconfigFile = path.resolve(__dirname, 'tsconfig.json');
let tsconfigTemplateNew =
currentTsconfigFile.replace(/.json$/, projectConfig.compileMode === 'esmodule' ? '.cjs.json' : '.esm.json');
fs.renameSync(currentTsconfigFile, tsconfigTemplateNew);
let tsconfigFileNew =
tsconfigTemplate.replace(projectConfig.compileMode === 'esmodule' ? /.esm.json$/ : /.cjs.json$/, '.json');
fs.renameSync(tsconfigTemplate, tsconfigFileNew);
}
}
module.exports = (env, argv) => {
const config = {};
setProjectConfig(env);
loadEntryObj(projectConfig);
loadModuleInfo(projectConfig, env);
setTsConfigFile();
initConfig(config);
const workerFile = readWorkerFile();
setOptimizationConfig(config, workerFile);
setCopyPluginConfig(config);
if (env.isPreview !== "true") {
loadWorker(projectConfig, workerFile);
if (env.compilerType && env.compilerType === 'ark') {
process.env.compilerType = 'ark';
let arkDir = path.join(__dirname, 'bin', 'ark');
if (env.arkFrontendDir) {
arkDir = env.arkFrontendDir;
@@ -342,4 +371,4 @@ module.exports = (env, argv) => {
}
config.output.library = projectConfig.hashProjectPath;
return config;
}
}