mirror of
https://github.com/openharmony/developtools_ace-ets2bundle.git
synced 2026-07-18 16:04:32 -04:00
Merge branch 'master' of gitee.com:openharmony/developtools_ace-ets2bundle into shz_Swiper_ets_indicatorStyle_0222
This commit is contained in:
@@ -17,10 +17,24 @@ const ts = require('typescript')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
|
||||
const addTSInterfaceSet = ['ForEach', 'LazyForEach', 'TapGesture', 'LongPressGesture', 'LongPressGesture',
|
||||
'PanGesture', 'SwipeGesture', 'PinchGesture', 'RotationGesture', 'GestureGroup','PageTransitionEnter',
|
||||
'PageTransitionExit'];
|
||||
const addTSAttributeSet = ['AlphabetIndexer', 'Animator', 'Badge', 'Blank', 'Button', 'Calendar', 'Canvas',
|
||||
'Checkbox', 'CheckboxGroup', 'Circle', 'Column', 'ColumnSplit', 'Counter', 'DataPanel', 'DatePicker',
|
||||
'Divider', 'Ellipse', 'Flex', 'FormComponent', 'Gauge', 'Grid', 'GridItem', 'GridContainer', 'Image',
|
||||
'ImageAnimator', 'Line', 'List', 'ListItem', 'LoadingProgress', 'Marquee', 'Navigation', 'Navigator',
|
||||
'Panel', 'Path', 'PatternLock', 'Piece', 'PluginComponent', 'Polygon', 'Polyline', 'Progress',
|
||||
'QRCode', 'Radio', 'Rating', 'Rect', 'Refresh', 'Row', 'RowSplit', 'Scroll', 'ScrollBar', 'Search',
|
||||
'Select', 'Shape', 'Sheet', 'Slider', 'Span', 'Stack', 'Stepper', 'StepperItem', 'Swiper',
|
||||
'TabContent', 'Tabs', 'Text', 'TextArea', 'TextClock', 'TextInput', 'TextPicker', 'TextTimer',
|
||||
'Toggle', 'Video', 'Web', 'XComponent', 'RichText'];
|
||||
|
||||
generateTargetFile(process.argv[2], process.argv[3]);
|
||||
function generateTargetFile(filePath, output) {
|
||||
const files = [];
|
||||
const globalTsFile = path.resolve(filePath, '../../global.d.ts');
|
||||
const middleTsFile = path.resolve(filePath, 'middle_class.d.ts');
|
||||
if (fs.existsSync(globalTsFile)) {
|
||||
files.push(globalTsFile);
|
||||
}
|
||||
@@ -47,7 +61,7 @@ function generateTargetFile(filePath, output) {
|
||||
const fileName = path.resolve(output, path.basename(item));
|
||||
if (item === globalTsFile) {
|
||||
content = license + '\n\n' + processsFile(content, fileName, true);
|
||||
} else {
|
||||
} else if (path.resolve(item) !== middleTsFile) {
|
||||
content = license + '\n\n' + processsFile(content, fileName, false);
|
||||
}
|
||||
fs.writeFile(fileName, content, err => {
|
||||
@@ -127,6 +141,18 @@ function processComponent(node, newStatements) {
|
||||
node = ts.factory.updateInterfaceDeclaration(node, node.decorators, node.modifiers,
|
||||
node.name, node.typeParameters, [heritageClause], node.members);
|
||||
}
|
||||
if (addTSInterfaceSet.includes(componentName)) {
|
||||
node = ts.factory.updateInterfaceDeclaration(node, node.decorators, node.modifiers, node.name,
|
||||
node.typeParameters, [ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword,
|
||||
[ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier('TS' + componentName + 'Interface'),
|
||||
undefined)])], node.members);
|
||||
}
|
||||
}
|
||||
if (isClass(node) && addTSAttributeSet.includes(node.name.getText().replace(/Attribute$/, ''))) {
|
||||
node = ts.factory.updateClassDeclaration(node, node.decorators, node.modifiers, node.name,
|
||||
node.typeParameters, [ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword,
|
||||
[ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier('TS' + node.name.getText()),
|
||||
undefined)])], node.members);
|
||||
}
|
||||
newStatements.push(node);
|
||||
}
|
||||
@@ -164,6 +190,11 @@ function isInterface(node) {
|
||||
/Interface$/.test(node.name.getText());
|
||||
}
|
||||
|
||||
function isClass(node) {
|
||||
return ts.isClassDeclaration(node) && node.name && ts.isIdentifier(node.name) &&
|
||||
/Attribute$/.test(node.name.getText());
|
||||
}
|
||||
|
||||
function isSignNode(node) {
|
||||
return (ts.isCallSignatureDeclaration(node) || ts.isConstructSignatureDeclaration(node)) &&
|
||||
node.type && ts.isTypeReferenceNode(node.type) && node.type.typeName && ts.isIdentifier(node.type.typeName) &&
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"name": "Button",
|
||||
"single": true,
|
||||
"attrs": ["type", "stateEffect", "fontColor", "fontSize", "fontWeight", "fontStyle", "fontFamily"]
|
||||
}
|
||||
@@ -5,6 +5,6 @@
|
||||
"columnsTemplate", "rowsTemplate", "columnsGap", "rowsGap", "scrollBar", "scrollBarWidth",
|
||||
"scrollBarColor", "editMode", "maxCount", "minCount", "cellLength", "onItemDragStart",
|
||||
"onItemDragMove", "onItemDragEnter", "onItemDragMove", "onItemDrop", "layoutDirection", "direction",
|
||||
"supportAnimation", "onItemDragLeave"
|
||||
"supportAnimation", "onItemDragLeave", "multiSelectable"
|
||||
]
|
||||
}
|
||||
@@ -2,5 +2,5 @@
|
||||
"name": "GridItem",
|
||||
"parents": ["Grid"],
|
||||
"single": true,
|
||||
"attrs": ["rowStart", "rowEnd", "columnStart", "columnEnd", "forceRebuild"]
|
||||
"attrs": ["rowStart", "rowEnd", "columnStart", "columnEnd", "forceRebuild", "selectable", "onSelect"]
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
"attrs": [
|
||||
"listDirection", "scrollBar", "edgeEffect", "divider", "editMode", "cachedCount",
|
||||
"chainAnimation", "onScroll", "onReachStart", "onReachEnd", "onScrollStop", "onItemDelete",
|
||||
"onItemMove", "onItemDragStart", "onItemDragEnter", "onItemDragMove", "onItemDragLeave", "onItemDrop"
|
||||
"onItemMove", "onItemDragStart", "onItemDragEnter", "onItemDragMove", "onItemDragLeave", "onItemDrop",
|
||||
"multiSelectable"
|
||||
]
|
||||
}
|
||||
@@ -2,5 +2,5 @@
|
||||
"name": "ListItem",
|
||||
"parents": ["List"],
|
||||
"single": true,
|
||||
"attrs": ["sticky", "editable"]
|
||||
"attrs": ["sticky", "editable", "selectable", "onSelect"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "RichText",
|
||||
"single": true,
|
||||
"attrs": [
|
||||
"onStart", "onComplete"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "SideBarContainer",
|
||||
"attrs": [
|
||||
"showControlButton", "onChange"
|
||||
"showControlButton", "onChange", "sideBarWidth", "maxSideBarWidth", "maxSideBarWidth"
|
||||
]
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "Slider",
|
||||
"atomic": true,
|
||||
"attrs": [
|
||||
"blockColor", "trackColor", "selectedColor", "minLabel", "maxLabel", "showSteps", "showTips",
|
||||
"blockColor", "trackColor", "selectedColor", "minLabel", "maxLabel", "showSteps", "showTips", "trackThickness",
|
||||
"onChange"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "Swiper",
|
||||
"attrs": [
|
||||
"index", "autoPlay", "interval", "indicator", "loop", "duration", "vertical", "itemSpace",
|
||||
"cachedCount", "displayMode", "displayCount", "effectMode", "disableSwipe", "onChange", "indicatorStyle"
|
||||
"cachedCount", "displayMode", "displayCount", "effectMode", "disableSwipe", "curve", "onChange",
|
||||
"indicatorStyle"
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "TabContent",
|
||||
"parents": ["Tabs"],
|
||||
"attrs": ["tabBar"]
|
||||
"attrs": ["tabBar"],
|
||||
"single": true
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "TextClock",
|
||||
"attrs": [
|
||||
"format", "onDateChange", "status", "fontColor",
|
||||
"format", "onDateChange", "fontColor",
|
||||
"fontSize", "fontStyle", "fontWeight", "fontFamily"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"name": "Web",
|
||||
"atomic": true,
|
||||
"attrs": ["onPageFinish", "onRequestFocus", "javaScriptEnabled", "fileAccessEnabled"]
|
||||
"attrs": [
|
||||
"password", "cacheMode", "tableData", "wideViewModeAccess", "overviewModeAccess", "textZoomAtio", "databaseAccess",
|
||||
"onRefreshAccessedHistory", "onUrlLoadIntercept", "onSslErrorReceive", "onRenderExited", "onFileSelectorShow",
|
||||
"onPageEnd", "onPageBegin", "onProgressChange", "onTitleReceive", "onGeolocationHide", "onGeolocationShow",
|
||||
"onRequestSelected", "javaScriptAccess", "fileAccess", "onAlert", "onBeforeUnload", "onlineImageAccess",
|
||||
"domStorageAccess", "imageAccess", "mixedMode", "zoomAccess", "geolocationAccess", "javaScriptProxy",
|
||||
"onConfirm", "onConsole", "onErrorReceive", "onHttpErrorReceive", "onDownloadStart"
|
||||
]
|
||||
}
|
||||
+2
-1
@@ -73,6 +73,7 @@ function loadEntryObj(projectConfig) {
|
||||
const jsonString = fs.readFileSync(projectConfig.manifestFilePath).toString();
|
||||
manifest = JSON.parse(jsonString);
|
||||
} else if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) {
|
||||
process.env.compileMode = 'moduleJson';
|
||||
buildManifest(manifest, projectConfig.aceModuleJsonPath);
|
||||
} else {
|
||||
throw Error('\u001b[31m ERROR: the manifest file ' + projectConfig.manifestFilePath +
|
||||
@@ -115,7 +116,7 @@ function buildManifest(manifest, aceConfigPath) {
|
||||
function getPages(configJson) {
|
||||
const pages = []
|
||||
const modulePagePath = path.resolve(projectConfig.aceProfilePath,
|
||||
`${configJson.module.pages.replace(/\@profile\:/, '')}.json`);
|
||||
`${configJson.module.pages.replace(/\$profile\:/, '')}.json`);
|
||||
if (fs.existsSync(modulePagePath)) {
|
||||
const pagesConfig = JSON.parse(fs.readFileSync(modulePagePath, 'utf-8'));
|
||||
if (pagesConfig && pagesConfig.src) {
|
||||
|
||||
@@ -57,7 +57,7 @@ function handlePluginCompileComponent(jsonData) {
|
||||
const newSource = ts.factory.updateSourceFile(sourceNode, previewStatements);
|
||||
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
||||
const result = printer.printNode(ts.EmitHint.Unspecified, newSource, newSource);
|
||||
receivedMsg.data.script = result;
|
||||
receivedMsg.data.script = ts.transpileModule(result, {}).outputText;
|
||||
if (pluginSocket.readyState === WebSocket.OPEN){
|
||||
responseToPlugin(receivedMsg);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export class ResultStates {
|
||||
}
|
||||
);
|
||||
|
||||
compilation.hooks.buildModule.tap("findModule", (module) => {
|
||||
compilation.hooks.buildModule.tap('findModule', (module) => {
|
||||
if (/node_modules/.test(module.context)) {
|
||||
const modulePath: string =
|
||||
path.resolve(module.resourceResolveData.descriptionFileRoot, MODULE_SHARE_PATH);
|
||||
@@ -113,7 +113,7 @@ export class ResultStates {
|
||||
compilation.hooks.processAssets.tap(
|
||||
{
|
||||
name: 'GLOBAL_COMMON_MODULE_CACHE',
|
||||
stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
|
||||
stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
|
||||
},
|
||||
(assets) => {
|
||||
if (assets['commons.js']) {
|
||||
@@ -133,7 +133,7 @@ export class ResultStates {
|
||||
`globalThis["__common_module_cache__"][moduleId]: null;\n` +
|
||||
`if (commonCachedModule) { return commonCachedModule.exports; }\n` +
|
||||
source.replace('// Execute the module function',
|
||||
`if (globalThis["__common_module_cache__"] && moduleId.indexOf("?name=") < 0 && ` +
|
||||
`if (globalThis["__common_module_cache__"] && moduleId.indexOf("?name=") < 0 && ` +
|
||||
`Object.keys(globalThis["__common_module_cache__"]).indexOf(moduleId) >= 0) {\n` +
|
||||
` globalThis["__common_module_cache__"][moduleId] = module;\n}`);
|
||||
});
|
||||
@@ -157,12 +157,12 @@ export class ResultStates {
|
||||
compiler.hooks.compilation.tap('Collect Components And Modules', compilation => {
|
||||
compilation.hooks.additionalAssets.tapAsync('Collect Components And Modules', callback => {
|
||||
compilation.assets['./component_collection.txt'] =
|
||||
new RawSource(Array.from(appComponentCollection).join(","));
|
||||
new RawSource(Array.from(appComponentCollection).join(','));
|
||||
compilation.assets['./module_collection.txt'] =
|
||||
new RawSource(moduleCollection.size === 0 ? 'NULL' : Array.from(moduleCollection).join(","));
|
||||
new RawSource(moduleCollection.size === 0 ? 'NULL' : Array.from(moduleCollection).join(','));
|
||||
callback();
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ export class ResultStates {
|
||||
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)?'\./;
|
||||
/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) ||
|
||||
|
||||
@@ -78,17 +78,22 @@ export interface ExtendParamterInterfance {
|
||||
export const EXTEND_ATTRIBUTE: Map<string, Set<ExtendParamterInterfance>> = 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',
|
||||
'PanGestureOption', 'CustomDialogController', 'Storage', 'Scroller', 'SwiperController',
|
||||
'TabsController', 'CalendarController', 'AbilityController', 'VideoController', 'WebController',
|
||||
'XComponentController', 'CanvasRenderingContext2D', 'CanvasGradient', 'ImageBitmap', 'ImageData',
|
||||
'Path2D', 'RenderingContextSettings', 'OffscreenCanvasRenderingContext2D', 'DatePickerDialog',
|
||||
'TextPickerDialog', 'AlertDialog', 'ActionSheet', 'PatternLockController'
|
||||
'TextPickerDialog', 'AlertDialog', 'ContextMenu', 'ActionSheet', 'PatternLockController'
|
||||
]);
|
||||
|
||||
export const NEEDPOP_COMPONENT: Set<string> = new Set(['Blank', 'Search']);
|
||||
|
||||
export const CUSTOM_BUILDER_PROPERTIES: Set<string> = new Set(['bindPopup', 'bindMenu', 'bindContextMenu', 'title',
|
||||
'menus', 'toolBar', 'tabBar']);
|
||||
|
||||
(function initComponent() {
|
||||
Object.keys(COMPONENT_MAP).forEach((componentName) => {
|
||||
INNER_COMPONENT_NAMES.add(componentName);
|
||||
|
||||
@@ -17,6 +17,7 @@ import path from 'path';
|
||||
|
||||
export const NATIVE_MODULE: Set<string> = new Set(
|
||||
['system.app', 'ohos.app', 'system.router', 'system.curves', 'ohos.curves', 'system.matrix4', 'ohos.matrix4']);
|
||||
export const VALIDATE_MODULE: string[] = ['application', 'util', 'screen'];
|
||||
export const SYSTEM_PLUGIN: string = 'system';
|
||||
export const OHOS_PLUGIN: string = 'ohos';
|
||||
|
||||
@@ -182,14 +183,18 @@ export const GEOMETRY_VIEW: string = 'GeometryView';
|
||||
export const MODULE_SHARE_PATH: string = 'src' + path.sep + 'ets' + path.sep + 'share';
|
||||
export const BUILD_SHARE_PATH: string = '../share';
|
||||
|
||||
export const CHILD: string = 'child';
|
||||
export const THIS: string = 'this';
|
||||
export const STYLES: string = 'Styles';
|
||||
export const VISUAL_STATE: string = 'visualState';
|
||||
export const VIEW_STACK_PROCESSOR: string = 'ViewStackProcessor';
|
||||
|
||||
export const BIND_POPUP: string = 'bindPopup';
|
||||
export const CHECKED: string = 'checked';
|
||||
export const RADIO: string = 'Radio';
|
||||
export const $$_VALUE: string = 'value';
|
||||
export const $$_CHANGE_EVENT: string = 'changeEvent';
|
||||
export const $$_THIS: string = '$$this';
|
||||
export const $$_NEW_VALUE: string = 'newValue';
|
||||
|
||||
export const INTERFACE_NAME_SUFFIX:string = '_Params';
|
||||
export const OBSERVED_PROPERTY_ABSTRACT:string = 'ObservedPropertyAbstract';
|
||||
|
||||
@@ -52,25 +52,25 @@ function preProcess(source: string): string {
|
||||
function parseVisual(resourcePath: string, content: string, log: LogInfo[]): string {
|
||||
if (componentCollection.entryComponent && projectConfig.aceSuperVisualPath) {
|
||||
const sourceFile: ts.SourceFile = ts.createSourceFile(resourcePath, content,
|
||||
ts.ScriptTarget.Latest, true, ts.ScrpitKint.TS);
|
||||
if (sourceFile.statments) {
|
||||
sourceFile.statments.forEach(statment => {
|
||||
content = parseStatment(statment, content, log, resourcePath);
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
||||
if (sourceFile.statements) {
|
||||
sourceFile.statements.forEach(statement => {
|
||||
content = parseStatement(statement, content, log, resourcePath);
|
||||
});
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
function parseStatment(statement: ts.Statement, content: string, log: LogInfo[],
|
||||
function parseStatement(statement: ts.Statement, content: string, log: LogInfo[],
|
||||
resourcePath: string): string {
|
||||
if (statement.kind === ts.SyntaxKind.ClassDeclaration &&
|
||||
statement.name && statement.name.getText() === componentCollection.entryComponent) {
|
||||
const visualPath: string = findVisualFile(resourcePath);
|
||||
if (visualPath && fs.existsSync(visualPath) && statement.members) {
|
||||
statement.members.forEach(member => {
|
||||
if (member.kind && member === ts.SyntaxKind.MethodDeclaration) {
|
||||
content = parseMember(member, content, log, visualPath)
|
||||
if (member.kind && member.kind === ts.SyntaxKind.MethodDeclaration) {
|
||||
content = parseMember(member, content, log, visualPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -108,7 +108,7 @@ function findVisualFile(filePath: string): string {
|
||||
|
||||
function getVisualContent(visualPath: string, log: LogInfo[], pos: number): string {
|
||||
const parseContent: any = genETS(fs.readFileSync(visualPath, 'utf-8'));
|
||||
if (parseContent && parseContent.errorType && parseContent.errorType != '') {
|
||||
if (parseContent && parseContent.errorType && parseContent.errorType !== '') {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: parseContent.message,
|
||||
@@ -118,4 +118,4 @@ function getVisualContent(visualPath: string, log: LogInfo[], pos: number): stri
|
||||
return parseContent ? parseContent.ets : null;
|
||||
}
|
||||
|
||||
module.exports = preProcess;
|
||||
module.exports = preProcess;
|
||||
|
||||
@@ -45,7 +45,6 @@ import {
|
||||
COMPONENT_TRANSITION_NAME,
|
||||
COMPONENT_DEBUGLINE_FUNCTION,
|
||||
ATTRIBUTE_STATESTYLES,
|
||||
CHILD,
|
||||
THIS,
|
||||
VISUAL_STATE,
|
||||
VIEW_STACK_PROCESSOR,
|
||||
@@ -53,7 +52,12 @@ import {
|
||||
$$_VALUE,
|
||||
$$_CHANGE_EVENT,
|
||||
$$_THIS,
|
||||
$$_NEW_VALUE
|
||||
$$_NEW_VALUE,
|
||||
CHECKED,
|
||||
RADIO,
|
||||
BUILDER_ATTR_NAME,
|
||||
BUILDER_ATTR_BIND,
|
||||
CUSTOM_DIALOG_CONTROLLER_BUILDER
|
||||
} from './pre_define';
|
||||
import {
|
||||
INNER_COMPONENT_NAMES,
|
||||
@@ -67,7 +71,8 @@ import {
|
||||
NEEDPOP_COMPONENT,
|
||||
INNER_STYLE_FUNCTION,
|
||||
GLOBAL_STYLE_FUNCTION,
|
||||
COMMON_ATTRS
|
||||
COMMON_ATTRS,
|
||||
CUSTOM_BUILDER_PROPERTIES
|
||||
} from './component_map';
|
||||
import { componentCollection } from './validate_ui_syntax';
|
||||
import { processCustomComponent } from './process_custom_component';
|
||||
@@ -169,15 +174,17 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
|
||||
break;
|
||||
case ComponentType.customComponent:
|
||||
if (index + 1 < array.length && ts.isBlock(array[index + 1])) {
|
||||
item = processBlockChange(item,
|
||||
array[index + 1] as ts.Block, log)
|
||||
if (processExpressionStatementChange(item, array[index + 1] as ts.Block, log)) {
|
||||
item = processExpressionStatementChange(item, array[index + 1] as ts.Block, log);
|
||||
}
|
||||
}
|
||||
processCustomComponent(item, newStatements, log);
|
||||
processCustomComponent(item as ts.ExpressionStatement, newStatements, log);
|
||||
break;
|
||||
case ComponentType.forEachComponent:
|
||||
processForEachComponent(item, newStatements, log);
|
||||
break;
|
||||
case ComponentType.customBuilderMethod || ComponentType.builderParamMethod:
|
||||
case ComponentType.customBuilderMethod:
|
||||
case ComponentType.builderParamMethod:
|
||||
newStatements.push(item);
|
||||
break;
|
||||
}
|
||||
@@ -195,28 +202,47 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
|
||||
}
|
||||
}
|
||||
|
||||
function processBlockChange(node: ts.ExpressionStatement, nextNode: ts.Block,
|
||||
log: LogInfo[]): ts.block {
|
||||
function processExpressionStatementChange(node: ts.ExpressionStatement, nextNode: ts.Block,
|
||||
log: LogInfo[]): ts.ExpressionStatement {
|
||||
let name: string;
|
||||
// @ts-ignore
|
||||
if (node.expression.expression && ts.isIdentifier(node.expression.expression)) {
|
||||
name = node.expression.expression.escapedText.toString();
|
||||
}
|
||||
if (builderParamObjectCollection.get(name) &&
|
||||
builderParamObjectCollection.get(name).size === 1) {
|
||||
return processBlockToExpression(node, nextNode, log, name);
|
||||
} else {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: `In the trailing lambda case, '${name}' must have one and only one property decorated with `
|
||||
+ `@BuilderParam, and its @BuilderParam expects no parameter.`,
|
||||
pos: node.getStart()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function processBlockToExpression(node: ts.ExpressionStatement, nextNode: ts.Block,
|
||||
log: LogInfo[], name: string): ts.ExpressionStatement {
|
||||
const childParam: string = [...builderParamObjectCollection.get(name)].slice(-1)[0];
|
||||
const newBlock: ts.Block = processComponentBlock(nextNode, false, log);
|
||||
const arrowNode: ts.ArrowFunction = ts.factory.createArrowFunction(undefined, undefined,
|
||||
[], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), newBlock);
|
||||
const newPropertyAssignment:ts.PropertyAssignment = ts.factory.createPropertyAssignment(
|
||||
ts.factory.createIdentifier(CHILD), arrowNode);
|
||||
ts.factory.createIdentifier(childParam), arrowNode);
|
||||
// @ts-ignore
|
||||
let argumentsArray: ts.ObjectLiteralExpression[] = node.express.arguments;
|
||||
if (arguments && arguments.length < 1) {
|
||||
argumentsArray = [ts.factory.createObjectLiteralExpression([newPropertyAssignment], true)]
|
||||
let argumentsArray: ts.ObjectLiteralExpression[] = node.expression.arguments;
|
||||
if (argumentsArray && !argumentsArray.length) {
|
||||
argumentsArray = [ts.factory.createObjectLiteralExpression([newPropertyAssignment], true)];
|
||||
} else {
|
||||
// @ts-ignore
|
||||
argumentsArray = [ts.factory.createObjectLiteralExpression(
|
||||
// @ts-ignore
|
||||
node.express.arguments[0].properties.concat([newPropertyAssignment]), true)]
|
||||
node.expression.arguments[0].properties.concat([newPropertyAssignment]), true)];
|
||||
}
|
||||
// @ts-ignore
|
||||
node = ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression(node.expression,
|
||||
node = ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression(
|
||||
// @ts-ignore
|
||||
node.expression.expression, node.expression.expression,typeArguments, argumentsArray))
|
||||
node.expression, node.expression.expression, node.expression.expression.typeArguments,
|
||||
argumentsArray));
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -491,21 +517,31 @@ interface AnimationInfo {
|
||||
|
||||
export function bindComponentAttr(node: ts.ExpressionStatement, identifierNode: ts.Identifier,
|
||||
newStatements: ts.Statement[], log: LogInfo[], reverse: boolean = true,
|
||||
isStylesAttr: boolean = false): void {
|
||||
isStylesAttr: boolean = false, isGlobalStyles: boolean = false): void {
|
||||
let temp: any = node.expression;
|
||||
const statements: ts.Statement[] = [];
|
||||
const lastStatement: AnimationInfo = { statement: null, kind: false };
|
||||
while (temp && ts.isCallExpression(temp) && temp.expression) {
|
||||
if (temp.expression && (validatePropertyAccessExpressionWithCustomBuilder(temp.expression) ||
|
||||
validateIdentifierWithCustomBuilder(temp.expression))) {
|
||||
let propertyName: string = '';
|
||||
if (ts.isIdentifier(temp.expression)) {
|
||||
propertyName = temp.expression.escapedText.toString();
|
||||
} else if (ts.isPropertyAccessExpression(temp.expression)) {
|
||||
propertyName = temp.expression.name.escapedText.toString();
|
||||
}
|
||||
temp = propertyName === BIND_POPUP ? processBindPopupBuilder(temp) : processCustomBuilderProperty(temp);
|
||||
}
|
||||
if (ts.isPropertyAccessExpression(temp.expression) &&
|
||||
temp.expression.name && ts.isIdentifier(temp.expression.name)) {
|
||||
addComponentAttr(temp, temp.expression.name, lastStatement, statements, identifierNode, log,
|
||||
isStylesAttr);
|
||||
isStylesAttr, isGlobalStyles);
|
||||
temp = temp.expression.expression;
|
||||
} else if (ts.isIdentifier(temp.expression)) {
|
||||
if (!INNER_COMPONENT_NAMES.has(temp.expression.getText()) &&
|
||||
!GESTURE_TYPE_NAMES.has(temp.expression.getText())) {
|
||||
addComponentAttr(temp, temp.expression, lastStatement, statements, identifierNode, log,
|
||||
isStylesAttr);
|
||||
isStylesAttr, isGlobalStyles);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -518,7 +554,131 @@ export function bindComponentAttr(node: ts.ExpressionStatement, identifierNode:
|
||||
}
|
||||
}
|
||||
|
||||
function createArrowFunctionFor$$ ($$varExp: ts.Expression): ts.ArrowFunction {
|
||||
function processCustomBuilderProperty(node: ts.CallExpression): ts.CallExpression {
|
||||
const newArguments: ts.Expression[] = [];
|
||||
node.arguments.forEach((argument: ts.Expression | ts.Identifier, index: number) => {
|
||||
if (index === 0 && isBuilderChangeNode(argument)) {
|
||||
newArguments.push(parseBuilderNode(argument));
|
||||
} else {
|
||||
newArguments.push(argument);
|
||||
}
|
||||
});
|
||||
node = ts.factory.updateCallExpression(node, node.expression, node.typeArguments, newArguments);
|
||||
return node;
|
||||
}
|
||||
|
||||
function isBuilderChangeNode(argument: ts.Node): boolean {
|
||||
return (ts.isPropertyAccessExpression(argument) && argument.name && ts.isIdentifier(argument.name)
|
||||
&& CUSTOM_BUILDER_METHOD.has(argument.name.getText())) ||
|
||||
(ts.isCallExpression(argument) && argument.expression && argument.expression.name &&
|
||||
ts.isIdentifier(argument.expression.name) &&
|
||||
CUSTOM_BUILDER_METHOD.has(argument.expression.name.getText())) || (ts.isIdentifier(argument) &&
|
||||
argument.escapedText && CUSTOM_BUILDER_METHOD.has(argument.escapedText.toString()));
|
||||
}
|
||||
|
||||
function parseBuilderNode(node: ts.Node): ts.ObjectLiteralExpression {
|
||||
if (isPropertyAccessExpressionNode(node)) {
|
||||
return processPropertyBuilder(node as ts.PropertyAccessExpression);
|
||||
} else if (ts.isIdentifier(node) && CUSTOM_BUILDER_METHOD.has(node.escapedText.toString())) {
|
||||
return processIdentifierBuilder(node);
|
||||
} else if (ts.isCallExpression(node)) {
|
||||
return getParsedBuilderAttrArgumentWithParams(node);
|
||||
}
|
||||
}
|
||||
|
||||
function isPropertyAccessExpressionNode(node: ts.Node): boolean {
|
||||
return ts.isPropertyAccessExpression(node) && node.expression &&
|
||||
node.expression.kind === ts.SyntaxKind.ThisKeyword && node.name && ts.isIdentifier(node.name) &&
|
||||
CUSTOM_BUILDER_METHOD.has(node.name.escapedText.toString());
|
||||
}
|
||||
|
||||
function processBindPopupBuilder(node: ts.CallExpression): ts.CallExpression {
|
||||
const newArguments: ts.Expression[] = [];
|
||||
node.arguments.forEach((argument: ts.ObjectLiteralExpression, index: number) => {
|
||||
if (index === 1) {
|
||||
// @ts-ignore
|
||||
newArguments.push(processBindPopupBuilderProperty(argument));
|
||||
} else {
|
||||
newArguments.push(argument);
|
||||
}
|
||||
});
|
||||
node = ts.factory.updateCallExpression(node, node.expression, node.typeArguments, newArguments);
|
||||
return node;
|
||||
}
|
||||
|
||||
function processBindPopupBuilderProperty(node: ts.ObjectLiteralExpression): ts.ObjectLiteralExpression {
|
||||
const newProperties: ts.PropertyAssignment[] = [];
|
||||
node.properties.forEach((property: ts.PropertyAssignment, index: number) => {
|
||||
if (index === 0) {
|
||||
if (property.name && ts.isIdentifier(property.name) &&
|
||||
property.name.escapedText.toString() === CUSTOM_DIALOG_CONTROLLER_BUILDER) {
|
||||
newProperties.push(ts.factory.updatePropertyAssignment(property, property.name,
|
||||
parseBuilderNode(property.initializer)));
|
||||
} else {
|
||||
newProperties.push(property);
|
||||
}
|
||||
} else {
|
||||
newProperties.push(property);
|
||||
}
|
||||
});
|
||||
return ts.factory.updateObjectLiteralExpression(node, newProperties);
|
||||
}
|
||||
|
||||
function processPropertyBuilder(node: ts.PropertyAccessExpression): ts.ObjectLiteralExpression {
|
||||
return ts.factory.createObjectLiteralExpression([
|
||||
ts.factory.createPropertyAssignment(
|
||||
ts.factory.createIdentifier(BUILDER_ATTR_NAME),
|
||||
ts.factory.createCallExpression(
|
||||
ts.factory.createPropertyAccessExpression(
|
||||
node,
|
||||
ts.factory.createIdentifier(BUILDER_ATTR_BIND)
|
||||
),
|
||||
undefined,
|
||||
[ts.factory.createThis()]
|
||||
)
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
function processIdentifierBuilder(node: ts.Identifier): ts.ObjectLiteralExpression {
|
||||
return ts.factory.createObjectLiteralExpression([
|
||||
ts.factory.createPropertyAssignment(
|
||||
ts.factory.createIdentifier(BUILDER_ATTR_NAME),
|
||||
node
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
function getParsedBuilderAttrArgumentWithParams(node: ts.CallExpression):
|
||||
ts.ObjectLiteralExpression {
|
||||
return ts.factory.createObjectLiteralExpression([
|
||||
ts.factory.createPropertyAssignment(
|
||||
ts.factory.createIdentifier(BUILDER_ATTR_NAME),
|
||||
ts.factory.createArrowFunction(
|
||||
undefined,
|
||||
undefined,
|
||||
[],
|
||||
undefined,
|
||||
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
||||
ts.factory.createBlock(
|
||||
[ts.factory.createExpressionStatement(node)],
|
||||
true
|
||||
)
|
||||
)
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
function validatePropertyAccessExpressionWithCustomBuilder(node: ts.Node): boolean {
|
||||
return ts.isPropertyAccessExpression(node) && node.name &&
|
||||
ts.isIdentifier(node.name) && CUSTOM_BUILDER_PROPERTIES.has(node.name.escapedText.toString());
|
||||
}
|
||||
|
||||
function validateIdentifierWithCustomBuilder(node: ts.Node): boolean {
|
||||
return ts.isIdentifier(node) && CUSTOM_BUILDER_PROPERTIES.has(node.escapedText.toString());
|
||||
}
|
||||
|
||||
function createArrowFunctionFor$$($$varExp: ts.Expression): ts.ArrowFunction {
|
||||
return ts.factory.createArrowFunction(
|
||||
undefined, undefined,
|
||||
[ts.factory.createParameterDeclaration(
|
||||
@@ -541,8 +701,8 @@ function createArrowFunctionFor$$ ($$varExp: ts.Expression): ts.ArrowFunction {
|
||||
|
||||
function updateArgumentFor$$(argument: any): ts.Expression {
|
||||
if (ts.isElementAccessExpression(argument)) {
|
||||
return ts.factory.updateElementAccessExpression
|
||||
(argument, updateArgumentFor$$(argument.expression), argument.argumentExpression);
|
||||
return ts.factory.updateElementAccessExpression(
|
||||
argument, updateArgumentFor$$(argument.expression), argument.argumentExpression);
|
||||
} else if (ts.isIdentifier(argument)) {
|
||||
props.push(argument.getText());
|
||||
if (argument.getText() === $$_THIS) {
|
||||
@@ -551,14 +711,14 @@ function updateArgumentFor$$(argument: any): ts.Expression {
|
||||
return ts.factory.createIdentifier(argument.getText().replace(/\$\$/, ''));
|
||||
}
|
||||
} else if (ts.isPropertyAccessExpression(argument)) {
|
||||
return ts.factory.updatePropertyAccessExpression
|
||||
(argument, updateArgumentFor$$(argument.expression), argument.name);
|
||||
return ts.factory.updatePropertyAccessExpression(
|
||||
argument, updateArgumentFor$$(argument.expression), argument.name);
|
||||
}
|
||||
}
|
||||
|
||||
function addComponentAttr(temp: any, node: ts.Identifier, lastStatement: any,
|
||||
statements: ts.Statement[], identifierNode: ts.Identifier, log: LogInfo[],
|
||||
isStylesAttr: boolean): void {
|
||||
isStylesAttr: boolean, isGlobalStyles: boolean): void {
|
||||
const propName: string = node.getText();
|
||||
if (propName === ATTRIBUTE_ANIMATION) {
|
||||
if (!lastStatement.statement) {
|
||||
@@ -595,15 +755,18 @@ function addComponentAttr(temp: any, node: ts.Identifier, lastStatement: any,
|
||||
} else if (GLOBAL_STYLE_FUNCTION.has(propName) || INNER_STYLE_FUNCTION.has(propName)) {
|
||||
const styleBlock: ts.Block =
|
||||
GLOBAL_STYLE_FUNCTION.get(propName) || INNER_STYLE_FUNCTION.get(propName);
|
||||
bindComponentAttr(styleBlock.statements[0] as ts.ExpressionStatement, identifierNode,
|
||||
statements, log, false, true);
|
||||
if (GLOBAL_STYLE_FUNCTION.has(propName)) {
|
||||
bindComponentAttr(styleBlock.statements[0] as ts.ExpressionStatement, identifierNode,
|
||||
statements, log, false, true, true);
|
||||
} else {
|
||||
bindComponentAttr(styleBlock.statements[0] as ts.ExpressionStatement, identifierNode,
|
||||
statements, log, false, true, false);
|
||||
}
|
||||
lastStatement.kind = true;
|
||||
} else if (propName === BIND_POPUP && temp.arguments.length === 2 &&
|
||||
temp.arguments[0].getText().match(/^\$\$(.|\n)+/)) {
|
||||
} else if (!isStylesAttr && [BIND_POPUP, CHECKED].includes(propName) &&
|
||||
temp.arguments.length && temp.arguments[0] && temp.arguments[0].getText().match(/^\$\$(.|\n)+/)) {
|
||||
const argumentsArr: ts.Expression[] = [];
|
||||
const varExp: ts.Expression = updateArgumentFor$$(temp.arguments[0]);
|
||||
argumentsArr.push(generateObjectFor$$(varExp));
|
||||
argumentsArr.push(temp.arguments[1]);
|
||||
classifyArgumentsNum(temp.arguments, argumentsArr, propName, identifierNode);
|
||||
statements.push(ts.factory.createExpressionStatement(
|
||||
createFunction(identifierNode, node, argumentsArr)));
|
||||
lastStatement.kind = true;
|
||||
@@ -612,8 +775,10 @@ function addComponentAttr(temp: any, node: ts.Identifier, lastStatement: any,
|
||||
if (!COMMON_ATTRS.has(propName)) {
|
||||
validateStateStyleSyntax(temp, log);
|
||||
}
|
||||
for (let i=0; i<temp.arguments.length; i++) {
|
||||
temp.arguments[i] = traverseStylesAttr(temp.arguments[i]);
|
||||
if (isGlobalStyles) {
|
||||
for (let i = 0; i < temp.arguments.length; i++) {
|
||||
temp.arguments[i] = traverseStylesAttr(temp.arguments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
statements.push(ts.factory.createExpressionStatement(
|
||||
@@ -622,6 +787,17 @@ function addComponentAttr(temp: any, node: ts.Identifier, lastStatement: any,
|
||||
}
|
||||
}
|
||||
|
||||
function classifyArgumentsNum(args: any, argumentsArr: ts.Expression[], propName: string,
|
||||
identifierNode: ts.Identifier): void {
|
||||
if (propName === BIND_POPUP && args.length === 2) {
|
||||
const varExp: ts.Expression = updateArgumentFor$$(args[0]);
|
||||
argumentsArr.push(generateObjectFor$$(varExp), args[1]);
|
||||
} else if (propName === CHECKED && args.length === 1 && identifierNode.getText() === RADIO) {
|
||||
const varExp: ts.Expression = updateArgumentFor$$(args[0]);
|
||||
argumentsArr.push(varExp, createArrowFunctionFor$$(varExp));
|
||||
}
|
||||
}
|
||||
|
||||
function traverseStylesAttr(node: ts.Node): ts.Node {
|
||||
if (ts.isStringLiteral(node)) {
|
||||
node = ts.factory.createStringLiteral(node.text);
|
||||
@@ -679,15 +855,15 @@ function traverseStateStylesAttr(temp: any, statements: ts.Statement[],
|
||||
} else if (ts.isObjectLiteralExpression(item.initializer) &&
|
||||
item.initializer.properties.length === 1 &&
|
||||
ts.isPropertyAssignment(item.initializer.properties[0])) {
|
||||
bindComponentAttr(ts.factory.createExpressionStatement
|
||||
(item.initializer.properties[0].initializer), identifierNode, statements, log, false, true);
|
||||
bindComponentAttr(ts.factory.createExpressionStatement(
|
||||
item.initializer.properties[0].initializer), identifierNode, statements, log, false, true);
|
||||
} else {
|
||||
validateStateStyleSyntax(temp, log);
|
||||
}
|
||||
if (item.name) {
|
||||
statements.push(createViewStackProcessor(item, false));
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function isExtendFunctionNode(identifierNode: ts.Identifier, propName: string): boolean {
|
||||
@@ -808,8 +984,8 @@ export function isAttributeNode(node: ts.ExpressionStatement): boolean {
|
||||
function validateFirstNode(node: ts.Statement): boolean {
|
||||
const isEntryComponent: boolean =
|
||||
componentCollection.entryComponent === componentCollection.currentClassName;
|
||||
if ((isEntryComponent && validateEntryComponent(node)) ||
|
||||
(!isEntryComponent && validateCustomComponent(node))) {
|
||||
if (isEntryComponent && validateEntryComponent(node) ||
|
||||
!isEntryComponent && validateCustomComponent(node)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -824,8 +1000,8 @@ function validateEntryComponent(node: ts.Statement): boolean {
|
||||
|
||||
function validateCustomComponent(node: ts.Statement): boolean {
|
||||
if (ts.isIfStatement(node) ||
|
||||
(ts.isExpressionStatement(node) && (INNER_COMPONENT_NAMES.has(getName(node)) ||
|
||||
componentCollection.customComponents.has(getName(node))))) {
|
||||
ts.isExpressionStatement(node) && (INNER_COMPONENT_NAMES.has(getName(node)) ||
|
||||
componentCollection.customComponents.has(getName(node)))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -864,10 +1040,10 @@ function getComponentType(node: ts.ExpressionStatement, log: LogInfo[],
|
||||
return ComponentType.forEachComponent;
|
||||
} else if (CUSTOM_BUILDER_METHOD.has(name)) {
|
||||
return ComponentType.customBuilderMethod;
|
||||
} else if (builderParamObjectCollection.get(componentCollection.currentClassName) &&
|
||||
} else if (builderParamObjectCollection.get(componentCollection.currentClassName) &&
|
||||
builderParamObjectCollection.get(componentCollection.currentClassName).has(name)) {
|
||||
return ComponentType.builderParamMethod;
|
||||
}else if (!isAttributeNode(node)) {
|
||||
} else if (!isAttributeNode(node)) {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: `'${node.getText()}' does not meet UI component syntax.`,
|
||||
|
||||
@@ -16,6 +16,19 @@
|
||||
import ts from 'typescript';
|
||||
|
||||
import {
|
||||
COMPONENT_STATE_DECORATOR,
|
||||
COMPONENT_PROVIDE_DECORATOR,
|
||||
COMPONENT_LINK_DECORATOR,
|
||||
COMPONENT_PROP_DECORATOR,
|
||||
COMPONENT_STORAGE_LINK_DECORATOR,
|
||||
COMPONENT_STORAGE_PROP_DECORATOR,
|
||||
COMPONENT_OBJECT_LINK_DECORATOR,
|
||||
COMPONENT_CONSUME_DECORATOR,
|
||||
SYNCHED_PROPERTY_NESED_OBJECT,
|
||||
SYNCHED_PROPERTY_SIMPLE_TWO_WAY,
|
||||
SYNCHED_PROPERTY_SIMPLE_ONE_WAY,
|
||||
OBSERVED_PROPERTY_OBJECT,
|
||||
OBSERVED_PROPERTY_SIMPLE,
|
||||
COMPONENT_BUILD_FUNCTION,
|
||||
BASE_COMPONENT_NAME,
|
||||
ATTRIBUTE_ANIMATETO,
|
||||
@@ -34,16 +47,16 @@ import {
|
||||
COMPONENT_TRANSITION_FUNCTION,
|
||||
COMPONENT_CREATE_FUNCTION,
|
||||
GEOMETRY_VIEW,
|
||||
BUILDER_ATTR_NAME,
|
||||
BUILDER_ATTR_BIND,
|
||||
COMPONENT_STYLES_DECORATOR,
|
||||
STYLES,
|
||||
CUSTOM_COMPONENT_EARLIER_CREATE_CHILD
|
||||
INTERFACE_NAME_SUFFIX,
|
||||
OBSERVED_PROPERTY_ABSTRACT
|
||||
} from './pre_define';
|
||||
import {
|
||||
BUILDIN_STYLE_NAMES,
|
||||
CUSTOM_BUILDER_METHOD,
|
||||
INNER_STYLE_FUNCTION,
|
||||
INTERFACE_NODE_SET,
|
||||
STYLES_ATTRIBUTE
|
||||
} from './component_map';
|
||||
import {
|
||||
@@ -60,7 +73,8 @@ import {
|
||||
UpdateResult,
|
||||
stateObjectCollection,
|
||||
curPropMap,
|
||||
decoratorParamSet
|
||||
decoratorParamSet,
|
||||
isSimpleType
|
||||
} from './process_component_member';
|
||||
import {
|
||||
processComponentBuild,
|
||||
@@ -109,11 +123,14 @@ function processMembers(members: ts.NodeArray<ts.ClassElement>, parentComponentN
|
||||
const deleteParamsStatements: ts.PropertyDeclaration[] = [];
|
||||
const checkController: ControllerType =
|
||||
{ hasController: !componentCollection.customDialogs.has(parentComponentName.getText()) };
|
||||
const interfaceNode = ts.factory.createInterfaceDeclaration(undefined, undefined,
|
||||
parentComponentName.getText() + INTERFACE_NAME_SUFFIX, undefined, undefined, []);
|
||||
members.forEach((item: ts.ClassElement) => {
|
||||
let updateItem: ts.ClassElement;
|
||||
if (ts.isPropertyDeclaration(item)) {
|
||||
addPropertyMember(item, newMembers, program);
|
||||
const result: UpdateResult = processMemberVariableDecorators(parentComponentName, item,
|
||||
ctorNode, watchMap, checkController, log, program, context, hasPreview);
|
||||
ctorNode, watchMap, checkController, log, program, context, hasPreview, interfaceNode);
|
||||
if (result.isItemUpdate()) {
|
||||
updateItem = result.getProperity();
|
||||
} else {
|
||||
@@ -146,14 +163,74 @@ function processMembers(members: ts.NodeArray<ts.ClassElement>, parentComponentN
|
||||
newMembers.push(updateItem);
|
||||
}
|
||||
});
|
||||
INTERFACE_NODE_SET.add(interfaceNode);
|
||||
validateBuildMethodCount(buildCount, parentComponentName, log);
|
||||
validateHasController(parentComponentName, checkController, log);
|
||||
newMembers.unshift(addDeleteParamsFunc(deleteParamsStatements));
|
||||
newMembers.unshift(addUpdateParamsFunc(updateParamsStatements));
|
||||
newMembers.unshift(addConstructor(ctorNode, watchMap));
|
||||
newMembers.unshift(addUpdateParamsFunc(updateParamsStatements, parentComponentName));
|
||||
newMembers.unshift(addConstructor(ctorNode, watchMap, parentComponentName));
|
||||
return newMembers;
|
||||
}
|
||||
|
||||
function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[],
|
||||
program: ts.Program):void {
|
||||
const propertyItem: ts.PropertyDeclaration = item as ts.PropertyDeclaration;
|
||||
let decoratorName: string;
|
||||
let updatePropertyItem: ts.PropertyDeclaration;
|
||||
const type: ts.TypeNode = propertyItem.type;
|
||||
if (!propertyItem.decorators || propertyItem.decorators.length === 0) {
|
||||
updatePropertyItem = createPropertyDeclaration(propertyItem, type, true);
|
||||
newMembers.push(updatePropertyItem);
|
||||
} else if (propertyItem.decorators) {
|
||||
for (let i = 0; i < propertyItem.decorators.length; i++) {
|
||||
let newType: ts.TypeNode;
|
||||
decoratorName = propertyItem.decorators[i].getText().replace(/\(.*\)$/, '').trim();
|
||||
switch (decoratorName) {
|
||||
case COMPONENT_STATE_DECORATOR:
|
||||
case COMPONENT_PROVIDE_DECORATOR:
|
||||
newType = ts.factory.createTypeReferenceNode(isSimpleType(type, program) ?
|
||||
OBSERVED_PROPERTY_SIMPLE : OBSERVED_PROPERTY_OBJECT, [type]);
|
||||
break;
|
||||
case COMPONENT_LINK_DECORATOR:
|
||||
case COMPONENT_CONSUME_DECORATOR:
|
||||
newType = ts.factory.createTypeReferenceNode(isSimpleType(type, program) ?
|
||||
SYNCHED_PROPERTY_SIMPLE_TWO_WAY : SYNCHED_PROPERTY_SIMPLE_ONE_WAY, [type]);
|
||||
break;
|
||||
case COMPONENT_PROP_DECORATOR:
|
||||
newType = ts.factory.createTypeReferenceNode(SYNCHED_PROPERTY_SIMPLE_ONE_WAY, [type]);
|
||||
break;
|
||||
case COMPONENT_OBJECT_LINK_DECORATOR:
|
||||
newType = ts.factory.createTypeReferenceNode(SYNCHED_PROPERTY_NESED_OBJECT, [type]);
|
||||
break;
|
||||
case COMPONENT_STORAGE_PROP_DECORATOR:
|
||||
case COMPONENT_STORAGE_LINK_DECORATOR:
|
||||
newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [type]);
|
||||
break;
|
||||
}
|
||||
updatePropertyItem = createPropertyDeclaration(propertyItem, newType, false);
|
||||
if (updatePropertyItem) {
|
||||
newMembers.push(updatePropertyItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createPropertyDeclaration(propertyItem: ts.PropertyDeclaration, newType: ts.TypeNode | undefined,
|
||||
normalVar: boolean): ts.PropertyDeclaration {
|
||||
if (typeof newType === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
let prefix: string = '';
|
||||
if (!normalVar) {
|
||||
prefix = '__';
|
||||
}
|
||||
const privateM: ts.ModifierToken<ts.SyntaxKind.PrivateKeyword> =
|
||||
ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword);
|
||||
return ts.factory.updatePropertyDeclaration(propertyItem, undefined,
|
||||
propertyItem.modifiers || [privateM], prefix + propertyItem.name.getText(),
|
||||
propertyItem.questionToken, newType, undefined);
|
||||
}
|
||||
|
||||
function processComponentMethod(node: ts.MethodDeclaration, parentComponentName: ts.Identifier,
|
||||
context: ts.TransformationContext, log: LogInfo[], buildCount: BuildCount): ts.MethodDeclaration {
|
||||
let updateItem: ts.MethodDeclaration = node;
|
||||
@@ -212,9 +289,6 @@ function processBuildMember(node: ts.MethodDeclaration, context: ts.Transformati
|
||||
const buildNode: ts.MethodDeclaration = processComponentBuild(node, log);
|
||||
return ts.visitNode(buildNode, visitBuild);
|
||||
function visitBuild(node: ts.Node): ts.Node {
|
||||
if (isCustomComponentNode(node)) {
|
||||
return node;
|
||||
}
|
||||
if (isGeometryView(node)) {
|
||||
node = processGeometryView(node as ts.ExpressionStatement, log);
|
||||
}
|
||||
@@ -229,80 +303,10 @@ function processBuildMember(node: ts.MethodDeclaration, context: ts.Transformati
|
||||
ts.factory.createIdentifier(FOREACH_OBSERVED_OBJECT),
|
||||
ts.factory.createIdentifier(FOREACH_GET_RAW_OBJECT)), undefined, [node]);
|
||||
}
|
||||
if ((ts.isIdentifier(node) || ts.isPropertyAccessExpression(node)) &&
|
||||
validateBuilderFunctionNode(node)) {
|
||||
return getParsedBuilderAttrArgument(node);
|
||||
}
|
||||
return ts.visitEachChild(node, visitBuild, context);
|
||||
}
|
||||
}
|
||||
|
||||
function validateBuilderFunctionNode(node: ts.PropertyAccessExpression | ts.Identifier): boolean {
|
||||
if (((ts.isPropertyAccessExpression(node) && node.expression && node.name &&
|
||||
node.expression.kind === ts.SyntaxKind.ThisKeyword && ts.isIdentifier(node.name) &&
|
||||
CUSTOM_BUILDER_METHOD.has(node.name.escapedText.toString())) ||
|
||||
ts.isIdentifier(node) && CUSTOM_BUILDER_METHOD.has(node.escapedText.toString())) &&
|
||||
!((ts.isPropertyAccessExpression(node) && validateBuilderParam(node)) ||
|
||||
(ts.isIdentifier(node) && node.parent && ts.isPropertyAccessExpression(node.parent) &&
|
||||
validateBuilderParam(node.parent)))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function validateBuilderParam(node: ts.PropertyAccessExpression): boolean {
|
||||
if (node.parent && ts.isCallExpression(node.parent) && node.parent.expression === node) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getParsedBuilderAttrArgument(node: ts.PropertyAccessExpression | ts.Identifier):
|
||||
ts.ObjectLiteralExpression {
|
||||
let newObjectNode: ts.ObjectLiteralExpression = null;
|
||||
if (ts.isPropertyAccessExpression(node)) {
|
||||
newObjectNode = ts.factory.createObjectLiteralExpression([
|
||||
ts.factory.createPropertyAssignment(
|
||||
ts.factory.createIdentifier(BUILDER_ATTR_NAME),
|
||||
ts.factory.createCallExpression(
|
||||
ts.factory.createPropertyAccessExpression(
|
||||
node,
|
||||
ts.factory.createIdentifier(BUILDER_ATTR_BIND)
|
||||
),
|
||||
undefined,
|
||||
[ts.factory.createThis()]
|
||||
)
|
||||
)
|
||||
]);
|
||||
} else if (ts.isIdentifier(node)) {
|
||||
newObjectNode = ts.factory.createObjectLiteralExpression([
|
||||
ts.factory.createPropertyAssignment(
|
||||
ts.factory.createIdentifier(BUILDER_ATTR_NAME),
|
||||
node
|
||||
)
|
||||
])
|
||||
}
|
||||
return newObjectNode;
|
||||
}
|
||||
|
||||
function isCustomComponentNode(node:ts.NewExpression | ts.ExpressionStatement): boolean {
|
||||
if ((ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.escapedText
|
||||
&& componentCollection.customComponents.has(node.expression.escapedText.toString())) ||
|
||||
// @ts-ignore
|
||||
(ts.isExpressionStatement(node) && node.expression && node.expression.expression &&
|
||||
// @ts-ignore
|
||||
node.expression.expression.expression && node.expression.expression.expression.escapedText &&
|
||||
// @ts-ignore
|
||||
node.expression.expression.expression.escapedText.toString().startsWith(
|
||||
CUSTOM_COMPONENT_EARLIER_CREATE_CHILD))) {
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isGeometryView(node: ts.Node): boolean {
|
||||
if (ts.isExpressionStatement(node) && ts.isCallExpression(node.expression)) {
|
||||
const call: ts.CallExpression = node.expression;
|
||||
@@ -436,8 +440,9 @@ function processAnimateTo(node: ts.CallExpression): ts.CallExpression {
|
||||
node.typeArguments, node.arguments);
|
||||
}
|
||||
|
||||
function addUpdateParamsFunc(statements: ts.Statement[]): ts.MethodDeclaration {
|
||||
return createParamsInitBlock(COMPONENT_CONSTRUCTOR_UPDATE_PARAMS, statements);
|
||||
function addUpdateParamsFunc(statements: ts.Statement[], parentComponentName: ts.Identifier):
|
||||
ts.MethodDeclaration {
|
||||
return createParamsInitBlock(COMPONENT_CONSTRUCTOR_UPDATE_PARAMS, statements, parentComponentName);
|
||||
}
|
||||
|
||||
function addDeleteParamsFunc(statements: ts.PropertyDeclaration[]): ts.MethodDeclaration {
|
||||
@@ -467,13 +472,17 @@ function addDeleteParamsFunc(statements: ts.PropertyDeclaration[]): ts.MethodDec
|
||||
return deleteParamsMethod;
|
||||
}
|
||||
|
||||
function createParamsInitBlock(express: string, statements: ts.Statement[]): ts.MethodDeclaration {
|
||||
function createParamsInitBlock(express: string, statements: ts.Statement[],
|
||||
parentComponentName?: ts.Identifier): ts.MethodDeclaration {
|
||||
const methodDeclaration: ts.MethodDeclaration = ts.factory.createMethodDeclaration(undefined,
|
||||
undefined, undefined, ts.factory.createIdentifier(express), undefined, undefined,
|
||||
[ts.factory.createParameterDeclaration(undefined, undefined, undefined,
|
||||
express === COMPONENT_CONSTRUCTOR_DELETE_PARAMS ? undefined :
|
||||
ts.factory.createIdentifier(CREATE_CONSTRUCTOR_PARAMS), undefined, undefined, undefined)],
|
||||
undefined, ts.factory.createBlock(statements, true));
|
||||
ts.factory.createIdentifier(CREATE_CONSTRUCTOR_PARAMS), undefined,
|
||||
express === COMPONENT_CONSTRUCTOR_DELETE_PARAMS ? undefined :
|
||||
ts.factory.createTypeReferenceNode(
|
||||
ts.factory.createIdentifier(parentComponentName.getText() + INTERFACE_NAME_SUFFIX), undefined),
|
||||
undefined)], undefined, ts.factory.createBlock(statements, true));
|
||||
return methodDeclaration;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ import {
|
||||
COMPONENT_CONSTRUCTOR_PARENT,
|
||||
COMPONENT_CONSTRUCTOR_PARAMS,
|
||||
COMPONENT_CONSTRUCTOR_UPDATE_PARAMS,
|
||||
COMPONENT_WATCH_FUNCTION
|
||||
COMPONENT_WATCH_FUNCTION,
|
||||
BASE_COMPONENT_NAME,
|
||||
INTERFACE_NAME_SUFFIX
|
||||
} from './pre_define';
|
||||
|
||||
export function getInitConstructor(members: ts.NodeArray<ts.Node>): ts.ConstructorDeclaration {
|
||||
@@ -35,7 +37,8 @@ export function getInitConstructor(members: ts.NodeArray<ts.Node>): ts.Construct
|
||||
|
||||
export function updateConstructor(ctorNode: ts.ConstructorDeclaration,
|
||||
para: ts.ParameterDeclaration[], addStatements: ts.Statement[],
|
||||
isSuper: boolean = false): ts.ConstructorDeclaration {
|
||||
isSuper: boolean = false, isAdd: boolean = false, parentComponentName?: ts.Identifier):
|
||||
ts.ConstructorDeclaration {
|
||||
let modifyPara: ts.ParameterDeclaration[];
|
||||
if (para && para.length) {
|
||||
modifyPara = Array.from(ctorNode.parameters);
|
||||
@@ -55,15 +58,50 @@ 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, modifyPara || ctorNode.parameters,
|
||||
ts.factory.createBlock(modifyBody || ctorNode.body.statements, true));
|
||||
ctorNode.modifiers, ctorPara, ts.factory.createBlock(modifyBody || ctorNode.body.statements, true));
|
||||
}
|
||||
return ctorNode;
|
||||
}
|
||||
|
||||
export function addConstructor(ctorNode: any, watchMap: Map<string, ts.Node>)
|
||||
: ts.ConstructorDeclaration {
|
||||
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);
|
||||
});
|
||||
return newTSPara;
|
||||
}
|
||||
|
||||
export function addConstructor(ctorNode: any, watchMap: Map<string, ts.Node>,
|
||||
parentComponentName: ts.Identifier): ts.ConstructorDeclaration {
|
||||
const watchStatements: ts.ExpressionStatement[] = [];
|
||||
watchMap.forEach((value, key) => {
|
||||
const watchNode: ts.ExpressionStatement = ts.factory.createExpressionStatement(
|
||||
@@ -77,7 +115,7 @@ export function addConstructor(ctorNode: any, watchMap: Map<string, ts.Node>)
|
||||
ts.factory.createStringLiteral(key),
|
||||
ts.isStringLiteral(value) ?
|
||||
ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
|
||||
ts.factory.createIdentifier(value.text)) : value as ts.PropertyAccessExpression
|
||||
ts.factory.createIdentifier(value.text)) : value as ts.PropertyAccessExpression
|
||||
]
|
||||
));
|
||||
watchStatements.push(watchNode);
|
||||
@@ -91,5 +129,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);
|
||||
[updateWithValueParamsStatement, ...watchStatements], false, true, parentComponentName);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ export const setUpdateParamsDecorators: Set<string> =
|
||||
]);
|
||||
|
||||
export const immutableDecorators: Set<string> =
|
||||
new Set([COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR]);
|
||||
new Set([COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR, COMPONENT_BUILDERPARAM_DECORATOR]);
|
||||
|
||||
export const simpleTypes: Set<ts.SyntaxKind> = new Set([ts.SyntaxKind.StringKeyword,
|
||||
ts.SyntaxKind.NumberKeyword, ts.SyntaxKind.BooleanKeyword, ts.SyntaxKind.EnumDeclaration]);
|
||||
@@ -197,8 +197,8 @@ export const curPropMap: Map<string, string> = new Map();
|
||||
|
||||
export function processMemberVariableDecorators(parentName: ts.Identifier,
|
||||
item: ts.PropertyDeclaration, ctorNode: ts.ConstructorDeclaration, watchMap: Map<string, ts.Node>,
|
||||
checkController: ControllerType, log: LogInfo[], program: ts.Program,
|
||||
context: ts.TransformationContext, hasPreview: boolean): UpdateResult {
|
||||
checkController: ControllerType, log: LogInfo[], program: ts.Program, context: ts.TransformationContext,
|
||||
hasPreview: boolean, interfaceNode: ts.InterfaceDeclaration): UpdateResult {
|
||||
const updateResult: UpdateResult = new UpdateResult();
|
||||
const name: ts.Identifier = item.name as ts.Identifier;
|
||||
if (!item.decorators || !item.decorators.length) {
|
||||
@@ -206,14 +206,15 @@ export function processMemberVariableDecorators(parentName: ts.Identifier,
|
||||
updateResult.setProperity(undefined);
|
||||
updateResult.setUpdateParams(createUpdateParams(name, COMPONENT_NON_DECORATOR));
|
||||
updateResult.setCtor(updateConstructor(ctorNode, [], [
|
||||
createVariableInitStatement(item, COMPONENT_NON_DECORATOR, log, program, context, hasPreview)]));
|
||||
createVariableInitStatement(item, COMPONENT_NON_DECORATOR, log, program, context, hasPreview,
|
||||
interfaceNode)]));
|
||||
updateResult.setControllerSet(createControllerSet(item, parentName, name, checkController));
|
||||
} else if (!item.type) {
|
||||
validatePropertyNonType(name, log);
|
||||
return updateResult;
|
||||
} else {
|
||||
processPropertyNodeDecorator(parentName, item, updateResult, ctorNode, name, watchMap,
|
||||
log, program, context, hasPreview);
|
||||
log, program, context, hasPreview, interfaceNode);
|
||||
}
|
||||
return updateResult;
|
||||
}
|
||||
@@ -239,7 +240,8 @@ function createControllerSet(node: ts.PropertyDeclaration, componentName: ts.Ide
|
||||
function processPropertyNodeDecorator(parentName: ts.Identifier, node: ts.PropertyDeclaration,
|
||||
updateResult: UpdateResult, ctorNode: ts.ConstructorDeclaration, name: ts.Identifier,
|
||||
watchMap: Map<string, ts.Node>, log: LogInfo[], program: ts.Program,
|
||||
context: ts.TransformationContext, hasPreview: boolean): void {
|
||||
context: ts.TransformationContext, hasPreview: boolean, interfaceNode: ts.InterfaceDeclaration):
|
||||
void {
|
||||
let stateManagementDecoratorCount: number = 0;
|
||||
for (let i = 0; i < node.decorators.length; i++) {
|
||||
const decoratorName: string = node.decorators[i].getText().replace(/\(.*\)$/, '').trim();
|
||||
@@ -277,7 +279,8 @@ function processPropertyNodeDecorator(parentName: ts.Identifier, node: ts.Proper
|
||||
processWatch(node, node.decorators[i], watchMap, log);
|
||||
} else if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName)) {
|
||||
stateManagementDecoratorCount += 1;
|
||||
processStateDecorators(node, decoratorName, updateResult, ctorNode, log, program, context, hasPreview);
|
||||
processStateDecorators(node, decoratorName, updateResult, ctorNode, log, program, context,
|
||||
hasPreview, interfaceNode);
|
||||
}
|
||||
}
|
||||
if (stateManagementDecoratorCount > 1) {
|
||||
@@ -288,25 +291,28 @@ function processPropertyNodeDecorator(parentName: ts.Identifier, node: ts.Proper
|
||||
|
||||
function processStateDecorators(node: ts.PropertyDeclaration, decorator: string,
|
||||
updateResult: UpdateResult, ctorNode: ts.ConstructorDeclaration, log: LogInfo[],
|
||||
program: ts.Program, context: ts.TransformationContext, hasPreview:boolean): void {
|
||||
program: ts.Program, context: ts.TransformationContext, hasPreview:boolean,
|
||||
interfaceNode: ts.InterfaceDeclaration): void {
|
||||
const name: ts.Identifier = node.name as ts.Identifier;
|
||||
updateResult.setProperity(undefined);
|
||||
const updateState: ts.Statement[] = [];
|
||||
const variableInitStatement: ts.Statement =
|
||||
createVariableInitStatement(node, decorator, log, program, context, hasPreview);
|
||||
createVariableInitStatement(node, decorator, log, program, context, hasPreview, interfaceNode);
|
||||
if (variableInitStatement) {
|
||||
updateState.push(variableInitStatement);
|
||||
}
|
||||
addAddProvidedVar(node, name, decorator, updateState);
|
||||
updateResult.setCtor(updateConstructor(ctorNode, [], [...updateState], false));
|
||||
updateResult.setVariableGet(createGetAccessor(name, CREATE_GET_METHOD));
|
||||
if (decorator !== COMPONENT_BUILDERPARAM_DECORATOR) {
|
||||
updateResult.setVariableGet(createGetAccessor(name, CREATE_GET_METHOD));
|
||||
updateResult.setDeleteParams(true);
|
||||
}
|
||||
if (!immutableDecorators.has(decorator)) {
|
||||
updateResult.setVariableSet(createSetAccessor(name, CREATE_SET_METHOD));
|
||||
updateResult.setVariableSet(createSetAccessor(name, CREATE_SET_METHOD, node.type));
|
||||
}
|
||||
if (setUpdateParamsDecorators.has(decorator)) {
|
||||
updateResult.setUpdateParams(createUpdateParams(name, decorator));
|
||||
}
|
||||
updateResult.setDeleteParams(true);
|
||||
}
|
||||
|
||||
function processWatch(node: ts.PropertyDeclaration, decorator: ts.Decorator,
|
||||
@@ -344,8 +350,8 @@ function processWatch(node: ts.PropertyDeclaration, decorator: ts.Decorator,
|
||||
}
|
||||
|
||||
function createVariableInitStatement(node: ts.PropertyDeclaration, decorator: string,
|
||||
log: LogInfo[], program: ts.Program, context: ts.TransformationContext, hasPreview: boolean):
|
||||
ts.Statement {
|
||||
log: LogInfo[], program: ts.Program, context: ts.TransformationContext, hasPreview: boolean,
|
||||
interfaceNode: ts.InterfaceDeclaration): ts.Statement {
|
||||
const name: ts.Identifier = node.name as ts.Identifier;
|
||||
let type: ts.TypeNode;
|
||||
let updateState: ts.ExpressionStatement;
|
||||
@@ -382,6 +388,12 @@ function createVariableInitStatement(node: ts.PropertyDeclaration, decorator: st
|
||||
updateState = updateConsumeProperty(node, name);
|
||||
break;
|
||||
}
|
||||
const members = interfaceNode.members;
|
||||
members.push(ts.factory.createPropertySignature(undefined, name,
|
||||
ts.factory.createToken(ts.SyntaxKind.QuestionToken), type));
|
||||
interfaceNode = ts.factory.updateInterfaceDeclaration(interfaceNode, undefined,
|
||||
interfaceNode.modifiers, interfaceNode.name, interfaceNode.typeParameters,
|
||||
interfaceNode.heritageClauses, members);
|
||||
return updateState;
|
||||
}
|
||||
|
||||
@@ -417,9 +429,9 @@ function createUpdateParams(name: ts.Identifier, decorator: string): ts.Statemen
|
||||
builderParamObjectCollection.set(componentCollection.currentClassName, new Set([]));
|
||||
}
|
||||
builderParamObjectCollection.get(componentCollection.currentClassName)
|
||||
.add(name.escapedText.toString())
|
||||
.add(name.escapedText.toString());
|
||||
}
|
||||
updateParamsNode = createUpdateParamsWithoutIf(name, 1);
|
||||
updateParamsNode = createUpdateParamsWithoutIf(name);
|
||||
break;
|
||||
}
|
||||
return updateParamsNode;
|
||||
@@ -435,15 +447,9 @@ function createUpdateParamsWithIf(name: ts.Identifier): ts.IfStatement {
|
||||
createUpdateParamsWithoutIf(name)], true), undefined);
|
||||
}
|
||||
|
||||
function createUpdateParamsWithoutIf(name: ts.Identifier, isAdd: number = 0): ts.ExpressionStatement {
|
||||
let textName: string;
|
||||
if (isAdd) {
|
||||
textName = `__${name.getText()}`;
|
||||
} else {
|
||||
textName = name.getText();
|
||||
}
|
||||
function createUpdateParamsWithoutIf(name: ts.Identifier): ts.ExpressionStatement {
|
||||
return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(
|
||||
createPropertyAccessExpressionWithThis(textName),
|
||||
createPropertyAccessExpressionWithThis(name.getText()),
|
||||
ts.factory.createToken(ts.SyntaxKind.EqualsToken),
|
||||
createPropertyAccessExpressionWithParams(name.getText())));
|
||||
}
|
||||
@@ -711,11 +717,12 @@ function createGetAccessor(item: ts.Identifier, express: string): ts.GetAccessor
|
||||
return getAccessorStatement;
|
||||
}
|
||||
|
||||
function createSetAccessor(item: ts.Identifier, express: string): ts.SetAccessorDeclaration {
|
||||
function createSetAccessor(item: ts.Identifier, express: string, type: ts.TypeNode):
|
||||
ts.SetAccessorDeclaration {
|
||||
const setAccessorStatement: ts.SetAccessorDeclaration =
|
||||
ts.factory.createSetAccessorDeclaration(undefined, undefined, item,
|
||||
[ts.factory.createParameterDeclaration(undefined, undefined, undefined,
|
||||
ts.factory.createIdentifier(CREATE_NEWVALUE_IDENTIFIER), undefined, undefined,
|
||||
ts.factory.createIdentifier(CREATE_NEWVALUE_IDENTIFIER), undefined, type,
|
||||
undefined)], ts.factory.createBlock([ts.factory.createExpressionStatement(
|
||||
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
|
||||
createPropertyAccessExpressionWithThis(`__${item.getText()}`),
|
||||
@@ -732,7 +739,7 @@ function isForbiddenUseStateType(typeNode: ts.TypeNode): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isSimpleType(typeNode: ts.TypeNode, program: ts.Program): boolean {
|
||||
export function isSimpleType(typeNode: ts.TypeNode, program: ts.Program): boolean {
|
||||
let checker: ts.TypeChecker;
|
||||
if (program) {
|
||||
checker = program.getTypeChecker();
|
||||
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
createViewCreate,
|
||||
createCustomComponentNewExpression
|
||||
} from './process_component_member';
|
||||
import { builderParamObjectCollection } from './process_component_member';
|
||||
import {
|
||||
LogType,
|
||||
LogInfo,
|
||||
@@ -72,10 +73,50 @@ const decoractorMap: Map<string, Map<string, Set<string>>> = new Map(
|
||||
export function processCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[],
|
||||
log: LogInfo[]): void {
|
||||
if (ts.isCallExpression(node.expression)) {
|
||||
addCustomComponent(node, newStatements, createCustomComponentNewExpression(node.expression), log);
|
||||
let ischangeNode: boolean = false;
|
||||
let customComponentNewExpression: ts.NewExpression = createCustomComponentNewExpression(
|
||||
node.expression);
|
||||
let argumentsArray: ts.PropertyAssignment[];
|
||||
if (isHasChild(node.expression)) {
|
||||
// @ts-ignore
|
||||
argumentsArray = node.expression.arguments[0].properties.slice();
|
||||
argumentsArray.forEach((item: ts.PropertyAssignment, index: number) => {
|
||||
if (isToChange(item, node.expression as ts.CallExpression)) {
|
||||
ischangeNode = true;
|
||||
const propertyAssignmentNode: ts.PropertyAssignment = ts.factory.updatePropertyAssignment(
|
||||
item, item.name, changeNodeFromCallToArrow(item.initializer as ts.CallExpression));
|
||||
argumentsArray.splice(index, 1, propertyAssignmentNode);
|
||||
}
|
||||
});
|
||||
if (ischangeNode) {
|
||||
const newNode: ts.ExpressionStatement = ts.factory.updateExpressionStatement(node,
|
||||
ts.factory.createNewExpression(node.expression.expression, node.expression.typeArguments,
|
||||
[ts.factory.createObjectLiteralExpression(argumentsArray, true)]));
|
||||
customComponentNewExpression = createCustomComponentNewExpression(
|
||||
newNode.expression as ts.CallExpression);
|
||||
}
|
||||
}
|
||||
addCustomComponent(node, newStatements, customComponentNewExpression, log);
|
||||
}
|
||||
}
|
||||
|
||||
function isHasChild(node: ts.CallExpression): boolean {
|
||||
return node.arguments && node.arguments[0] && ts.isObjectLiteralExpression(node.arguments[0]) &&
|
||||
node.arguments[0].properties && node.arguments[0].properties.length;
|
||||
}
|
||||
|
||||
function isToChange(item: ts.PropertyAssignment, node: ts.CallExpression): boolean {
|
||||
const builderParamName: Set<string> = builderParamObjectCollection.get(node.expression.getText());
|
||||
return item.initializer && ts.isCallExpression(item.initializer) && builderParamName &&
|
||||
builderParamName.has(item.name.getText());
|
||||
}
|
||||
|
||||
function changeNodeFromCallToArrow(node: ts.CallExpression): ts.ArrowFunction {
|
||||
return ts.factory.createArrowFunction(undefined, undefined, [], undefined,
|
||||
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
||||
ts.factory.createBlock([ts.factory.createExpressionStatement(node)], true));
|
||||
}
|
||||
|
||||
function addCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[],
|
||||
newNode: ts.NewExpression, log: LogInfo[]): void {
|
||||
if (ts.isNewExpression(newNode)) {
|
||||
@@ -89,7 +130,7 @@ function addCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Stat
|
||||
function addCustomComponentStatements(node: ts.ExpressionStatement, newStatements: ts.Statement[],
|
||||
newNode: ts.NewExpression, name: string, props: ts.ObjectLiteralElementLike[]): void {
|
||||
const id: string = componentInfo.id.toString();
|
||||
newStatements.push(createFindChildById(id), createCustomComponentIfStatement(id,
|
||||
newStatements.push(createFindChildById(id, name), createCustomComponentIfStatement(id,
|
||||
ts.factory.updateExpressionStatement(node, createViewCreate(newNode)),
|
||||
ts.factory.createObjectLiteralExpression(props, true), name));
|
||||
}
|
||||
@@ -105,13 +146,16 @@ function validateCustomComponentPrams(node: ts.ExpressionStatement, name: string
|
||||
ts.isObjectLiteralExpression(nodeArguments[0])) {
|
||||
const nodeArgument: ts.ObjectLiteralExpression = nodeArguments[0] as ts.ObjectLiteralExpression;
|
||||
nodeArgument.properties.forEach(item => {
|
||||
if (item.name && item.name.escapedText) {
|
||||
// @ts-ignore
|
||||
if (item.name && ts.isIdentifier(item.name)) {
|
||||
curChildProps.add(item.name.escapedText.toString());
|
||||
}
|
||||
if (isThisProperty(item, propertySet)) {
|
||||
validateStateManagement(item, name, log);
|
||||
if (isNonThisProperty(item, linkSet)) {
|
||||
if (isToChange(item as ts.PropertyAssignment, node.expression as ts.CallExpression)) {
|
||||
item = ts.factory.updatePropertyAssignment(item as ts.PropertyAssignment,
|
||||
item.name, changeNodeFromCallToArrow(item.initializer));
|
||||
}
|
||||
props.push(item);
|
||||
}
|
||||
} else {
|
||||
@@ -119,6 +163,7 @@ function validateCustomComponentPrams(node: ts.ExpressionStatement, name: string
|
||||
}
|
||||
});
|
||||
}
|
||||
validateMandatoryToAssignmentViaParam(node, name, curChildProps, log);
|
||||
validateMandatoryToInitViaParam(node, name, curChildProps, log);
|
||||
}
|
||||
|
||||
@@ -272,13 +317,14 @@ function getPropertyDecoratorKind(propertyName: string, customComponentName: str
|
||||
}
|
||||
}
|
||||
|
||||
function createFindChildById(id: string): ts.VariableStatement {
|
||||
function createFindChildById(id: string, name: string): ts.VariableStatement {
|
||||
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList(
|
||||
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(
|
||||
`${CUSTOM_COMPONENT_EARLIER_CREATE_CHILD}${id}`), undefined, undefined,
|
||||
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
|
||||
ts.factory.createIdentifier(`${CUSTOM_COMPONENT_FUNCTION_FIND_CHILD_BY_ID}`)), undefined,
|
||||
[ts.factory.createStringLiteral(id)]))], ts.NodeFlags.Let));
|
||||
`${CUSTOM_COMPONENT_EARLIER_CREATE_CHILD}${id}`), undefined, ts.factory.createTypeReferenceNode(
|
||||
ts.factory.createIdentifier(name)), ts.factory.createAsExpression(ts.factory.createCallExpression(
|
||||
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createIdentifier(
|
||||
`${CUSTOM_COMPONENT_FUNCTION_FIND_CHILD_BY_ID}`)), undefined, [ts.factory.createStringLiteral(id)]),
|
||||
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(name))))], ts.NodeFlags.Let));
|
||||
}
|
||||
|
||||
function createCustomComponentIfStatement(id: string, node: ts.ExpressionStatement,
|
||||
@@ -346,11 +392,27 @@ function validateNonExistentProperty(node: ts.ObjectLiteralElementLike,
|
||||
customComponentName: string, log: LogInfo[]): void {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: `Property '${node.name.getText()}' does not exist on type '${customComponentName}'.`,
|
||||
message: `Property '${node.name.escapedText.toString()}' does not exist on type '${customComponentName}'.`,
|
||||
pos: node.name.getStart()
|
||||
});
|
||||
}
|
||||
|
||||
function validateMandatoryToAssignmentViaParam(node: ts.ExpressionStatement, customComponentName: string,
|
||||
curChildProps: Set<string>, log: LogInfo[]): void {
|
||||
if (builderParamObjectCollection.get(customComponentName) &&
|
||||
builderParamObjectCollection.get(customComponentName).size) {
|
||||
builderParamObjectCollection.get(customComponentName).forEach((item) => {
|
||||
if (!curChildProps.has(item)) {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: `The property decorated with @BuilderParam '${item}' must be assigned a value .`,
|
||||
pos: node.getStart()
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function validateMandatoryToInitViaParam(node: ts.ExpressionStatement, customComponentName: string,
|
||||
curChildProps: Set<string>, log: LogInfo[]): void {
|
||||
const mandatoryToInitViaParamSet: Set<string> = new Set([
|
||||
|
||||
@@ -56,7 +56,8 @@ import {
|
||||
EXTEND_ATTRIBUTE,
|
||||
JS_BIND_COMPONENTS,
|
||||
INNER_STYLE_FUNCTION,
|
||||
GLOBAL_STYLE_FUNCTION
|
||||
GLOBAL_STYLE_FUNCTION,
|
||||
INTERFACE_NODE_SET
|
||||
} from './component_map';
|
||||
import { resources } from '../main';
|
||||
|
||||
@@ -81,8 +82,14 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
|
||||
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;
|
||||
INTERFACE_NODE_SET.forEach(item => {
|
||||
statements.unshift(item);
|
||||
});
|
||||
node = ts.factory.updateSourceFile(node, statements);
|
||||
INTERFACE_NODE_SET.clear();
|
||||
return node;
|
||||
} else {
|
||||
return node;
|
||||
@@ -98,7 +105,7 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
|
||||
componentCollection.currentClassName = null;
|
||||
INNER_STYLE_FUNCTION.forEach((block, styleName) => {
|
||||
BUILDIN_STYLE_NAMES.delete(styleName);
|
||||
})
|
||||
});
|
||||
INNER_STYLE_FUNCTION.clear();
|
||||
} else if (ts.isFunctionDeclaration(node)) {
|
||||
if (hasDecorator(node, COMPONENT_EXTEND_DECORATOR)) {
|
||||
@@ -154,7 +161,7 @@ function collectComponents(node: ts.SourceFile): void {
|
||||
// @ts-ignore
|
||||
if (node.identifiers && node.identifiers.size) {
|
||||
// @ts-ignore
|
||||
for (let key of node.identifiers.keys()) {
|
||||
for (const key of node.identifiers.keys()) {
|
||||
if (JS_BIND_COMPONENTS.has(key)) {
|
||||
appComponentCollection.add(key);
|
||||
}
|
||||
@@ -186,7 +193,7 @@ function processResourceData(node: ts.CallExpression): ts.Node {
|
||||
return node;
|
||||
}
|
||||
|
||||
function createResourceParam(resourceValue: number, resourceType: number,argsArr: ts.Expression[]):
|
||||
function createResourceParam(resourceValue: number, resourceType: number, argsArr: ts.Expression[]):
|
||||
ts.ObjectLiteralExpression {
|
||||
const resourceParams: ts.ObjectLiteralExpression = ts.factory.createObjectLiteralExpression(
|
||||
[
|
||||
@@ -384,7 +391,7 @@ function isPropertyExist(typeChecker: ts.TypeChecker, pos: number, type: ts.Type
|
||||
} else {
|
||||
transformLog.errors.push({
|
||||
type: LogType.ERROR,
|
||||
message: `TS2339: Property '${propertyName}' does not exist on type '${componentName}'.`,
|
||||
message: `TS2339: Property '${propertyName}' does not exist on type '${componentName}Attribute'.`,
|
||||
pos: pos
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
import ts from 'typescript';
|
||||
import path from 'path';
|
||||
|
||||
import { BUILD_OFF } from './pre_define';
|
||||
import {
|
||||
|
||||
@@ -159,10 +159,10 @@ export function createFunction(node: ts.Identifier, attrNode: ts.Identifier,
|
||||
}
|
||||
|
||||
export function circularFile(inputPath: string, outputPath: string): void {
|
||||
if ((!inputPath) || (!outputPath)) {
|
||||
if (!inputPath || !outputPath) {
|
||||
return;
|
||||
}
|
||||
fs.readdir(inputPath, function (err, files) {
|
||||
fs.readdir(inputPath, function(err, files) {
|
||||
if (!files) {
|
||||
return;
|
||||
}
|
||||
@@ -205,4 +205,4 @@ function mkDir(path_: string): void {
|
||||
mkDir(parent);
|
||||
}
|
||||
fs.mkdirSync(path_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,10 @@ import {
|
||||
COMPONENT_CONSTRUCTOR_ID,
|
||||
COMPONENT_CONSTRUCTOR_PARENT,
|
||||
COMPONENT_CONSTRUCTOR_PARAMS,
|
||||
COMPONENT_EXTEND_DECORATOR,
|
||||
COMPONENT_OBSERVED_DECORATOR,
|
||||
STYLES
|
||||
STYLES,
|
||||
VALIDATE_MODULE,
|
||||
COMPONENT_BUILDER_DECORATOR
|
||||
} from './pre_define';
|
||||
import {
|
||||
INNER_COMPONENT_NAMES,
|
||||
@@ -53,7 +54,8 @@ import {
|
||||
BUILDIN_STYLE_NAMES,
|
||||
EXTEND_ATTRIBUTE,
|
||||
GLOBAL_STYLE_FUNCTION,
|
||||
STYLES_ATTRIBUTE
|
||||
STYLES_ATTRIBUTE,
|
||||
CUSTOM_BUILDER_METHOD
|
||||
} from './component_map';
|
||||
import {
|
||||
LogType,
|
||||
@@ -183,19 +185,20 @@ function checkComponentDecorator(source: string, filePath: string,
|
||||
}
|
||||
if (ts.isFunctionDeclaration(item) && item.decorators && item.decorators.length === 1 &&
|
||||
item.decorators[0].expression && item.decorators[0].expression.getText() === STYLES) {
|
||||
STYLES_ATTRIBUTE.add(item.name.getText())
|
||||
STYLES_ATTRIBUTE.add(item.name.getText());
|
||||
GLOBAL_STYLE_FUNCTION.set(item.name.getText(), item.body);
|
||||
BUILDIN_STYLE_NAMES.add(item.name.getText());
|
||||
}
|
||||
});
|
||||
validateEntryAndPreviewCount(result, fileQuery, sourceFile.fileName, projectConfig.isPreview, log);
|
||||
validateEntryAndPreviewCount(result, fileQuery, sourceFile.fileName, projectConfig.isPreview,
|
||||
!!projectConfig.checkEntry, log);
|
||||
}
|
||||
|
||||
return log.length ? log : null;
|
||||
}
|
||||
|
||||
function validateEntryAndPreviewCount(result: DecoratorResult, fileQuery: string,
|
||||
fileName: string, isPreview: boolean, log: LogInfo[]): void {
|
||||
fileName: string, isPreview: boolean, checkEntry: boolean, log: LogInfo[]): void {
|
||||
if (result.previewCount > 10 && fileQuery === '?entry') {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
@@ -210,7 +213,7 @@ function validateEntryAndPreviewCount(result: DecoratorResult, fileQuery: string
|
||||
fileName: fileName
|
||||
});
|
||||
}
|
||||
if (isPreview && result.previewCount < 1 && result.entryCount !== 1 &&
|
||||
if (isPreview && !checkEntry && result.previewCount < 1 && result.entryCount !== 1 &&
|
||||
fileQuery === '?entry') {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
@@ -218,7 +221,7 @@ function validateEntryAndPreviewCount(result: DecoratorResult, fileQuery: string
|
||||
+ `decorator, or at least one '@Preview' decorator.`,
|
||||
fileName: fileName
|
||||
});
|
||||
} else if (!isPreview && result.entryCount !== 1 && fileQuery === '?entry') {
|
||||
} else if ((!isPreview || isPreview && checkEntry) && result.entryCount !== 1 && fileQuery === '?entry') {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: `A page configured in 'config.json' must have one and only one '@Entry' `
|
||||
@@ -323,6 +326,9 @@ function visitAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, allComponent
|
||||
if (ts.isClassDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
|
||||
collectComponentProps(node);
|
||||
}
|
||||
if (ts.isMethodDeclaration(node) && hasDecorator(node, COMPONENT_BUILDER_DECORATOR)) {
|
||||
CUSTOM_BUILDER_METHOD.add(node.name.getText());
|
||||
}
|
||||
node.getChildren().forEach((item: ts.Node) => visitAllNode(item, sourceFileNode, allComponentNames, log));
|
||||
}
|
||||
|
||||
@@ -744,7 +750,7 @@ export function sourceReplace(source: string, sourcePath: string): ReplaceResult
|
||||
return {
|
||||
content: content,
|
||||
log: log
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function preprocessExtend(content: string, sourcePath: string, log: LogInfo[]): string {
|
||||
@@ -772,7 +778,7 @@ export function preprocessExtend(content: string, sourcePath: string, log: LogIn
|
||||
syntaxCheckContent = content;
|
||||
}
|
||||
if (result.error_otherParsers) {
|
||||
for(let i = 0; i < result.error_otherParsers.length; i++) {
|
||||
for (let i = 0; i < result.error_otherParsers.length; i++) {
|
||||
log.push({
|
||||
type: LogType.ERROR,
|
||||
message: result.error_otherParsers[i].errMessage,
|
||||
@@ -811,39 +817,53 @@ export function processSystemApi(content: string, isProcessWhiteList: boolean =
|
||||
}
|
||||
const REG_LIB_SO: RegExp =
|
||||
/import\s+(.+)\s+from\s+['"]lib(\S+)\.so['"]|import\s+(.+)\s*=\s*require\(\s*['"]lib(\S+)\.so['"]\s*\)/g;
|
||||
return content.replace(REG_LIB_SO, (_, item1, item2, item3, item4) => {
|
||||
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;
|
||||
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 (!isProcessWhiteList && validateWhiteListModule(moduleType, systemKey)) {
|
||||
return item;
|
||||
} else if (isProcessWhiteList) {
|
||||
systemValue = item2;
|
||||
moduleType = item4;
|
||||
systemKey = item5;
|
||||
}
|
||||
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}') ? ` +
|
||||
}).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 (!isProcessWhiteList && validateWhiteListModule(moduleType, systemKey)) {
|
||||
return item;
|
||||
} else if (isProcessWhiteList) {
|
||||
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}') || ` +
|
||||
} 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 item;
|
||||
});
|
||||
return processInnerModule(newContent, systemValueCollection);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
});
|
||||
return content;
|
||||
}
|
||||
|
||||
const VALIDATE_MODULE_REG: RegExp = new RegExp('^(' + VALIDATE_MODULE.join('|') + ')');
|
||||
function validateWhiteListModule(moduleType: string, systemKey: string): boolean {
|
||||
return moduleType === 'ohos' && /^application\./g.test(systemKey);
|
||||
return moduleType === 'ohos' && VALIDATE_MODULE_REG.test(systemKey);
|
||||
}
|
||||
|
||||
export function resetComponentCollection() {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
exports.source = `
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Banner {
|
||||
@Builder textBuilder() {
|
||||
Text("文本")
|
||||
.fontSize(30)
|
||||
}
|
||||
@Builder NavigationTitle(label:string) {
|
||||
Column() {
|
||||
Text(label)
|
||||
.width(10)
|
||||
.bindMenu(this.textBuilder)
|
||||
}
|
||||
}
|
||||
build() {
|
||||
Column() {
|
||||
Text("111")
|
||||
.bindMenu(this.NavigationTitle("111"))
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
exports.expectResult =
|
||||
`class Banner extends View {
|
||||
constructor(compilerAssignedUniqueChildId, parent, params) {
|
||||
super(compilerAssignedUniqueChildId, parent);
|
||||
this.updateWithValueParams(params);
|
||||
}
|
||||
updateWithValueParams(params) {
|
||||
}
|
||||
aboutToBeDeleted() {
|
||||
SubscriberManager.Get().delete(this.id());
|
||||
}
|
||||
textBuilder() {
|
||||
Text.create("文本");
|
||||
Text.fontSize(30);
|
||||
Text.pop();
|
||||
}
|
||||
NavigationTitle(label) {
|
||||
Column.create();
|
||||
Text.create(label);
|
||||
Text.width(10);
|
||||
Text.bindMenu({ builder: this.textBuilder.bind(this) });
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
}
|
||||
render() {
|
||||
Column.create();
|
||||
Text.create("111");
|
||||
Text.bindMenu({ builder: () => {
|
||||
this.NavigationTitle("111");
|
||||
} });
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
}
|
||||
}
|
||||
loadDocument(new Banner("1", undefined, {}));
|
||||
`
|
||||
@@ -29,10 +29,10 @@ struct CustomContainer {
|
||||
}
|
||||
}
|
||||
|
||||
@Builder function specificParam(label1: string, label2: string) {
|
||||
@Builder function specificParam() {
|
||||
Column() {
|
||||
Text(label1)
|
||||
Text(label2)
|
||||
Text("label1")
|
||||
Text("label2")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ struct CustomContainerUser {
|
||||
.width(50)
|
||||
Text("content2")
|
||||
}
|
||||
specificParam("content3", "content4")
|
||||
specificParam()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,8 +57,8 @@ exports.expectResult =
|
||||
`class CustomContainer extends View {
|
||||
constructor(compilerAssignedUniqueChildId, parent, params) {
|
||||
super(compilerAssignedUniqueChildId, parent);
|
||||
this.header = ""
|
||||
this.footer = ""
|
||||
this.header = "";
|
||||
this.footer = "";
|
||||
this.updateWithValueParams(params);
|
||||
}
|
||||
updateWithValueParams(params) {
|
||||
@@ -68,18 +68,11 @@ exports.expectResult =
|
||||
if (params.footer !== undefined) {
|
||||
this.footer = params.footer;
|
||||
}
|
||||
this.__child = params.child;
|
||||
this.child = params.child;
|
||||
}
|
||||
aboutToBeDeleted() {
|
||||
this.__child.aboutToBeDeleted();
|
||||
SubscriberManager.Get().delete(this.id());
|
||||
}
|
||||
get child(){
|
||||
return this.__child.get();
|
||||
}
|
||||
set child(newValue) {
|
||||
this.__child.set(newValue)
|
||||
}
|
||||
render() {
|
||||
Column.create();
|
||||
Text.create(this.header);
|
||||
@@ -90,15 +83,15 @@ exports.expectResult =
|
||||
Column.pop();
|
||||
}
|
||||
}
|
||||
function specificParam(label1, label2) {
|
||||
function specificParam() {
|
||||
Column.create();
|
||||
Text.create(label1);
|
||||
Text.create("label1");
|
||||
Text.pop();
|
||||
Text.create(label1);
|
||||
Text.create("label2");
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
}
|
||||
class CustomContainerUser {
|
||||
class CustomContainerUser extends View {
|
||||
constructor(compilerAssignedUniqueChildId, parent, params) {
|
||||
super(compilerAssignedUniqueChildId, parent);
|
||||
this.updateWithValueParams(params);
|
||||
@@ -117,12 +110,12 @@ class CustomContainerUser {
|
||||
child: () => {
|
||||
Column.create();
|
||||
Text.create("content1");
|
||||
Text.width(50)
|
||||
Text.width(50);
|
||||
Text.pop();
|
||||
Text.create("content2");
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
specificParam("content3", "content4)
|
||||
specificParam();
|
||||
}
|
||||
}));
|
||||
}
|
||||
@@ -132,18 +125,18 @@ class CustomContainerUser {
|
||||
child: () => {
|
||||
Column.create();
|
||||
Text.create("content1");
|
||||
Text.width(50)
|
||||
Text.width(50);
|
||||
Text.pop();
|
||||
Text.create("content2");
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
specificParam("content3", "content4)
|
||||
}}
|
||||
specificParam();
|
||||
}
|
||||
});
|
||||
View.create(earlierCreatedChild_2);
|
||||
}
|
||||
Column.pop();
|
||||
Column.pop();
|
||||
}
|
||||
}
|
||||
loadDocument(new MyComponent("1", undefined, {}));
|
||||
loadDocument(new CustomContainerUser("1", undefined, {}));
|
||||
`
|
||||
|
||||
@@ -14,35 +14,30 @@
|
||||
*/
|
||||
|
||||
exports.source = `
|
||||
|
||||
@Component
|
||||
struct CustomContainer {
|
||||
header: string = "";
|
||||
menuInfo: () => any;
|
||||
footer: string = "";
|
||||
@BuilderParam child: () => any;
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Text(this.header)
|
||||
this.child()
|
||||
Text(this.header)
|
||||
Text(this.footer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Builder function specificParam(label1: string, label2: string) {
|
||||
Column() {
|
||||
Text(label1)
|
||||
Text(label2)
|
||||
}
|
||||
}
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct CustomContainerUser {
|
||||
@Builder specificChild() {
|
||||
@Builder specificChild(label:string) {
|
||||
Column() {
|
||||
Text("My content1")
|
||||
Text("My content1")
|
||||
Text(label)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,12 +46,8 @@ struct CustomContainerUser {
|
||||
CustomContainer({
|
||||
header: "Header",
|
||||
footer: "Footer",
|
||||
child: this.specificChild
|
||||
})
|
||||
CustomContainer({
|
||||
header: "Header",
|
||||
footer: "Footer",
|
||||
child: specificParam("content3", "content4")
|
||||
menuInfo: this.specificChild("menuInfo"),
|
||||
child: this.specificChild("child")
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -66,48 +57,37 @@ exports.expectResult =
|
||||
`class CustomContainer extends View {
|
||||
constructor(compilerAssignedUniqueChildId, parent, params) {
|
||||
super(compilerAssignedUniqueChildId, parent);
|
||||
this.header = ""
|
||||
this.footer = ""
|
||||
this.header = "";
|
||||
this.menuInfo = undefined;
|
||||
this.footer = "";
|
||||
this.updateWithValueParams(params);
|
||||
}
|
||||
updateWithValueParams(params) {
|
||||
if (params.header !== undefined) {
|
||||
this.header = params.header;
|
||||
}
|
||||
if (params.menuInfo !== undefined) {
|
||||
this.menuInfo = params.menuInfo;
|
||||
}
|
||||
if (params.footer !== undefined) {
|
||||
this.footer = params.footer;
|
||||
}
|
||||
this.__child = params.child;
|
||||
this.child = params.child;
|
||||
}
|
||||
aboutToBeDeleted() {
|
||||
this.__child.aboutToBeDeleted();
|
||||
SubscriberManager.Get().delete(this.id());
|
||||
}
|
||||
get child(){
|
||||
return this.__child.get();
|
||||
}
|
||||
set child(newValue) {
|
||||
this.__child.set(newValue)
|
||||
}
|
||||
render() {
|
||||
Column.create();
|
||||
this.child();
|
||||
Text.create(this.header);
|
||||
Text.pop();
|
||||
this.child();
|
||||
Text.create(this.footer);
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
}
|
||||
}
|
||||
function specificParam(label1, label2) {
|
||||
Column.create();
|
||||
Text.create(label1);
|
||||
Text.pop();
|
||||
Text.create(label1);
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
}
|
||||
class CustomContainerUser {
|
||||
class CustomContainerUser extends View {
|
||||
constructor(compilerAssignedUniqueChildId, parent, params) {
|
||||
super(compilerAssignedUniqueChildId, parent);
|
||||
this.updateWithValueParams(params);
|
||||
@@ -117,50 +97,40 @@ class CustomContainerUser {
|
||||
aboutToBeDeleted() {
|
||||
SubscriberManager.Get().delete(this.id());
|
||||
}
|
||||
specificChild() {
|
||||
specificChild(label) {
|
||||
Column.create();
|
||||
Text.create("My content1");
|
||||
Text.pop();
|
||||
Text.create("My content2");
|
||||
Text.create(label);
|
||||
Text.pop();
|
||||
Column.pop();
|
||||
}
|
||||
render() {
|
||||
Column.create();
|
||||
let earlierCreatedChild_2 = this.findChildById("2");
|
||||
if (earlierCreatedChild_2 == undefined) {
|
||||
View.create(new CustomContainer("2", this, {
|
||||
header: "Header",
|
||||
footer: "Footer",
|
||||
child: this.specificChild
|
||||
}));
|
||||
}
|
||||
else {
|
||||
earlierCreatedChild_2.updateWithValueParams({
|
||||
header: "Header",
|
||||
footer: "Footer",
|
||||
child: this.specificChild
|
||||
});
|
||||
View.create(earlierCreatedChild_2);
|
||||
}
|
||||
let earlierCreatedChild_3 = this.findChildById("3");
|
||||
if (earlierCreatedChild_3 == undefined) {
|
||||
View.create(new CustomContainer("3", this, {
|
||||
header: "Header",
|
||||
footer: "Footer",
|
||||
child: specificParam("content3", "content4")
|
||||
menuInfo: this.specificChild("menuInfo"),
|
||||
child: () => {
|
||||
this.specificChild("child");
|
||||
}
|
||||
}));
|
||||
}
|
||||
else {
|
||||
earlierCreatedChild_3.updateWithValueParams({
|
||||
header: "Header",
|
||||
footer: "Footer",
|
||||
child: specificParam("content3", "content4")
|
||||
menuInfo: this.specificChild("menuInfo"),
|
||||
child: () => {
|
||||
this.specificChild("child");
|
||||
}
|
||||
});
|
||||
View.create(earlierCreatedChild_3);
|
||||
}
|
||||
Column.pop();
|
||||
Column.pop();
|
||||
}
|
||||
}
|
||||
loadDocument(new MyComponent("1", undefined, {}));
|
||||
loadDocument(new CustomContainerUser("1", undefined, {}));
|
||||
`
|
||||
|
||||
@@ -33,9 +33,7 @@ struct MyAlertDialog {
|
||||
}
|
||||
build() {
|
||||
Stack() {
|
||||
DialogView({dialogShow: $dialogVis}).onClick(() => {
|
||||
animateTo({}, () => {})
|
||||
})
|
||||
DialogView({dialogShow: $dialogVis})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,15 +106,13 @@ class MyAlertDialog extends View {
|
||||
}
|
||||
render() {
|
||||
Stack.create();
|
||||
let earlierCreatedChild_2 = this.findChildById("2");
|
||||
if (earlierCreatedChild_2 == undefined) {
|
||||
View.create(new (DialogView({ dialogShow: this.__dialogVis }).onClick)(() => {
|
||||
Context.animateTo({}, () => { });
|
||||
}));
|
||||
let earlierCreatedChild_3 = this.findChildById("3");
|
||||
if (earlierCreatedChild_3 == undefined) {
|
||||
View.create(new DialogView("3", this, { dialogShow: this.__dialogVis }));
|
||||
}
|
||||
else {
|
||||
earlierCreatedChild_2.updateWithValueParams({});
|
||||
View.create(earlierCreatedChild_2);
|
||||
earlierCreatedChild_3.updateWithValueParams({});
|
||||
View.create(earlierCreatedChild_3);
|
||||
}
|
||||
Stack.pop();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ struct HomeComponent {
|
||||
Text(this.value1)
|
||||
Text(this.value2)
|
||||
Text(this.value3)
|
||||
Radio({value: "Radio", group: "1"})
|
||||
.checked($$this.value4)
|
||||
}
|
||||
Row() {
|
||||
Button() {
|
||||
@@ -45,6 +47,8 @@ struct HomeComponent {
|
||||
.fontSize(100)
|
||||
.bindPopup($$value6.item1, {message: "This is $$ for Obj"})
|
||||
Text(this.value3)
|
||||
Radio({value: "Radio", group: "1"})
|
||||
.checked($$value5[0])
|
||||
}
|
||||
.width(20)
|
||||
}
|
||||
@@ -91,6 +95,8 @@ class HomeComponent extends View {
|
||||
Text.pop();
|
||||
Text.create(this.value3);
|
||||
Text.pop();
|
||||
Radio.create({ value: "Radio", group: "1" });
|
||||
Radio.checked(this.value4, newValue => { this.value4 = newValue; });
|
||||
Row.pop();
|
||||
Row.create();
|
||||
Row.width(20);
|
||||
@@ -109,6 +115,8 @@ class HomeComponent extends View {
|
||||
Text.pop();
|
||||
Text.create(this.value3);
|
||||
Text.pop();
|
||||
Radio.create({ value: "Radio", group: "1" });
|
||||
Radio.checked(value5[0], newValue => { value5[0] = newValue; });
|
||||
Row.pop();
|
||||
Column.pop();
|
||||
}
|
||||
|
||||
+35
-22
@@ -46,27 +46,6 @@ function initConfig(config) {
|
||||
poll: false,
|
||||
ignored: /node_modules/
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
chunks(chunk) {
|
||||
return !/^\.\/workers\//.test(chunk.name);
|
||||
},
|
||||
minSize: 0,
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: -10,
|
||||
name: "vendors",
|
||||
},
|
||||
commons: {
|
||||
name: 'commons',
|
||||
priority: -20,
|
||||
minChunks: 2,
|
||||
reuseExistingChunk: true
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, projectConfig.buildPath),
|
||||
filename: '[name].js',
|
||||
@@ -121,7 +100,7 @@ function initConfig(config) {
|
||||
path.join(projectPath, '../../../../../'),
|
||||
'./node_modules',
|
||||
path.join(__dirname, 'node_modules'),
|
||||
path.join(__dirname, '../../api/common')
|
||||
path.join(__dirname, '../../api')
|
||||
]
|
||||
},
|
||||
stats: { preset: 'none' },
|
||||
@@ -152,6 +131,12 @@ function setProjectConfig(envArgs) {
|
||||
if (envArgs.aceManifestPath) {
|
||||
projectConfig.manifestFilePath = envArgs.aceManifestPath;
|
||||
}
|
||||
if (envArgs.aceProfilePath) {
|
||||
projectConfig.aceProfilePath = envArgs.aceProfilePath;
|
||||
}
|
||||
if (envArgs.aceModuleJsonPath) {
|
||||
projectConfig.aceModuleJsonPath = envArgs.aceModuleJsonPath;
|
||||
}
|
||||
}
|
||||
|
||||
function setReleaseConfig(config) {
|
||||
@@ -207,11 +192,38 @@ function setCopyPluginConfig(config) {
|
||||
config.plugins.push(new CopyPlugin({ patterns: copyPluginPattrens }));
|
||||
}
|
||||
|
||||
function setOptimizationConfig(config) {
|
||||
if (process.env.compileMode !== 'moduleJson') {
|
||||
config.optimization = {
|
||||
splitChunks: {
|
||||
chunks(chunk) {
|
||||
return !/^\.\/workers\//.test(chunk.name);
|
||||
},
|
||||
minSize: 0,
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: -10,
|
||||
name: "vendors",
|
||||
},
|
||||
commons: {
|
||||
name: 'commons',
|
||||
priority: -20,
|
||||
minChunks: 2,
|
||||
reuseExistingChunk: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (env, argv) => {
|
||||
const config = {};
|
||||
setProjectConfig(env);
|
||||
loadEntryObj(projectConfig);
|
||||
initConfig(config);
|
||||
setOptimizationConfig(config);
|
||||
setCopyPluginConfig(config);
|
||||
|
||||
if (env.isPreview !== "true") {
|
||||
@@ -230,6 +242,7 @@ module.exports = (env, argv) => {
|
||||
}
|
||||
} else {
|
||||
projectConfig.isPreview = true;
|
||||
projectConfig.checkEntry = env.checkEntry;
|
||||
let port;
|
||||
process.argv.forEach((val, index) => {
|
||||
if(val.startsWith('port=')){
|
||||
|
||||
Reference in New Issue
Block a user