mirror of
https://github.com/openharmony/developtools_ace-ets2bundle.git
synced 2026-07-18 16:04:32 -04:00
optimize ets-loader. Signed-off-by: lihong <lihong67@huawei.com> Change-Id: I9392d2044df4ae051d11b50aa410c8d542c103f0
This commit is contained in:
@@ -143,8 +143,18 @@ ets_loader_sources = [
|
||||
"compiler/webpack.config.js",
|
||||
]
|
||||
|
||||
ohos_copy("copy_deps") {
|
||||
sources =
|
||||
[ "//third_party/typescript/build_package/ohos-typescript-4.2.3-r2.tgz" ]
|
||||
outputs = [ target_out_dir + "/ets_loader/deps/{{source_file_part}}" ]
|
||||
license_file = "//third_party/typescript/LICENSE"
|
||||
}
|
||||
|
||||
ohos_copy("ets_loader") {
|
||||
deps = [ ":build_ets_loader_library" ]
|
||||
deps = [
|
||||
":build_ets_loader_library",
|
||||
":copy_deps",
|
||||
]
|
||||
sources = ets_loader_sources
|
||||
deps += [ ":build_ets_sysResource" ]
|
||||
sources += [ ets_sysResource ]
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
module.exports = function(api) {
|
||||
api.cache(true);
|
||||
|
||||
const presets = ['@babel/preset-env', '@babel/typescript'];
|
||||
const presets = ['@babel/typescript'];
|
||||
const plugins = [
|
||||
'@babel/plugin-transform-modules-commonjs',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
|
||||
@@ -61,8 +61,6 @@ function generateTargetFile(filePath, output) {
|
||||
const fileName = path.resolve(output, path.basename(item));
|
||||
if (item === globalTsFile) {
|
||||
content = license + '\n\n' + processsFile(content, fileName, true);
|
||||
} else if (path.resolve(item) !== middleTsFile) {
|
||||
content = license + '\n\n' + processsFile(content, fileName, false);
|
||||
}
|
||||
fs.writeFile(fileName, content, err => {
|
||||
if (err) {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
../../../../third_party/typescript/build_package/ohos-typescript-4.2.3-r2.tgz
|
||||
Generated
+2
-3
@@ -4073,9 +4073,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmmirror.com/typescript/download/typescript-4.5.4.tgz",
|
||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
|
||||
"version": "file:deps/ohos-typescript-4.2.3-r2.tgz",
|
||||
"integrity": "sha512-a94p5mnxZMe9sJebu6gw2ixGaVGuKo7H3fU+Vd+VrogYbRrrCphlrJ2nlZnpm9r0TYe4HwHrmGkeyeJW63XUSA=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.14.5",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"log4js": "^6.3.0",
|
||||
"md5": "^2.3.0",
|
||||
"ts-loader": "^8.0.12",
|
||||
"typescript": "^4.1.3",
|
||||
"typescript": "file:./deps/ohos-typescript-4.2.3-r2.tgz",
|
||||
"webpack": "^5.48.0",
|
||||
"webpack-cli": "^4.2.0",
|
||||
"ws": "^8.3.0"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import Stats from 'webpack/lib/Stats';
|
||||
import Compiler from 'webpack/lib/Compiler';
|
||||
import Compilation from 'webpack/lib/Compilation';
|
||||
@@ -27,23 +28,18 @@ import fs from 'fs';
|
||||
import CachedSource from 'webpack-sources/lib/CachedSource';
|
||||
import ConcatSource from 'webpack-sources/lib/ConcatSource';
|
||||
|
||||
import {
|
||||
BUILDIN_STYLE_NAMES,
|
||||
EXTEND_ATTRIBUTE,
|
||||
STYLES_ATTRIBUTE
|
||||
} from './component_map';
|
||||
import { transformLog } from './process_ui_syntax';
|
||||
import {
|
||||
dollarCollection,
|
||||
componentCollection,
|
||||
moduleCollection
|
||||
} from './validate_ui_syntax';
|
||||
import { decoratorParamSet } from './process_component_member';
|
||||
import { appComponentCollection } from './process_component_build';
|
||||
import { moduleCollection } from './validate_ui_syntax';
|
||||
import { projectConfig } from '../main';
|
||||
import { circularFile } from './utils';
|
||||
import { MODULE_SHARE_PATH, BUILD_SHARE_PATH } from './pre_define';
|
||||
import { COMMON_ATTRS } from './component_map';
|
||||
import {
|
||||
createLanguageService,
|
||||
dollarCollection,
|
||||
appComponentCollection,
|
||||
decoratorParamsCollection,
|
||||
extendCollection
|
||||
} from './ets_checker';
|
||||
|
||||
configure({
|
||||
appenders: { 'ETS': {type: 'stderr', layout: {type: 'messagePassThrough'}}},
|
||||
@@ -78,7 +74,7 @@ export class ResultStates {
|
||||
compiler.hooks.compilation.tap('SourcemapFixer', compilation => {
|
||||
compilation.hooks.afterProcessAssets.tap('SourcemapFixer', assets => {
|
||||
Reflect.ownKeys(assets).forEach(key => {
|
||||
if (/\.map$/.test(key.toString())) {
|
||||
if (/\.map$/.test(key.toString()) && assets[key]._value) {
|
||||
assets[key]._value = assets[key]._value.toString().replace('.ets?entry', '.ets');
|
||||
}
|
||||
});
|
||||
@@ -146,17 +142,45 @@ export class ResultStates {
|
||||
});
|
||||
});
|
||||
|
||||
compiler.hooks.run.tapPromise('CheckSyntax', async(compiler) => {
|
||||
const rootFileNames: string[] = [];
|
||||
Object.values(projectConfig.entryObj).forEach((fileName: string) => {
|
||||
rootFileNames.push(fileName.replace('?entry', ''));
|
||||
});
|
||||
const languageService: ts.LanguageService = createLanguageService(rootFileNames);
|
||||
const rootProgram: ts.Program = languageService.getProgram();
|
||||
props.push(...dollarCollection, ...decoratorParamsCollection, ...extendCollection);
|
||||
let allDiagnostics: ts.Diagnostic[] = rootProgram
|
||||
.getSyntacticDiagnostics()
|
||||
.concat(rootProgram.getSemanticDiagnostics())
|
||||
.concat(rootProgram.getDeclarationDiagnostics());
|
||||
allDiagnostics = allDiagnostics.filter((item) => {
|
||||
return this.validateError(ts.flattenDiagnosticMessageText(item.messageText, '\n'));
|
||||
});
|
||||
this.mErrorCount += allDiagnostics.length;
|
||||
allDiagnostics.forEach((diagnostic: ts.Diagnostic) => {
|
||||
const message: string = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||||
if (diagnostic.file) {
|
||||
const { line, character }: ts.LineAndCharacter =
|
||||
diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
|
||||
logger.error(this.red,
|
||||
`ETS:ERROR File: ${diagnostic.file.fileName}:${line + 1}:${character + 1}\n ${message}\n`);
|
||||
} else {
|
||||
logger.error(this.red, `ETS:ERROR: ${message}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
compiler.hooks.done.tap('Result States', (stats: Stats) => {
|
||||
this.mStats = stats;
|
||||
this.warningCount = 0;
|
||||
this.noteCount = 0;
|
||||
if (this.mStats.compilation.errors) {
|
||||
this.mErrorCount = this.mStats.compilation.errors.length;
|
||||
this.mErrorCount += this.mStats.compilation.errors.length;
|
||||
}
|
||||
if (this.mStats.compilation.warnings) {
|
||||
this.mWarningCount = this.mStats.compilation.warnings.length;
|
||||
}
|
||||
props.push(...dollarCollection, ...decoratorParamSet, ...BUILDIN_STYLE_NAMES);
|
||||
this.printResult();
|
||||
});
|
||||
|
||||
@@ -261,41 +285,25 @@ export class ResultStates {
|
||||
}
|
||||
private validateError(message: string): boolean {
|
||||
const propInfoReg: RegExp = /Cannot find name\s*'(\$?\$?[_a-zA-Z0-9]+)'/;
|
||||
const componentNameReg: RegExp = /'typeof\s*(\$?[_a-zA-Z0-9]+)' is not callable/;
|
||||
const stateInfoReg: RegExp = /Property\s*'(\$[_a-zA-Z0-9]+)' does not exist on type/;
|
||||
const extendInfoReg: RegExp =
|
||||
/Property\s*'([_a-zA-Z0-9]+)' does not exist on type\s*'([_a-zA-Z0-9]+)(Attribute|Interface)'\./;
|
||||
if (this.matchMessage(message, props.concat([...STYLES_ATTRIBUTE]), propInfoReg) ||
|
||||
this.matchMessage(message, [...componentCollection.customComponents], componentNameReg) ||
|
||||
this.matchMessage(message, props, stateInfoReg) ||
|
||||
this.matchMessage(message, EXTEND_ATTRIBUTE, extendInfoReg, true) ||
|
||||
this.matchMessage(message, [...STYLES_ATTRIBUTE, ...COMMON_ATTRS], extendInfoReg)) {
|
||||
const stateInfoReg: RegExp = /Property\s*'(\$?[_a-zA-Z0-9]+)' does not exist on type/;
|
||||
if (this.matchMessage(message, props, propInfoReg) ||
|
||||
this.matchMessage(message, props, stateInfoReg)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private matchMessage(message: string, nameArr: any, reg: RegExp,
|
||||
validateComponent: boolean = false): boolean {
|
||||
private matchMessage(message: string, nameArr: any, reg: RegExp): boolean {
|
||||
if (reg.test(message)) {
|
||||
const match: string[] = message.match(reg);
|
||||
if (validateComponent) {
|
||||
if (match[1] && match[2] && nameArr.has(match[2])) {
|
||||
const attributeArray: string[] = [...nameArr.get(match[2])].map(item => item.attribute);
|
||||
if (attributeArray.includes(match[1])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (match[1] && nameArr.includes(match[1])) {
|
||||
return true;
|
||||
}
|
||||
if (match[1] && nameArr.includes(match[1])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private filterModuleError(message: string): string {
|
||||
if (/You may need an additional loader/.test(message) && transformLog && transformLog.sourceFile) {
|
||||
const fileName: string = transformLog.sourceFile.fileName.replace(/.ts$/, '');
|
||||
const fileName: string = transformLog.sourceFile.fileName;
|
||||
const errorInfos: string[] = message.split('You may need an additional loader to handle the result of these loaders.');
|
||||
if (errorInfos && errorInfos.length > 1 && errorInfos[1]) {
|
||||
message = `ERROR in ${fileName}\n The following syntax is incorrect.${errorInfos[1]}`;
|
||||
|
||||
@@ -75,13 +75,13 @@ export interface ExtendParamterInterfance {
|
||||
attribute: string,
|
||||
parameterCount: number
|
||||
}
|
||||
export const EXTEND_ATTRIBUTE: Map<string, Set<ExtendParamterInterfance>> = new Map();
|
||||
export const EXTEND_ATTRIBUTE: Map<string, Set<string>> = new Map();
|
||||
export const STYLES_ATTRIBUTE: Set<string> = new Set();
|
||||
|
||||
export const INTERFACE_NODE_SET: Set<ts.InterfaceDeclaration> = new Set();
|
||||
|
||||
export const JS_BIND_COMPONENTS: Set<string> = new Set([
|
||||
...GESTURE_TYPE_NAMES, 'Gesture',
|
||||
'ForEach', 'LazyForEach', ...GESTURE_TYPE_NAMES, 'Gesture',
|
||||
'PanGestureOption', 'CustomDialogController', 'Storage', 'Scroller', 'SwiperController',
|
||||
'TabsController', 'CalendarController', 'AbilityController', 'VideoController', 'WebController',
|
||||
'XComponentController', 'CanvasRenderingContext2D', 'CanvasGradient', 'ImageBitmap', 'ImageData',
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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 fs from 'fs';
|
||||
import path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import { projectConfig } from '../main';
|
||||
import {
|
||||
processSystemApi,
|
||||
preprocessExtend
|
||||
} from './validate_ui_syntax';
|
||||
import {
|
||||
INNER_COMPONENT_MEMBER_DECORATORS,
|
||||
COMPONENT_IF,
|
||||
COMPONENT_DECORATORS_PARAMS
|
||||
} from './pre_define';
|
||||
import { JS_BIND_COMPONENTS } from './component_map';
|
||||
|
||||
function readDeaclareFiles(): string[] {
|
||||
const declarationsFileNames: string[] = [];
|
||||
fs.readdirSync(path.resolve(__dirname, '../declarations'))
|
||||
.forEach((fileName: string) => {
|
||||
if (/\.d\.ts$/.test(fileName)) {
|
||||
declarationsFileNames.push(path.resolve(__dirname, '../declarations', fileName));
|
||||
}
|
||||
});
|
||||
return declarationsFileNames;
|
||||
}
|
||||
|
||||
export function createLanguageService(rootFileNames: string[]): ts.LanguageService {
|
||||
const compilerOptions: ts.CompilerOptions = ts.readConfigFile(
|
||||
path.resolve(__dirname, '../tsconfig.json'), ts.sys.readFile).config.compilerOptions;
|
||||
Object.assign(compilerOptions, {
|
||||
'moduleResolution': ts.ModuleResolutionKind.NodeJs,
|
||||
'target': ts.ScriptTarget.ES2017,
|
||||
'baseUrl': path.resolve(projectConfig.projectPath),
|
||||
'paths': {
|
||||
'*': [
|
||||
'*',
|
||||
'../../../../../*'
|
||||
]
|
||||
},
|
||||
'lib': [
|
||||
'lib.es2020.d.ts'
|
||||
]
|
||||
});
|
||||
const files: ts.MapLike<{ version: number }> = {};
|
||||
const servicesHost: ts.LanguageServiceHost = {
|
||||
getScriptFileNames: () => [...rootFileNames, ...readDeaclareFiles()],
|
||||
getScriptVersion: fileName =>
|
||||
files[fileName] && files[fileName].version.toString(),
|
||||
getScriptSnapshot: fileName => {
|
||||
if (!fs.existsSync(fileName)) {
|
||||
return undefined;
|
||||
}
|
||||
if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
|
||||
checkUISyntax(fs.readFileSync(fileName).toString(), fileName);
|
||||
return ts.ScriptSnapshot.fromString(processContent(fs.readFileSync(fileName).toString()));
|
||||
}
|
||||
return ts.ScriptSnapshot.fromString(fs.readFileSync(fileName).toString());
|
||||
},
|
||||
getCurrentDirectory: () => process.cwd(),
|
||||
getCompilationSettings: () => compilerOptions,
|
||||
getDefaultLibFileName: options => ts.getDefaultLibFilePath(options),
|
||||
fileExists: ts.sys.fileExists,
|
||||
readFile: ts.sys.readFile,
|
||||
readDirectory: ts.sys.readDirectory,
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] {
|
||||
const resolvedModules: ts.ResolvedModuleFull[] = [];
|
||||
for (const moduleName of moduleNames) {
|
||||
const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, {
|
||||
fileExists(fileName: string): boolean {
|
||||
return ts.sys.fileExists(fileName);
|
||||
},
|
||||
readFile(fileName: string): string | undefined {
|
||||
return ts.sys.readFile(fileName);
|
||||
}
|
||||
});
|
||||
if (result.resolvedModule) {
|
||||
resolvedModules.push(result.resolvedModule);
|
||||
} else if (/^@(system|ohos)/.test(moduleName.trim())) {
|
||||
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
|
||||
}
|
||||
} else if (/\.ets$/.test(moduleName)) {
|
||||
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.ets'));
|
||||
}
|
||||
} else if (/\.ts$/.test(moduleName)) {
|
||||
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.ts'));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (moduleNames.length !== resolvedModules.length) {
|
||||
const length: number = moduleNames.length - resolvedModules.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
}
|
||||
return resolvedModules;
|
||||
},
|
||||
directoryExists: ts.sys.directoryExists,
|
||||
getDirectories: ts.sys.getDirectories
|
||||
};
|
||||
return ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
|
||||
}
|
||||
|
||||
function getResolveModule(modulePath: string, type): ts.ResolvedModuleFull {
|
||||
return {
|
||||
resolvedFileName: modulePath,
|
||||
isExternalLibraryImport: false,
|
||||
extension: type
|
||||
};
|
||||
}
|
||||
|
||||
export const dollarCollection: Set<string> = new Set();
|
||||
export const appComponentCollection: Set<string> = new Set();
|
||||
export const decoratorParamsCollection: Set<string> = new Set();
|
||||
export const extendCollection: Set<string> = new Set();
|
||||
|
||||
function checkUISyntax(source: string, fileName: string): void {
|
||||
if (/\.ets$/.test(fileName)) {
|
||||
if (path.basename(fileName) !== 'app.ets') {
|
||||
const sourceFile: ts.SourceFile = ts.createSourceFile(fileName, source,
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
|
||||
collectComponents(sourceFile);
|
||||
parseAllNode(sourceFile, sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function collectComponents(node: ts.SourceFile): void {
|
||||
// @ts-ignore
|
||||
if (node.identifiers && node.identifiers.size) {
|
||||
// @ts-ignore
|
||||
for (const key of node.identifiers.keys()) {
|
||||
if (JS_BIND_COMPONENTS.has(key)) {
|
||||
appComponentCollection.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseAllNode(node: ts.Node, sourceFileNode: ts.SourceFile): void {
|
||||
if (ts.isStructDeclaration(node)) {
|
||||
if (node.members) {
|
||||
node.members.forEach(item => {
|
||||
if (ts.isPropertyDeclaration(item) && ts.isIdentifier(item.name)) {
|
||||
const propertyName: string = item.name.getText();
|
||||
if (item.decorators && item.decorators.length) {
|
||||
for (let i = 0; i < item.decorators.length; i++) {
|
||||
const decoratorName: string = item.decorators[i].getText().replace(/\(.*\)$/, '').trim();
|
||||
if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName)) {
|
||||
dollarCollection.add('$' + propertyName);
|
||||
}
|
||||
if (isDecoratorCollection(item.decorators[i], decoratorName)) {
|
||||
decoratorParamsCollection.add(item.decorators[i].expression.arguments[0].getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (ts.isIfStatement(node)) {
|
||||
appComponentCollection.add(COMPONENT_IF);
|
||||
}
|
||||
node.getChildren().forEach((item: ts.Node) => parseAllNode(item, sourceFileNode));
|
||||
}
|
||||
|
||||
function isDecoratorCollection(item: ts.Decorator, decoratorName: string): boolean {
|
||||
return COMPONENT_DECORATORS_PARAMS.has(decoratorName) &&
|
||||
// @ts-ignore
|
||||
item.expression.arguments && item.expression.arguments.length &&
|
||||
// @ts-ignore
|
||||
ts.isIdentifier(item.expression.arguments[0]);
|
||||
}
|
||||
|
||||
function processDraw(source: string): string {
|
||||
const reg: RegExp = /new\s+\b(Circle|Ellipse|Rect|Path)\b/g;
|
||||
return source.replace(reg, (item:string, item1: string) => {
|
||||
return '\xa0'.repeat(item.length - item1.length) + item1;
|
||||
});
|
||||
}
|
||||
|
||||
function processContent(source: string): string {
|
||||
source = processSystemApi(source);
|
||||
source = preprocessExtend(source, extendCollection);
|
||||
source = processDraw(source);
|
||||
return source;
|
||||
}
|
||||
@@ -38,6 +38,9 @@ export const COMPONENT_OBJECT_LINK_DECORATOR: string = '@ObjectLink';
|
||||
export const COMPONENT_WATCH_DECORATOR: string = '@Watch';
|
||||
export const COMPONENT_BUILDERPARAM_DECORATOR: string = '@BuilderParam';
|
||||
|
||||
export const COMPONENT_DECORATORS_PARAMS: Set<string> = new Set([COMPONENT_CONSUME_DECORATOR,
|
||||
COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_STORAGE_LINK_DECORATOR, COMPONENT_PROVIDE_DECORATOR,
|
||||
COMPONENT_WATCH_DECORATOR]);
|
||||
export const INNER_COMPONENT_DECORATORS: Set<string> = new Set([COMPONENT_DECORATOR_ENTRY,
|
||||
COMPONENT_DECORATOR_PREVIEW, COMPONENT_DECORATOR_COMPONENT, COMPONENT_DECORATOR_CUSTOM_DIALOG]);
|
||||
export const INNER_COMPONENT_MEMBER_DECORATORS: Set<string> = new Set([COMPONENT_STATE_DECORATOR,
|
||||
@@ -49,6 +52,7 @@ export const COMPONENT_OBSERVED_DECORATOR: string = '@Observed';
|
||||
export const COMPONENT_BUILDER_DECORATOR: string = '@Builder';
|
||||
export const COMPONENT_EXTEND_DECORATOR: string = '@Extend';
|
||||
export const COMPONENT_STYLES_DECORATOR: string = '@Styles';
|
||||
export const CHECK_COMPONENT_EXTEND_DECORATOR: string = 'Extend';
|
||||
|
||||
export const OBSERVED_PROPERTY_SIMPLE: string = 'ObservedPropertySimple';
|
||||
export const OBSERVED_PROPERTY_OBJECT: string = 'ObservedPropertyObject';
|
||||
@@ -202,3 +206,5 @@ export const OBSERVED_PROPERTY_ABSTRACT:string = 'ObservedPropertyAbstract';
|
||||
|
||||
export const SUPERVISUAL: string = './supervisual';
|
||||
export const SUPERVISUAL_SOURCEMAP_EXT: string = '.visual.js.map';
|
||||
|
||||
export const INSTANCE: string = 'Instance';
|
||||
|
||||
@@ -150,8 +150,8 @@ function insertImport(visualContent: any, content: string): string {
|
||||
|
||||
function insertVarAndFunc(build: ts.MethodDeclaration, visualContent: any,
|
||||
content: string, oriContent: string): string {
|
||||
const visualVarAndFunc: string = (visualContent.etsVariable ?? '') +
|
||||
(visualContent.etsFunction ?? '');
|
||||
const visualVarAndFunc: string = (visualContent.etsVariable ? visualContent.etsVariable : '') +
|
||||
(visualContent.etsFunction ? visualContent.etsFunction : '');
|
||||
return visualVarAndFunc ? insertVisualCodeBeforePos(build, '\n' + visualVarAndFunc, content,
|
||||
oriContent) : content;
|
||||
}
|
||||
|
||||
@@ -88,8 +88,6 @@ import { projectConfig } from '../main';
|
||||
import { transformLog, contextGlobal } from './process_ui_syntax';
|
||||
import { props } from './compile_info';
|
||||
|
||||
export const appComponentCollection: Set<string> = new Set();
|
||||
|
||||
export function processComponentBuild(node: ts.MethodDeclaration,
|
||||
log: LogInfo[]): ts.MethodDeclaration {
|
||||
let newNode: ts.MethodDeclaration;
|
||||
@@ -130,27 +128,15 @@ export function processComponentBlock(node: ts.Block, isLazy: boolean, log: LogI
|
||||
|
||||
function validateRootNode(node: ts.MethodDeclaration, log: LogInfo[]): boolean {
|
||||
let isValid: boolean = false;
|
||||
if (node.body.statements.length < 4) {
|
||||
switch (node.body.statements.length) {
|
||||
case 1:
|
||||
if (validateFirstNode(node.body.statements[0])) {
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (validateFirstNode(node.body.statements[0]) &&
|
||||
validateBlockNode(node.body.statements[1])) {
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (validateFirstNode(node.body.statements[0]) &&
|
||||
validateBlockNode(node.body.statements[1]) &&
|
||||
validateSecondNode(node.body.statements[2])) {
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
if (node.body.statements.length === 1) {
|
||||
const statement: ts.Node = node.body.statements[0];
|
||||
if (ts.isIfStatement(statement) || ts.isExpressionStatement(statement) && statement.expression &&
|
||||
(ts.isEtsComponentExpression(statement.expression) || ts.isCallExpression(statement.expression)) &&
|
||||
validateEtsComponentNode(statement.expression)) {
|
||||
isValid = true;
|
||||
}
|
||||
} else {
|
||||
isValid = false;
|
||||
}
|
||||
if (!isValid) {
|
||||
log.push({
|
||||
@@ -174,6 +160,19 @@ let newsupplement: supplementType = {
|
||||
column: 0
|
||||
};
|
||||
|
||||
function validateEtsComponentNode(node: ts.CallExpression | ts.EtsComponentExpression) {
|
||||
let childNode: ts.Node = node;
|
||||
while (ts.isCallExpression(childNode) && childNode.expression &&
|
||||
ts.isPropertyAccessExpression(childNode.expression) && childNode.expression.expression) {
|
||||
childNode = childNode.expression.expression;
|
||||
}
|
||||
if (ts.isEtsComponentExpression(childNode)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function processComponentChild(node: ts.Block | ts.SourceFile, newStatements: ts.Statement[],
|
||||
log: LogInfo[], supplement: supplementType = {isAcceleratePreview: false, line: 0, column: 0}): void {
|
||||
if (supplement.isAcceleratePreview) {
|
||||
@@ -189,9 +188,9 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
|
||||
newStatements, log, name);
|
||||
break;
|
||||
case ComponentType.customComponent:
|
||||
if (index + 1 < array.length && ts.isBlock(array[index + 1])) {
|
||||
if (processExpressionStatementChange(item, array[index + 1] as ts.Block, log)) {
|
||||
item = processExpressionStatementChange(item, array[index + 1] as ts.Block, log);
|
||||
if (item.expression && ts.isEtsComponentExpression(item.expression) && item.expression.body) {
|
||||
if (processExpressionStatementChange(item, item.expression.body, log)) {
|
||||
item = processExpressionStatementChange(item, item.expression.body, log);
|
||||
}
|
||||
}
|
||||
processCustomComponent(item as ts.ExpressionStatement, newStatements, log);
|
||||
@@ -205,7 +204,6 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
|
||||
break;
|
||||
}
|
||||
} else if (ts.isIfStatement(item)) {
|
||||
appComponentCollection.add(COMPONENT_IF);
|
||||
processIfStatement(item, newStatements, log);
|
||||
} else if (!ts.isBlock(item)) {
|
||||
log.push({
|
||||
@@ -262,6 +260,28 @@ function processBlockToExpression(node: ts.ExpressionStatement, nextNode: ts.Blo
|
||||
return node;
|
||||
}
|
||||
|
||||
type EtsComponentResult = {
|
||||
etsComponentNode: ts.EtsComponentExpression;
|
||||
hasAttr: boolean;
|
||||
}
|
||||
function parseEtsComponentExpression(node: ts.ExpressionStatement): EtsComponentResult {
|
||||
let etsComponentNode: ts.EtsComponentExpression;
|
||||
let hasAttr: boolean = false;
|
||||
let temp: any = node.expression;
|
||||
while (temp) {
|
||||
if (ts.isCallExpression(temp) && temp.expression &&
|
||||
ts.isPropertyAccessExpression(temp.expression)) {
|
||||
hasAttr = true;
|
||||
}
|
||||
if (ts.isEtsComponentExpression(temp)) {
|
||||
etsComponentNode = temp;
|
||||
break;
|
||||
}
|
||||
temp = temp.expression;
|
||||
}
|
||||
return { etsComponentNode: etsComponentNode, hasAttr: hasAttr };
|
||||
}
|
||||
|
||||
function processInnerComponent(node: ts.ExpressionStatement, index: number, arr: ts.Statement[],
|
||||
newStatements: ts.Statement[], log: LogInfo[], name: string): void {
|
||||
const res: CreateResult = createComponent(node, COMPONENT_CREATE_FUNCTION);
|
||||
@@ -293,7 +313,8 @@ function processInnerComponent(node: ts.ExpressionStatement, index: number, arr:
|
||||
ts.factory.createNodeArray([ts.factory.createStringLiteral(debugInfo)])));
|
||||
newStatements.push(debugNode);
|
||||
}
|
||||
if (index + 1 < arr.length && ts.isBlock(arr[index + 1])) {
|
||||
const etsComponentResult: EtsComponentResult = parseEtsComponentExpression(node);
|
||||
if (etsComponentResult.etsComponentNode.body && ts.isBlock(etsComponentResult.etsComponentNode.body)) {
|
||||
if (res.isButton) {
|
||||
if (projectConfig.isPreview) {
|
||||
newStatements.splice(-2, 1, createComponent(node, COMPONENT_CREATE_CHILD_FUNCTION).newNode);
|
||||
@@ -301,11 +322,10 @@ function processInnerComponent(node: ts.ExpressionStatement, index: number, arr:
|
||||
newStatements.splice(-1, 1, createComponent(node, COMPONENT_CREATE_CHILD_FUNCTION).newNode);
|
||||
}
|
||||
}
|
||||
if (index + 2 < arr.length && ts.isExpressionStatement(arr[index + 2]) &&
|
||||
isAttributeNode(arr[index + 2] as ts.ExpressionStatement)) {
|
||||
bindComponentAttr(arr[index + 2] as ts.ExpressionStatement, res.identifierNode, newStatements, log);
|
||||
if (etsComponentResult.hasAttr) {
|
||||
bindComponentAttr(node, res.identifierNode, newStatements, log);
|
||||
}
|
||||
processComponentChild(arr[index + 1] as ts.Block, newStatements, log);
|
||||
processComponentChild(etsComponentResult.etsComponentNode.body, newStatements, log);
|
||||
} else {
|
||||
bindComponentAttr(node, res.identifierNode, newStatements, log);
|
||||
}
|
||||
@@ -516,7 +536,8 @@ function createComponent(node: ts.ExpressionStatement, type: string): CreateResu
|
||||
while (temp && !ts.isIdentifier(temp) && temp.expression) {
|
||||
temp = temp.expression;
|
||||
}
|
||||
if (temp && temp.parent && ts.isCallExpression(temp.parent) && ts.isIdentifier(temp)) {
|
||||
if (temp && temp.parent && (ts.isCallExpression(temp.parent) ||
|
||||
ts.isEtsComponentExpression(temp.parent)) && ts.isIdentifier(temp)) {
|
||||
if (temp.getText() === COMPONENT_BUTTON && type !== COMPONENT_POP_FUNCTION) {
|
||||
res.isButton = true;
|
||||
identifierNode = type === COMPONENT_CREATE_CHILD_FUNCTION
|
||||
@@ -837,7 +858,6 @@ function addComponentAttr(temp: any, node: ts.Identifier, lastStatement: any,
|
||||
parseGesture(temp, propName, statements, log);
|
||||
lastStatement.kind = true;
|
||||
} else if (isExtendFunctionNode(identifierNode, propName)) {
|
||||
validateExtendParameterCount(temp, identifierNode, propName, log);
|
||||
statements.push(ts.factory.createExpressionStatement(ts.factory.createCallExpression(
|
||||
ts.factory.createIdentifier(`__${identifierNode.escapedText.toString()}__${propName}`),
|
||||
undefined, temp.arguments)));
|
||||
@@ -873,18 +893,36 @@ function addComponentAttr(temp: any, node: ts.Identifier, lastStatement: any,
|
||||
if (!COMMON_ATTRS.has(propName)) {
|
||||
validateStateStyleSyntax(temp, log);
|
||||
}
|
||||
if (isGlobalStyles) {
|
||||
for (let i = 0; i < temp.arguments.length; i++) {
|
||||
temp.arguments[i] = traverseStylesAttr(temp.arguments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
temp = loopEtsComponent(temp, isStylesAttr, isGlobalStyles);
|
||||
statements.push(ts.factory.createExpressionStatement(
|
||||
createFunction(identifierNode, node, temp.arguments)));
|
||||
lastStatement.kind = true;
|
||||
}
|
||||
}
|
||||
|
||||
function loopEtsComponent(temp: any, isStylesAttr: boolean, isGlobalStyles: boolean): ts.Node {
|
||||
temp.arguments.forEach((item: ts.Node, index: number) => {
|
||||
if (isStylesAttr && isGlobalStyles) {
|
||||
temp.arguments[index] = traverseStylesAttr(item);
|
||||
}
|
||||
if (ts.isNewExpression(item) && item.expression && ts.isEtsComponentExpression(
|
||||
item.expression)) {
|
||||
temp.arguments[index] = ts.factory.updateNewExpression(item, item.expression.expression,
|
||||
undefined, item.expression.arguments);
|
||||
} else if (ts.isEtsComponentExpression(item)) {
|
||||
temp.arguments[index] = ts.factory.createCallExpression(item.expression,
|
||||
undefined, item.arguments);
|
||||
} else if ((ts.isCallExpression(item) || ts.isNewExpression(item)) && item.expression &&
|
||||
ts.isPropertyAccessExpression(item.expression) && item.expression.expression &&
|
||||
ts.isEtsComponentExpression(item.expression.expression)) {
|
||||
temp.arguments[index].expression.expression = ts.factory.createCallExpression(
|
||||
item.expression.expression.expression, undefined, item.expression.expression.arguments);
|
||||
}
|
||||
});
|
||||
return temp;
|
||||
}
|
||||
|
||||
function classifyArgumentsNum(args: any, argumentsArr: ts.Expression[], propName: string,
|
||||
identifierNode: ts.Identifier): void {
|
||||
if (propName === BIND_POPUP && args.length === 2) {
|
||||
@@ -967,7 +1005,7 @@ function traverseStateStylesAttr(temp: any, statements: ts.Statement[],
|
||||
function isExtendFunctionNode(identifierNode: ts.Identifier, propName: string): boolean {
|
||||
if (identifierNode && EXTEND_ATTRIBUTE.has(identifierNode.escapedText.toString())) {
|
||||
const attributeArray: string[] =
|
||||
[...EXTEND_ATTRIBUTE.get(identifierNode.escapedText.toString())].map(item => item.attribute);
|
||||
[...EXTEND_ATTRIBUTE.get(identifierNode.escapedText.toString())];
|
||||
if (attributeArray.includes(propName)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1053,7 +1091,8 @@ export function getName(node: ts.ExpressionStatement): string {
|
||||
let temp: any = node.expression;
|
||||
let name: string;
|
||||
while (temp) {
|
||||
if (ts.isIdentifier(temp) && temp.parent && ts.isCallExpression(temp.parent)) {
|
||||
if (ts.isIdentifier(temp) && temp.parent && (ts.isCallExpression(temp.parent) ||
|
||||
ts.isEtsComponentExpression(temp.parent))) {
|
||||
name = temp.escapedText.toString();
|
||||
break;
|
||||
} else if (ts.isPropertyAccessExpression(temp) && temp.name && ts.isIdentifier(temp.name) &&
|
||||
@@ -1079,46 +1118,6 @@ export function isAttributeNode(node: ts.ExpressionStatement): boolean {
|
||||
return BUILDIN_STYLE_NAMES.has(name);
|
||||
}
|
||||
|
||||
function validateFirstNode(node: ts.Statement): boolean {
|
||||
const isEntryComponent: boolean =
|
||||
componentCollection.entryComponent === componentCollection.currentClassName;
|
||||
if (isEntryComponent && validateEntryComponent(node) ||
|
||||
!isEntryComponent && validateCustomComponent(node)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateEntryComponent(node: ts.Statement): boolean {
|
||||
if (ts.isExpressionStatement(node) && BUILDIN_CONTAINER_COMPONENT.has(getName(node))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateCustomComponent(node: ts.Statement): boolean {
|
||||
if (ts.isIfStatement(node) ||
|
||||
ts.isExpressionStatement(node) && (INNER_COMPONENT_NAMES.has(getName(node)) ||
|
||||
componentCollection.customComponents.has(getName(node)))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateBlockNode(node: ts.Statement): boolean {
|
||||
if (ts.isBlock(node)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateSecondNode(node: ts.Statement): boolean {
|
||||
if (ts.isExpressionStatement(node) && isAttributeNode(node)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
enum ComponentType {
|
||||
innerComponent,
|
||||
customComponent,
|
||||
@@ -1127,14 +1126,29 @@ enum ComponentType {
|
||||
builderParamMethod
|
||||
}
|
||||
|
||||
function isEtsComponent(node: ts.ExpressionStatement): boolean {
|
||||
let isEtsComponent: boolean = false;
|
||||
let temp: any = node.expression;
|
||||
while (temp) {
|
||||
if (ts.isEtsComponentExpression(temp)) {
|
||||
isEtsComponent = true;
|
||||
}
|
||||
temp = temp.expression;
|
||||
}
|
||||
return isEtsComponent;
|
||||
}
|
||||
|
||||
function getComponentType(node: ts.ExpressionStatement, log: LogInfo[],
|
||||
name: string): ComponentType {
|
||||
if (INNER_COMPONENT_NAMES.has(name)) {
|
||||
return ComponentType.innerComponent;
|
||||
if (isEtsComponent(node)) {
|
||||
if (componentCollection.customComponents.has(name)) {
|
||||
return ComponentType.customComponent;
|
||||
} else {
|
||||
return ComponentType.innerComponent;
|
||||
}
|
||||
} else if (componentCollection.customComponents.has(name)) {
|
||||
return ComponentType.customComponent;
|
||||
} else if (name === COMPONENT_FOREACH || name === COMPONENT_LAZYFOREACH) {
|
||||
appComponentCollection.add(name);
|
||||
return ComponentType.forEachComponent;
|
||||
} else if (CUSTOM_BUILDER_METHOD.has(name)) {
|
||||
return ComponentType.customBuilderMethod;
|
||||
@@ -1151,20 +1165,6 @@ function getComponentType(node: ts.ExpressionStatement, log: LogInfo[],
|
||||
return null;
|
||||
}
|
||||
|
||||
function validateExtendParameterCount(temp: any, identifierNode: ts.Identifier, propName: string,
|
||||
log: LogInfo[]): void {
|
||||
const parameterCount: number =
|
||||
[...EXTEND_ATTRIBUTE.get(identifierNode.escapedText.toString())].filter(item =>
|
||||
item.attribute === propName)[0].parameterCount;
|
||||
if (temp.arguments && temp.arguments.length !== parameterCount) {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: `The '${propName}' is expected ${parameterCount} arguments, but got ${temp.arguments.length}.`,
|
||||
pos: temp.getStart()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function validateStateStyleSyntax(temp: any, log: LogInfo[]): void {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
|
||||
@@ -31,8 +31,6 @@ import {
|
||||
OBSERVED_PROPERTY_SIMPLE,
|
||||
COMPONENT_BUILD_FUNCTION,
|
||||
BASE_COMPONENT_NAME,
|
||||
ATTRIBUTE_ANIMATETO,
|
||||
GLOBAL_CONTEXT,
|
||||
CREATE_CONSTRUCTOR_PARAMS,
|
||||
COMPONENT_CONSTRUCTOR_UPDATE_PARAMS,
|
||||
COMPONENT_CONSTRUCTOR_DELETE_PARAMS,
|
||||
@@ -86,12 +84,12 @@ import {
|
||||
hasDecorator
|
||||
} from './utils';
|
||||
|
||||
export function processComponentClass(node: ts.ClassDeclaration, context: ts.TransformationContext,
|
||||
export function processComponentClass(node: ts.StructDeclaration, context: ts.TransformationContext,
|
||||
log: LogInfo[], program: ts.Program): ts.ClassDeclaration {
|
||||
validateInheritClass(node, log);
|
||||
const memberNode: ts.ClassElement[] =
|
||||
processMembers(node.members, node.name, context, log, program, checkPreview(node));
|
||||
return ts.factory.updateClassDeclaration(node, undefined, node.modifiers, node.name,
|
||||
return ts.factory.createClassDeclaration(undefined, node.modifiers, node.name,
|
||||
node.typeParameters, updateHeritageClauses(node), memberNode);
|
||||
}
|
||||
|
||||
@@ -335,7 +333,7 @@ function getGeometryReaderFunctionBlock(node: ts.ArrowFunction | ts.FunctionExpr
|
||||
return processComponentBlock(blockNode, false, log);
|
||||
}
|
||||
|
||||
function updateHeritageClauses(node: ts.ClassDeclaration): ts.NodeArray<ts.HeritageClause> {
|
||||
function updateHeritageClauses(node: ts.StructDeclaration): ts.NodeArray<ts.HeritageClause> {
|
||||
const result:ts.HeritageClause[] = [];
|
||||
const heritageClause:ts.HeritageClause = ts.factory.createHeritageClause(
|
||||
ts.SyntaxKind.ExtendsKeyword,
|
||||
@@ -482,7 +480,7 @@ function validateBuildMethodCount(buildCount: BuildCount, parentComponentName: t
|
||||
}
|
||||
}
|
||||
|
||||
function validateInheritClass(node: ts.ClassDeclaration, log: LogInfo[]): void {
|
||||
function validateInheritClass(node: ts.StructDeclaration, log: LogInfo[]): void {
|
||||
if (node.heritageClauses) {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
|
||||
@@ -20,9 +20,7 @@ import {
|
||||
COMPONENT_CONSTRUCTOR_PARENT,
|
||||
COMPONENT_CONSTRUCTOR_PARAMS,
|
||||
COMPONENT_CONSTRUCTOR_UPDATE_PARAMS,
|
||||
COMPONENT_WATCH_FUNCTION,
|
||||
BASE_COMPONENT_NAME,
|
||||
INTERFACE_NAME_SUFFIX
|
||||
COMPONENT_WATCH_FUNCTION
|
||||
} from './pre_define';
|
||||
|
||||
export function getInitConstructor(members: ts.NodeArray<ts.Node>): ts.ConstructorDeclaration {
|
||||
@@ -32,12 +30,11 @@ export function getInitConstructor(members: ts.NodeArray<ts.Node>): ts.Construct
|
||||
if (ctorNode) {
|
||||
ctorNode = updateConstructor(ctorNode, [], [], true);
|
||||
}
|
||||
return ctorNode;
|
||||
return initConstructorParams(ctorNode);
|
||||
}
|
||||
|
||||
export function updateConstructor(ctorNode: ts.ConstructorDeclaration,
|
||||
para: ts.ParameterDeclaration[], addStatements: ts.Statement[],
|
||||
isSuper: boolean = false, isAdd: boolean = false, parentComponentName?: ts.Identifier):
|
||||
para: ts.ParameterDeclaration[], addStatements: ts.Statement[], isSuper: boolean = false):
|
||||
ts.ConstructorDeclaration {
|
||||
let modifyPara: ts.ParameterDeclaration[];
|
||||
if (para && para.length) {
|
||||
@@ -58,46 +55,29 @@ export function updateConstructor(ctorNode: ts.ConstructorDeclaration,
|
||||
}
|
||||
}
|
||||
if (ctorNode) {
|
||||
let ctorPara: ts.ParameterDeclaration[] | ts.NodeArray<ts.ParameterDeclaration> =
|
||||
modifyPara || ctorNode.parameters;
|
||||
if (isAdd) {
|
||||
ctorPara = addParamsType(ctorNode, modifyPara, parentComponentName);
|
||||
}
|
||||
ctorNode = ts.factory.updateConstructorDeclaration(ctorNode, ctorNode.decorators,
|
||||
ctorNode.modifiers, ctorPara, ts.factory.createBlock(modifyBody || ctorNode.body.statements, true));
|
||||
ctorNode.modifiers, modifyPara || ctorNode.parameters,
|
||||
ts.factory.createBlock(modifyBody || ctorNode.body.statements, true));
|
||||
}
|
||||
return ctorNode;
|
||||
}
|
||||
|
||||
function addParamsType(ctorNode: ts.ConstructorDeclaration, modifyPara: ts.ParameterDeclaration[],
|
||||
parentComponentName: ts.Identifier): ts.ParameterDeclaration[] {
|
||||
const tsPara: ts.ParameterDeclaration[] | ts.NodeArray<ts.ParameterDeclaration> =
|
||||
modifyPara || ctorNode.parameters;
|
||||
const newTSPara: ts.ParameterDeclaration[] = [];
|
||||
tsPara.forEach((item) => {
|
||||
let parameter: ts.ParameterDeclaration = item;
|
||||
switch (item.getText()) {
|
||||
case COMPONENT_CONSTRUCTOR_ID + '?':
|
||||
parameter = ts.factory.updateParameterDeclaration(item, item.decorators, item.modifiers,
|
||||
item.dotDotDotToken, item.name, item.questionToken,
|
||||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), item.initializer);
|
||||
break;
|
||||
case COMPONENT_CONSTRUCTOR_PARENT + '?':
|
||||
parameter = ts.factory.createParameterDeclaration(item.decorators, item.modifiers,
|
||||
item.dotDotDotToken, item.name, item.questionToken,
|
||||
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(BASE_COMPONENT_NAME), undefined),
|
||||
item.initializer);
|
||||
break;
|
||||
case COMPONENT_CONSTRUCTOR_PARAMS + '?':
|
||||
parameter = ts.factory.updateParameterDeclaration(item, item.decorators, item.modifiers,
|
||||
item.dotDotDotToken, item.name, item.questionToken,
|
||||
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(
|
||||
parentComponentName.getText() + INTERFACE_NAME_SUFFIX), undefined), item.initializer);
|
||||
break;
|
||||
}
|
||||
newTSPara.push(parameter);
|
||||
function initConstructorParams(node: ts.ConstructorDeclaration): ts.ConstructorDeclaration {
|
||||
const paramNames: string[] = [COMPONENT_CONSTRUCTOR_ID, COMPONENT_CONSTRUCTOR_PARENT,
|
||||
COMPONENT_CONSTRUCTOR_PARAMS];
|
||||
const newParameters: ts.ParameterDeclaration[] = Array.from(node.parameters);
|
||||
if (newParameters.length !== 0) {
|
||||
// @ts-ignore
|
||||
newParameters.splice(0, newParameters.length);
|
||||
}
|
||||
paramNames.forEach((paramName: string) => {
|
||||
// @ts-ignore
|
||||
newParameters.push(ts.factory.createParameterDeclaration(undefined, undefined, undefined,
|
||||
ts.factory.createIdentifier(paramName), undefined, undefined, undefined));
|
||||
});
|
||||
return newTSPara;
|
||||
|
||||
return ts.factory.updateConstructorDeclaration(node, undefined, node.modifiers, newParameters,
|
||||
node.body);
|
||||
}
|
||||
|
||||
export function addConstructor(ctorNode: any, watchMap: Map<string, ts.Node>,
|
||||
@@ -129,5 +109,5 @@ export function addConstructor(ctorNode: any, watchMap: Map<string, ts.Node>,
|
||||
ts.factory.createThis(), ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_UPDATE_PARAMS)),
|
||||
undefined, [ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS)]));
|
||||
return updateConstructor(updateConstructor(ctorNode, [], [callSuperStatement], true), [],
|
||||
[updateWithValueParamsStatement, ...watchStatements], false, true, parentComponentName);
|
||||
[updateWithValueParamsStatement, ...watchStatements], false);
|
||||
}
|
||||
|
||||
@@ -178,6 +178,9 @@ function getCustomComponentName(newNode: ts.NewExpression): string {
|
||||
}
|
||||
|
||||
function getCollectionSet(name: string, collection: Map<string, Set<string>>): Set<string> {
|
||||
if (!collection) {
|
||||
return new Set([]);
|
||||
}
|
||||
return collection.get(name) || new Set([]);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ export default function processImport(node: ts.ImportDeclaration | ts.ImportEqua
|
||||
fs.readFileSync(fileResolvePath, { encoding: 'utf-8' }).replace(
|
||||
new RegExp('\\b' + STRUCT + '\\b.+\\{', 'g'), item => {
|
||||
return item.replace(new RegExp('\\b' + STRUCT + '\\b', 'g'), `${CLASS} `);
|
||||
})), fileResolvePath, log);
|
||||
})));
|
||||
const sourceFile: ts.SourceFile = ts.createSourceFile(filePath, content,
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
||||
visitAllNode(sourceFile, defaultName, asName, path.dirname(fileResolvePath), log);
|
||||
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
PAGE_ENTRY_FUNCTION_NAME,
|
||||
COMPONENT_CONSTRUCTOR_UNDEFINED,
|
||||
BUILD_ON,
|
||||
COMPONENT_BUILD_FUNCTION,
|
||||
COMPONENT_BUILDER_DECORATOR,
|
||||
COMPONENT_EXTEND_DECORATOR,
|
||||
COMPONENT_STYLES_DECORATOR,
|
||||
@@ -35,7 +34,9 @@ import {
|
||||
RESOURCE_NAME_PARAMS,
|
||||
RESOURCE_RAWFILE,
|
||||
ATTRIBUTE_ANIMATETO,
|
||||
GLOBAL_CONTEXT
|
||||
GLOBAL_CONTEXT,
|
||||
CHECK_COMPONENT_EXTEND_DECORATOR,
|
||||
INSTANCE
|
||||
} from './pre_define';
|
||||
import {
|
||||
componentInfo,
|
||||
@@ -45,18 +46,13 @@ import {
|
||||
FileLog
|
||||
} from './utils';
|
||||
import {
|
||||
getName,
|
||||
isAttributeNode,
|
||||
processComponentBlock,
|
||||
bindComponentAttr,
|
||||
appComponentCollection
|
||||
bindComponentAttr
|
||||
} from './process_component_build';
|
||||
import {
|
||||
BUILDIN_CONTAINER_COMPONENT,
|
||||
BUILDIN_STYLE_NAMES,
|
||||
CUSTOM_BUILDER_METHOD,
|
||||
EXTEND_ATTRIBUTE,
|
||||
JS_BIND_COMPONENTS,
|
||||
INNER_STYLE_FUNCTION,
|
||||
GLOBAL_STYLE_FUNCTION,
|
||||
INTERFACE_NODE_SET
|
||||
@@ -73,20 +69,18 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
|
||||
return (node: ts.SourceFile) => {
|
||||
pagesDir = path.resolve(path.dirname(node.fileName));
|
||||
if (process.env.compiler === BUILD_ON) {
|
||||
if (!ut && (path.basename(node.fileName) === 'app.ets.ts' || !/\.ets\.ts$/.test(node.fileName))) {
|
||||
if (!ut && (path.basename(node.fileName) === 'app.ets' || /\.ts$/.test(node.fileName))) {
|
||||
node = ts.visitEachChild(node, processResourceNode, context);
|
||||
return node;
|
||||
}
|
||||
collectComponents(node);
|
||||
transformLog.sourceFile = node;
|
||||
validateSourceFileNode(node);
|
||||
node = createEntryNode(node, context);
|
||||
node = ts.visitEachChild(node, processAllNodes, context);
|
||||
GLOBAL_STYLE_FUNCTION.forEach((block, styleName) => {
|
||||
BUILDIN_STYLE_NAMES.delete(styleName);
|
||||
});
|
||||
GLOBAL_STYLE_FUNCTION.clear();
|
||||
const statements: ts.NodeArray<ts.Statement> = node.statements;
|
||||
const statements: ts.Statement[] = Array.from(node.statements);
|
||||
INTERFACE_NODE_SET.forEach(item => {
|
||||
statements.unshift(item);
|
||||
});
|
||||
@@ -100,8 +94,7 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
|
||||
function processAllNodes(node: ts.Node): ts.Node {
|
||||
if (ts.isImportDeclaration(node) || ts.isImportEqualsDeclaration(node)) {
|
||||
processImport(node, pagesDir, transformLog.errors);
|
||||
} else if (ts.isClassDeclaration(node) && node.name &&
|
||||
componentCollection.customComponents.has(node.name.getText())) {
|
||||
} else if (ts.isStructDeclaration(node)) {
|
||||
componentCollection.currentClassName = node.name.getText();
|
||||
node = processComponentClass(node, context, transformLog.errors, program);
|
||||
componentCollection.currentClassName = null;
|
||||
@@ -144,35 +137,9 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
|
||||
}
|
||||
return ts.visitEachChild(node, processResourceNode, context);
|
||||
}
|
||||
function validateSourceFileNode(node: ts.SourceFile): void {
|
||||
if (program) {
|
||||
node = ts.visitEachChild(node, validateAllNodes, context);
|
||||
}
|
||||
}
|
||||
function validateAllNodes(node: ts.Node): ts.Node {
|
||||
if (ts.isMethodDeclaration(node) && node.name &&
|
||||
node.name.getText() === COMPONENT_BUILD_FUNCTION && node.body && ts.isBlock(node.body)) {
|
||||
const typeChecker: ts.TypeChecker = program.getTypeChecker();
|
||||
validateBody(node.body, typeChecker);
|
||||
return node;
|
||||
}
|
||||
return ts.visitEachChild(node, validateAllNodes, context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function collectComponents(node: ts.SourceFile): void {
|
||||
// @ts-ignore
|
||||
if (node.identifiers && node.identifiers.size) {
|
||||
// @ts-ignore
|
||||
for (const key of node.identifiers.keys()) {
|
||||
if (JS_BIND_COMPONENTS.has(key)) {
|
||||
appComponentCollection.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isResource(node: ts.Node): boolean {
|
||||
return ts.isCallExpression(node) && ts.isIdentifier(node.expression) &&
|
||||
(node.expression.escapedText.toString() === RESOURCE ||
|
||||
@@ -285,29 +252,51 @@ function processAnimateTo(node: ts.CallExpression): ts.CallExpression {
|
||||
|
||||
function processExtend(node: ts.FunctionDeclaration, log: LogInfo[]): ts.FunctionDeclaration {
|
||||
const componentName: string = isExtendFunction(node);
|
||||
if (componentName) {
|
||||
if (componentName && node.body && node.body.statements.length) {
|
||||
const statementArray: ts.Statement[] = [];
|
||||
bindComponentAttr(node.body.statements[0] as ts.ExpressionStatement,
|
||||
const attrSet: ts.CallExpression = node.body.statements[0].expression;
|
||||
const changeCompName: ts.ExpressionStatement = ts.factory.createExpressionStatement(processExtendBody(attrSet));
|
||||
bindComponentAttr(changeCompName as ts.ExpressionStatement,
|
||||
ts.factory.createIdentifier(componentName), statementArray, log);
|
||||
let extendFunctionName: string;
|
||||
if (node.name.getText().startsWith('__' + componentName + '__')) {
|
||||
extendFunctionName = node.name.getText();
|
||||
} else {
|
||||
extendFunctionName = '__' + componentName + '__' + node.name.getText();
|
||||
collectExtend(EXTEND_ATTRIBUTE, componentName, node.name.escapedText.toString());
|
||||
}
|
||||
return ts.factory.updateFunctionDeclaration(node, undefined, node.modifiers, node.asteriskToken,
|
||||
node.name, node.typeParameters, node.parameters, node.type,
|
||||
ts.factory.updateBlock(node.body, statementArray));
|
||||
ts.factory.createIdentifier(extendFunctionName), node.typeParameters,
|
||||
node.parameters, node.type, ts.factory.updateBlock(node.body, statementArray));
|
||||
}
|
||||
}
|
||||
|
||||
function processExtendBody(node: ts.Node): ts.Expression {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.CallExpression:
|
||||
return ts.factory.createCallExpression(processExtendBody(node.expression), undefined, node.arguments);
|
||||
case ts.SyntaxKind.PropertyAccessExpression:
|
||||
return ts.factory.createPropertyAccessExpression(processExtendBody(node.expression), node.name);
|
||||
case ts.SyntaxKind.Identifier:
|
||||
return ts.factory.createIdentifier(node.escapedText.toString().replace(INSTANCE, ''));
|
||||
}
|
||||
}
|
||||
|
||||
export function collectExtend(collectionSet: Map<string, Set<string>>, component: string, attribute: string): void {
|
||||
if (collectionSet.has(component)) {
|
||||
collectionSet.get(component).add(attribute);
|
||||
} else {
|
||||
collectionSet.set(component, new Set([attribute]));
|
||||
}
|
||||
}
|
||||
|
||||
function isExtendFunction(node: ts.FunctionDeclaration): string {
|
||||
if (ts.isBlock(node.body) && node.body.statements && node.body.statements.length === 1 &&
|
||||
ts.isExpressionStatement(node.body.statements[0]) &&
|
||||
// @ts-ignore
|
||||
ts.isCallExpression(node.body.statements[0].expression) && ts.isIdentifier(node.name)) {
|
||||
const nameArray: string[] = node.name.getText().split('__');
|
||||
if (nameArray.length === 3 && !nameArray[0] && EXTEND_ATTRIBUTE.has(nameArray[1])) {
|
||||
const attributeArray: string[] =
|
||||
[...EXTEND_ATTRIBUTE.get(nameArray[1])].map(item => item.attribute);
|
||||
if (attributeArray.includes(nameArray[2])) {
|
||||
return nameArray[1];
|
||||
}
|
||||
}
|
||||
if (node.decorators && node.decorators[0].expression &&
|
||||
node.decorators[0].expression.expression.escapedText.toString() === CHECK_COMPONENT_EXTEND_DECORATOR &&
|
||||
node.decorators[0].expression.arguments) {
|
||||
return node.decorators[0].expression.arguments[0].escapedText.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,122 +314,6 @@ function createEntryNode(node: ts.SourceFile, context: ts.TransformationContext)
|
||||
}
|
||||
}
|
||||
|
||||
function validateBody(node: ts.Block, typeChecker: ts.TypeChecker): void {
|
||||
if (node.statements.length) {
|
||||
node.statements.forEach((item, index, arr) => {
|
||||
if (ts.isBlock(item)) {
|
||||
validateBody(item, typeChecker);
|
||||
}
|
||||
if (index + 2 < arr.length && ts.isExpressionStatement(item) &&
|
||||
isAttributeBlockNode(item, arr as ts.Statement[], index) &&
|
||||
ts.isCallExpression(item.expression) && ts.isIdentifier(item.expression.expression)) {
|
||||
const componentName: string = item.expression.expression.getText();
|
||||
const type: ts.Type = typeChecker.getTypeAtLocation(item.expression);
|
||||
let temp: any = arr[index + 2];
|
||||
let name: string;
|
||||
while (temp) {
|
||||
if (ts.isCallExpression(temp)) {
|
||||
if (ts.isPropertyAccessExpression(temp.expression)) {
|
||||
const pos: number = temp.expression.name.getStart();
|
||||
name = temp.expression.name.getText();
|
||||
validateSymbol(isPropertyExist(typeChecker, pos, type, name, componentName),
|
||||
temp.arguments, pos, typeChecker);
|
||||
} else if (ts.isIdentifier(temp.expression)) {
|
||||
const pos: number = temp.expression.getStart();
|
||||
name = temp.expression.getText();
|
||||
validateSymbol(isPropertyExist(typeChecker, pos, type, name, componentName),
|
||||
temp.arguments, pos, typeChecker);
|
||||
break;
|
||||
}
|
||||
}
|
||||
temp = temp.expression;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function validateSymbol(type: ts.Symbol, args: ts.NodeArray<ts.Expression>,
|
||||
argPos: number, typeChecker: ts.TypeChecker): void {
|
||||
// @ts-ignore
|
||||
if (type && type.valueDeclaration.parameters) {
|
||||
// @ts-ignore
|
||||
const parameters: ts.ParameterDeclaration[] = type.valueDeclaration.parameters;
|
||||
const maxLength: number = parameters.length;
|
||||
const minLength: number = getMinLength(parameters);
|
||||
if (args.length < minLength || args.length > maxLength) {
|
||||
let message:string;
|
||||
if (maxLength !== minLength) {
|
||||
message = `TS2554: Expected ${minLength}-${maxLength} arguments, but got ${args.length}.`;
|
||||
} else {
|
||||
message = `TS2554: Expected ${maxLength} arguments, but got ${args.length}.`;
|
||||
}
|
||||
transformLog.errors.push({
|
||||
type: LogType.ERROR,
|
||||
message: message,
|
||||
pos: argPos
|
||||
});
|
||||
} else {
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
validatePropertyType(parameters[i], args[i], typeChecker);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMinLength(parameters: ts.ParameterDeclaration[]): number {
|
||||
let length: number = parameters.length;
|
||||
parameters.forEach((item: ts.ParameterDeclaration) => {
|
||||
if (item.questionToken !== undefined) {
|
||||
length--;
|
||||
}
|
||||
});
|
||||
return length;
|
||||
}
|
||||
|
||||
function isPropertyExist(typeChecker: ts.TypeChecker, pos: number, type: ts.Type,
|
||||
propertyName: string, componentName: string): ts.Symbol {
|
||||
const symbol: ts.Symbol = typeChecker.getPropertyOfType(type, propertyName);
|
||||
if (symbol) {
|
||||
return symbol;
|
||||
} else {
|
||||
transformLog.errors.push({
|
||||
type: LogType.ERROR,
|
||||
message: `TS2339: Property '${propertyName}' does not exist on type '${componentName}Attribute'.`,
|
||||
pos: pos
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function validatePropertyType(param: ts.ParameterDeclaration, arg: ts.Expression,
|
||||
typeChecker: ts.TypeChecker): void {
|
||||
const argLocalType: ts.Type = typeChecker.getTypeAtLocation(arg);
|
||||
const paramLocalType: ts.Type = typeChecker.getTypeAtLocation(param.type);
|
||||
const argType: ts.Type = typeChecker.getBaseTypeOfLiteralType(typeChecker.getTypeAtLocation(arg));
|
||||
// @ts-ignore
|
||||
const intrinsicName: string = argType.intrinsicName;
|
||||
const argTypeName: string = intrinsicName || typeChecker.typeToString(argLocalType);
|
||||
// @ts-ignore
|
||||
if (!typeChecker.isTypeAssignableTo(argLocalType, paramLocalType)) {
|
||||
generateArgumentLog(arg, argTypeName, typeChecker.typeToString(paramLocalType));
|
||||
}
|
||||
}
|
||||
|
||||
function generateArgumentLog(arg: ts.Expression, argTypeName: string, paramTypeName: string): void {
|
||||
transformLog.errors.push({
|
||||
type: LogType.ERROR,
|
||||
message: `TS2345: Argument of type '${argTypeName}' is not assignable to parameter of type '${paramTypeName}'.`,
|
||||
pos: arg.getStart()
|
||||
});
|
||||
}
|
||||
|
||||
function isAttributeBlockNode(node: ts.ExpressionStatement, arr: ts.Statement[], index: number): boolean {
|
||||
const attributeNode: ts.Node = arr[index + 2];
|
||||
return BUILDIN_CONTAINER_COMPONENT.has(getName(node)) && ts.isBlock(arr[index + 1])
|
||||
&& ts.isExpressionStatement(attributeNode) && isAttributeNode(attributeNode);
|
||||
}
|
||||
|
||||
function createEntryFunction(name: string, context: ts.TransformationContext)
|
||||
: ts.ExpressionStatement {
|
||||
return context.factory.createExpressionStatement(context.factory.createCallExpression(
|
||||
|
||||
@@ -52,7 +52,7 @@ module.exports = function resultProcess(source: string, map: any): void {
|
||||
item.line = undefined;
|
||||
item.column = undefined;
|
||||
}
|
||||
item.fileName = sourceFile.fileName.replace(/.ts$/, '');
|
||||
item.fileName = sourceFile.fileName;
|
||||
return item;
|
||||
});
|
||||
emitLogInfo(this, logInfos);
|
||||
|
||||
@@ -112,11 +112,11 @@ class ComponentInfo {
|
||||
|
||||
export const componentInfo: ComponentInfo = new ComponentInfo();
|
||||
|
||||
export function hasDecorator(node: ts.MethodDeclaration | ts.FunctionDeclaration | ts.ClassDeclaration,
|
||||
decortorName: string): boolean {
|
||||
export function hasDecorator(node: ts.MethodDeclaration | ts.FunctionDeclaration |
|
||||
ts.StructDeclaration | ts.ClassDeclaration, decortorName: string): boolean {
|
||||
if (node.decorators && node.decorators.length) {
|
||||
for (let i = 0; i < node.decorators.length; i++) {
|
||||
if (node.decorators[i].getText() === decortorName) {
|
||||
if (node.decorators[i].getText().replace(/\(.*\)$/, '').trim() === decortorName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ import {
|
||||
COMPONENT_DECORATOR_PREVIEW,
|
||||
COMPONENT_DECORATOR_COMPONENT,
|
||||
COMPONENT_DECORATOR_CUSTOM_DIALOG,
|
||||
STRUCT,
|
||||
CLASS,
|
||||
NATIVE_MODULE,
|
||||
SYSTEM_PLUGIN,
|
||||
OHOS_PLUGIN,
|
||||
@@ -38,9 +36,6 @@ import {
|
||||
COMPONENT_PROVIDE_DECORATOR,
|
||||
COMPONENT_CONSUME_DECORATOR,
|
||||
COMPONENT_OBJECT_LINK_DECORATOR,
|
||||
COMPONENT_CONSTRUCTOR_ID,
|
||||
COMPONENT_CONSTRUCTOR_PARENT,
|
||||
COMPONENT_CONSTRUCTOR_PARAMS,
|
||||
COMPONENT_OBSERVED_DECORATOR,
|
||||
STYLES,
|
||||
VALIDATE_MODULE,
|
||||
@@ -65,7 +60,7 @@ import {
|
||||
hasDecorator
|
||||
} from './utils';
|
||||
import { projectConfig } from '../main';
|
||||
const parser = require('../syntax_parser/dist/exclude_comment.js');
|
||||
import { collectExtend } from './process_ui_syntax';
|
||||
|
||||
export interface ComponentCollection {
|
||||
entryComponent: string;
|
||||
@@ -137,7 +132,7 @@ function checkComponentDecorator(source: string, filePath: string,
|
||||
fileQuery: string): LogInfo[] | null {
|
||||
const log: LogInfo[] = [];
|
||||
const sourceFile: ts.SourceFile = ts.createSourceFile(filePath, source,
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
|
||||
if (sourceFile && sourceFile.statements && sourceFile.statements.length) {
|
||||
const result: DecoratorResult = {
|
||||
entryCount: 0,
|
||||
@@ -151,26 +146,17 @@ function checkComponentDecorator(source: string, filePath: string,
|
||||
if (ts.isEnumDeclaration(item) && item.name) {
|
||||
enumCollection.add(item.name.getText());
|
||||
}
|
||||
if (isStruct(item)) {
|
||||
if (index + 1 < arr.length && ts.isExpressionStatement(arr[index + 1]) &&
|
||||
// @ts-ignore
|
||||
arr[index + 1].expression && ts.isIdentifier(arr[index + 1].expression)) {
|
||||
if (ts.isExportAssignment(item) && hasComponentDecorator(item)) {
|
||||
checkDecorators(item, result, arr[index + 1] as ts.ExpressionStatement, log, sourceFile);
|
||||
} else if (index > 0 && hasComponentDecorator(arr[index - 1])) {
|
||||
checkDecorators(arr[index - 1] as ts.MissingDeclaration, result,
|
||||
arr[index + 1] as ts.ExpressionStatement, log, sourceFile);
|
||||
if (ts.isStructDeclaration(item)) {
|
||||
if (item.name && ts.isIdentifier(item.name)) {
|
||||
if (item.decorators && item.decorators.length) {
|
||||
checkDecorators(item.decorators, result, item.name, log, sourceFile);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
const pos: number = item.expression.getStart();
|
||||
const message: string = `A struct should use decorator '@Component'.`;
|
||||
addLog(LogType.WARN, message, pos, log, sourceFile);
|
||||
addLog(LogType.WARN, message, item.getStart(), log, sourceFile);
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
const pos: number = item.expression.getStart();
|
||||
const message: string = `A struct must have a name.`;
|
||||
addLog(LogType.ERROR, message, pos, log, sourceFile);
|
||||
addLog(LogType.ERROR, message, item.getStart(), log, sourceFile);
|
||||
}
|
||||
}
|
||||
if (ts.isMissingDeclaration(item)) {
|
||||
@@ -245,32 +231,16 @@ export function isCustomDialogClass(node: ts.Node): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isStruct(node: ts.Node): boolean {
|
||||
if ((ts.isExpressionStatement(node) || ts.isExportAssignment(node)) &&
|
||||
node.expression && ts.isIdentifier(node.expression) && node.expression.getText() === STRUCT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function hasComponentDecorator(node: ts.Node): boolean {
|
||||
if ((ts.isMissingDeclaration(node) || ts.isExportAssignment(node)) &&
|
||||
node.decorators && node.decorators.length) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
interface DecoratorResult {
|
||||
entryCount: number;
|
||||
previewCount: number;
|
||||
}
|
||||
|
||||
function checkDecorators(node: ts.MissingDeclaration | ts.ExportAssignment, result: DecoratorResult,
|
||||
component: ts.ExpressionStatement, log: LogInfo[], sourceFile: ts.SourceFile): void {
|
||||
function checkDecorators(decorators: ts.NodeArray<ts.Decorator>, result: DecoratorResult,
|
||||
component: ts.Identifier, log: LogInfo[], sourceFile: ts.SourceFile): void {
|
||||
let hasComponentDecorator: boolean = false;
|
||||
const componentName: string = component.getText();
|
||||
node.decorators.forEach((element) => {
|
||||
decorators.forEach((element) => {
|
||||
const name: string = element.getText().replace(/\([^\(\)]*\)/, '').trim();
|
||||
if (INNER_COMPONENT_DECORATORS.has(name)) {
|
||||
componentCollection.customComponents.add(componentName);
|
||||
@@ -316,14 +286,14 @@ function checkDecorators(node: ts.MissingDeclaration | ts.ExportAssignment, resu
|
||||
function checkUISyntax(filePath: string, allComponentNames: Set<string>, content: string,
|
||||
log: LogInfo[]): void {
|
||||
const sourceFile: ts.SourceFile = ts.createSourceFile(filePath, content,
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
|
||||
visitAllNode(sourceFile, sourceFile, allComponentNames, log);
|
||||
}
|
||||
|
||||
function visitAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, allComponentNames: Set<string>,
|
||||
log: LogInfo[]) {
|
||||
checkAllNode(node, allComponentNames, sourceFileNode, log);
|
||||
if (ts.isClassDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
|
||||
if (ts.isStructDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
|
||||
collectComponentProps(node);
|
||||
}
|
||||
if (ts.isMethodDeclaration(node) && hasDecorator(node, COMPONENT_BUILDER_DECORATOR)) {
|
||||
@@ -335,7 +305,7 @@ function visitAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, allComponent
|
||||
function checkAllNode(node: ts.Node, allComponentNames: Set<string>, sourceFileNode: ts.SourceFile,
|
||||
log: LogInfo[]): void {
|
||||
if (ts.isExpressionStatement(node) && node.expression && ts.isIdentifier(node.expression) &&
|
||||
allComponentNames.has(node.expression.escapedText.toString())) {
|
||||
allComponentNames.has(node.expression.escapedText.toString())) {
|
||||
const pos: number = node.expression.getStart();
|
||||
const message: string =
|
||||
`The component name must be followed by parentheses, like '${node.expression.getText()}()'.`;
|
||||
@@ -629,7 +599,7 @@ function isNonspecificChildIfStatement(node: ts.Node, specificChildSet: Set<stri
|
||||
return false;
|
||||
}
|
||||
|
||||
function collectComponentProps(node: ts.ClassDeclaration): void {
|
||||
function collectComponentProps(node: ts.StructDeclaration): void {
|
||||
const componentName: string = node.name.getText();
|
||||
const ComponentSet: IComponentSet = getComponentSet(node);
|
||||
propertyCollection.set(componentName, ComponentSet.propertys);
|
||||
@@ -644,7 +614,7 @@ function collectComponentProps(node: ts.ClassDeclaration): void {
|
||||
objectLinkCollection.set(componentName, ComponentSet.objectLinks);
|
||||
}
|
||||
|
||||
export function getComponentSet(node: ts.ClassDeclaration): IComponentSet {
|
||||
export function getComponentSet(node: ts.StructDeclaration): IComponentSet {
|
||||
const propertys: Set<string> = new Set();
|
||||
const states: Set<string> = new Set();
|
||||
const links: Set<string> = new Set();
|
||||
@@ -663,7 +633,7 @@ export function getComponentSet(node: ts.ClassDeclaration): IComponentSet {
|
||||
};
|
||||
}
|
||||
|
||||
function traversalComponentProps(node: ts.ClassDeclaration, propertys: Set<string>,
|
||||
function traversalComponentProps(node: ts.StructDeclaration, propertys: Set<string>,
|
||||
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>): void {
|
||||
@@ -736,14 +706,7 @@ export interface ReplaceResult {
|
||||
export function sourceReplace(source: string, sourcePath: string): ReplaceResult {
|
||||
let content: string = source;
|
||||
const log: LogInfo[] = [];
|
||||
// replace struct->class
|
||||
content = content.replace(
|
||||
new RegExp('\\b' + STRUCT + '\\b.+\\{', 'g'), item => {
|
||||
item = item.replace(new RegExp('\\b' + STRUCT + '\\b', 'g'), `${CLASS} `);
|
||||
return `${item} constructor(${COMPONENT_CONSTRUCTOR_ID}?, ${COMPONENT_CONSTRUCTOR_PARENT}?, ${COMPONENT_CONSTRUCTOR_PARAMS}?) {}`;
|
||||
});
|
||||
|
||||
content = preprocessExtend(content, sourcePath, log);
|
||||
content = preprocessExtend(content);
|
||||
// process @system.
|
||||
content = processSystemApi(content);
|
||||
|
||||
@@ -753,57 +716,16 @@ export function sourceReplace(source: string, sourcePath: string): ReplaceResult
|
||||
};
|
||||
}
|
||||
|
||||
export function preprocessExtend(content: string, sourcePath: string, log: LogInfo[]): string {
|
||||
let syntaxCheckContent: string;
|
||||
let result: any;
|
||||
try {
|
||||
result = parser.parse(content);
|
||||
syntaxCheckContent = result.content;
|
||||
for (let i = 0; i < result.collect_extend.component.length; i++) {
|
||||
collectExtend(
|
||||
result.collect_extend.component[i],
|
||||
result.collect_extend.functionName[i],
|
||||
result.collect_extend.parameters[i]
|
||||
);
|
||||
export function preprocessExtend(content: string, extendCollection?: Set<string>): string {
|
||||
const REG_EXTEND: RegExp = /@Extend(\s+)([^\.\s]+)\.([^\(]+)\(/gm;
|
||||
return content.replace(REG_EXTEND, (item, item1, item2, item3) => {
|
||||
collectExtend(EXTEND_ATTRIBUTE, item2, '__' + item2 + '__' + item3);
|
||||
collectExtend(EXTEND_ATTRIBUTE, item2, item3);
|
||||
if (extendCollection) {
|
||||
extendCollection.add(item3);
|
||||
}
|
||||
} catch (err) {
|
||||
result = err;
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: parser.SyntaxError.buildMessage(err.expected, err.found),
|
||||
line: err.location.start.line,
|
||||
column: err.location.start.column,
|
||||
fileName: sourcePath
|
||||
});
|
||||
syntaxCheckContent = content;
|
||||
}
|
||||
if (result.error_otherParsers) {
|
||||
for (let i = 0; i < result.error_otherParsers.length; i++) {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: result.error_otherParsers[i].errMessage,
|
||||
line: result.error_otherParsers[i].errPosition.line,
|
||||
column: result.error_otherParsers[i].errPosition.column,
|
||||
fileName: sourcePath
|
||||
});
|
||||
}
|
||||
}
|
||||
return syntaxCheckContent;
|
||||
}
|
||||
|
||||
function collectExtend(component: string, attribute: string, parameter: string): void {
|
||||
let parameterCount: number;
|
||||
if (parameter) {
|
||||
parameterCount = parameter.split(',').length;
|
||||
} else {
|
||||
parameterCount = 0;
|
||||
}
|
||||
BUILDIN_STYLE_NAMES.add(attribute);
|
||||
if (EXTEND_ATTRIBUTE.has(component)) {
|
||||
EXTEND_ATTRIBUTE.get(component).add({ attribute, parameterCount });
|
||||
} else {
|
||||
EXTEND_ATTRIBUTE.set(component, new Set([{ attribute, parameterCount }]));
|
||||
}
|
||||
return `@Extend(${item2})${item1}function __${item2}__${item3}(`;
|
||||
});
|
||||
}
|
||||
|
||||
export function processSystemApi(content: string, isProcessWhiteList: boolean = false): string {
|
||||
|
||||
@@ -38,11 +38,14 @@ function expectActual(name, filePath) {
|
||||
process.env.compiler = BUILD_ON;
|
||||
const afterProcess = sourceReplace(source);
|
||||
validateUISyntax(source, afterProcess.content, `${name}.ts`);
|
||||
const compilerOptions = ts.readConfigFile(
|
||||
path.resolve(__dirname, '../tsconfig.json'), ts.sys.readFile).config.compilerOptions;
|
||||
Object.assign(compilerOptions, {
|
||||
"sourceMap": false,
|
||||
});
|
||||
const result = ts.transpileModule(afterProcess.content, {
|
||||
compilerOptions: {
|
||||
"target": ts.ScriptTarget.ES2017
|
||||
},
|
||||
fileName: `${name}.ts`,
|
||||
compilerOptions: compilerOptions,
|
||||
fileName: `${name}.ets`,
|
||||
transformers: { before: [processUISyntax(null, true)] }
|
||||
});
|
||||
componentInfo.id = 0;
|
||||
|
||||
@@ -25,8 +25,7 @@ struct Parent {
|
||||
Row() {
|
||||
Child({ stateProperty: this.regularToState,
|
||||
propProperty: this.stateToProp,
|
||||
regularProperty: this.regularToRegular,
|
||||
linkProperty: this.$stateToLink
|
||||
regularProperty: this.regularToRegular, linkProperty: this.__stateToLink
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -91,8 +90,7 @@ exports.expectResult =
|
||||
if (earlierCreatedChild_2 == undefined) {
|
||||
View.create(new Child("2", this, { stateProperty: this.regularToState,
|
||||
propProperty: this.stateToProp,
|
||||
regularProperty: this.regularToRegular,
|
||||
linkProperty: this.__stateToLink
|
||||
regularProperty: this.regularToRegular, linkProperty: this.__stateToLink
|
||||
}));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -20,9 +20,17 @@ struct MyComponent {
|
||||
}`
|
||||
|
||||
exports.expectResult =
|
||||
`class MyComponent {
|
||||
constructor(compilerAssignedUniqueChildId, parent, params) { }
|
||||
build() {
|
||||
`class MyComponent extends View {
|
||||
constructor(compilerAssignedUniqueChildId, parent, params) {
|
||||
super(compilerAssignedUniqueChildId, parent);
|
||||
this.updateWithValueParams(params);
|
||||
}
|
||||
updateWithValueParams(params) {
|
||||
}
|
||||
aboutToBeDeleted() {
|
||||
SubscriberManager.Get().delete(this.id());
|
||||
}
|
||||
render() {
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@@ -1,6 +1,544 @@
|
||||
{
|
||||
"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",
|
||||
"FrictionMotion",
|
||||
"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",
|
||||
"Row",
|
||||
"RowSplit",
|
||||
"RichText",
|
||||
"Scroll",
|
||||
"ScrollBar",
|
||||
"ScrollMotion",
|
||||
"Search",
|
||||
"Section",
|
||||
"Select",
|
||||
"Shape",
|
||||
"Sheet",
|
||||
"SideBarContainer",
|
||||
"Slider",
|
||||
"Span",
|
||||
"Stack",
|
||||
"Stepper",
|
||||
"StepperItem",
|
||||
"Swiper",
|
||||
"TabContent",
|
||||
"Tabs",
|
||||
"Text",
|
||||
"TextPicker",
|
||||
"TextClock",
|
||||
"TextArea",
|
||||
"TextInput",
|
||||
"TextTimer",
|
||||
"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": "FrictionMotion",
|
||||
"type": "FrictionMotionAttribute",
|
||||
"instance": "FrictionMotionInstance"
|
||||
},
|
||||
{
|
||||
"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": "Refresh",
|
||||
"type": "RefreshAttribute",
|
||||
"instance": "RefreshInstance"
|
||||
},
|
||||
{
|
||||
"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": "ScrollMotion",
|
||||
"type": "ScrollMotionAttribute",
|
||||
"instance": "ScrollMotionInstance"
|
||||
},
|
||||
{
|
||||
"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": "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,
|
||||
@@ -11,6 +549,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"module": "commonjs",
|
||||
"target": "es2017",
|
||||
|
||||
@@ -40,6 +40,9 @@ function initConfig(config) {
|
||||
const projectPath = path.resolve(projectConfig.projectPath);
|
||||
Object.assign(config, {
|
||||
entry: projectConfig.entryObj,
|
||||
cache: {
|
||||
type: "filesystem"
|
||||
},
|
||||
watch: watchMode,
|
||||
watchOptions: {
|
||||
aggregateTimeout: 10,
|
||||
@@ -67,8 +70,8 @@ function initConfig(config) {
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
appendTsSuffixTo: [/\.ets$/],
|
||||
onlyCompileBundledFiles: true,
|
||||
transpileOnly: true,
|
||||
configFile: path.resolve(__dirname, 'tsconfig.json'),
|
||||
getCustomTransformers(program) {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user