fix collect 15272 in wrong ast

Signed-off-by: houhaoyu <houhaoyu@huawei.com>
Change-Id: If2fa6518eebcb0232021f2c55ec12d0a2e78e2df
This commit is contained in:
houhaoyu 2024-07-18 17:17:55 +08:00
parent fe8cc4305c
commit f9e0548af7
4 changed files with 362 additions and 45 deletions

View File

@ -54,7 +54,6 @@ import {
WATCH_COMPILER_BUILD_INFO_SUFFIX,
COMPONENT_STYLES_DECORATOR
} from './pre_define';
import { getName } from './process_component_build';
import {
INNER_COMPONENT_NAMES,
JS_BIND_COMPONENTS,
@ -1116,7 +1115,7 @@ function checkUISyntax(source: string, fileName: string, extendFunctionInfo: ext
if (process.env.compileMode === 'moduleJson' ||
path.resolve(fileName) !== path.resolve(projectConfig.projectPath, 'app.ets')) {
const sourceFile: ts.SourceFile = ts.createSourceFile(fileName, source,
ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS, compilerOptions);
collectComponents(sourceFile);
collectionCustomizeStyles(sourceFile);
parseAllNode(sourceFile, sourceFile, extendFunctionInfo);
@ -1220,31 +1219,47 @@ function isForeachAndLzayForEach(node: ts.Node): boolean {
ts.isArrowFunction(node.arguments[1]) && node.arguments[1].body && ts.isBlock(node.arguments[1].body);
}
function getComponentName(node: ts.Node): string {
let temp: any = node.expression;
let name: string;
while (temp) {
if (ts.isIdentifier(temp) && temp.parent && (ts.isCallExpression(temp.parent) ||
ts.isEtsComponentExpression(temp.parent))) {
name = temp.escapedText.toString();
break;
}
temp = temp.expression;
}
return name;
}
function traverseBuild(node: ts.Node, index: number): void {
if (ts.isExpressionStatement(node)) {
let parentComponentName: string = getName(node);
if (!INNER_COMPONENT_NAMES.has(parentComponentName) && node.parent && node.parent.statements && index >= 1 &&
node.parent.statements[index - 1].expression && node.parent.statements[index - 1].expression.expression) {
parentComponentName = node.parent.statements[index - 1].expression.expression.escapedText;
}
const parentComponentName: string = getComponentName(node);
node = node.expression;
if (ts.isEtsComponentExpression(node) && node.body && ts.isBlock(node.body) &&
ts.isIdentifier(node.expression) && !DOLLAR_BLOCK_INTERFACE.has(node.expression.escapedText.toString())) {
node.body.statements.forEach((item: ts.Statement, indexBlock: number) => {
traverseBuild(item, indexBlock);
});
} else if (isForeachAndLzayForEach(node)) {
node.arguments[1].body.statements.forEach((item: ts.Statement, indexBlock: number) => {
traverseBuild(item, indexBlock);
});
} else {
loopNodeFindDoubleDollar(node, parentComponentName);
while (node) {
if (ts.isEtsComponentExpression(node) && node.body && ts.isBlock(node.body) &&
ts.isIdentifier(node.expression)) {
ts.isIdentifier(node.expression) && !DOLLAR_BLOCK_INTERFACE.has(node.expression.escapedText.toString())) {
node.body.statements.forEach((item: ts.Statement, indexBlock: number) => {
traverseBuild(item, indexBlock);
});
break;
} else if (isForeachAndLzayForEach(node)) {
node.arguments[1].body.statements.forEach((item: ts.Statement, indexBlock: number) => {
traverseBuild(item, indexBlock);
});
break;
} else {
loopNodeFindDoubleDollar(node, parentComponentName);
if (ts.isEtsComponentExpression(node) && node.body && ts.isBlock(node.body) &&
ts.isIdentifier(node.expression)) {
node.body.statements.forEach((item: ts.Statement, indexBlock: number) => {
traverseBuild(item, indexBlock);
});
break;
}
}
node = node.expression;
}
} else if (ts.isIfStatement(node)) {
ifInnerDollarAttribute(node);
@ -1275,38 +1290,35 @@ function elseInnerDollarAttribute(node: ts.IfStatement): void {
function isPropertiesAddDoubleDollar(node: ts.Node): boolean {
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.arguments && node.arguments.length) {
return true;
} else if (ts.isEtsComponentExpression(node) && node.body && ts.isBlock(node.body) &&
ts.isIdentifier(node.expression) && DOLLAR_BLOCK_INTERFACE.has(node.expression.escapedText.toString())) {
} else if (ts.isEtsComponentExpression(node) && ts.isIdentifier(node.expression) &&
DOLLAR_BLOCK_INTERFACE.has(node.expression.escapedText.toString())) {
return true;
} else {
return false;
}
}
function loopNodeFindDoubleDollar(node: ts.Node, parentComponentName: string): void {
while (node) {
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
const argument: ts.NodeArray<ts.Node> = node.arguments;
const propertyName: ts.Identifier | ts.PrivateIdentifier = node.expression.name;
if (isCanAddDoubleDollar(propertyName.getText(), parentComponentName)) {
argument.forEach((item: ts.Node) => {
doubleDollarCollection(item);
});
}
} else if (isPropertiesAddDoubleDollar(node)) {
node.arguments.forEach((item: ts.Node) => {
if (ts.isObjectLiteralExpression(item) && item.properties && item.properties.length) {
item.properties.forEach((param: ts.Node) => {
if (isObjectPram(param, parentComponentName)) {
doubleDollarCollection(param.initializer);
}
});
} else if (ts.isPropertyAccessExpression(item) && (handleComponentDollarBlock(node as ts.CallExpression, parentComponentName) ||
STYLE_ADD_DOUBLE_DOLLAR.has(node.expression.getText()))) {
doubleDollarCollection(item);
}
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
const argument: ts.NodeArray<ts.Node> = node.arguments;
const propertyName: ts.Identifier | ts.PrivateIdentifier = node.expression.name;
if (isCanAddDoubleDollar(propertyName.getText(), parentComponentName)) {
argument.forEach((item: ts.Node) => {
doubleDollarCollection(item);
});
}
node = node.expression;
} else if (isPropertiesAddDoubleDollar(node)) {
node.arguments.forEach((item: ts.Node) => {
if (ts.isObjectLiteralExpression(item) && item.properties && item.properties.length) {
item.properties.forEach((param: ts.Node) => {
if (isObjectPram(param, parentComponentName)) {
doubleDollarCollection(param.initializer);
}
});
} else if (ts.isPropertyAccessExpression(item) && (handleComponentDollarBlock(node as ts.CallExpression, parentComponentName) ||
STYLE_ADD_DOUBLE_DOLLAR.has(node.expression.getText()))) {
doubleDollarCollection(item);
}
});
}
}

View File

@ -365,7 +365,7 @@ export const UPDATE_FUNC_BY_ELMT_ID: string = 'updateFuncByElmtId';
export const DOLLAR_BLOCK_INTERFACE: Set<string> = new Set([
CHECK_BOX, CHECKBOX_GROUP, DATE_PICKER, TIME_PICKER, MENU_ITEM, PANEL, RATING, SIDE_BAR_CONTAINER, STEPPER, SWIPER, TABS, TEXT_PICKER, TOGGLE, SELECT,
REFRESH, CALENDAR, GRID_ITEM, LIST_ITEM, TEXT_TIMER, SEAECH]);
REFRESH, CALENDAR, GRID_ITEM, LIST_ITEM, TEXT_TIMER, SEAECH, TEXT_INPUT]);
export const STYLE_ADD_DOUBLE_DOLLAR: Set<string> = new Set([
BIND_POPUP, $$_VISIBILITY, BIND_CONTENT_COVER, BIND_SHEET]);
export const PROPERTIES_ADD_DOUBLE_DOLLAR: Map<string, Set<string>> = new Map([

View File

@ -0,0 +1,293 @@
/*
* Copyright (c) 2024 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 = `
function func1(){}
@Component
struct Child {
@BuilderParam build1: ()=>void
build() {
Text('Child')
}
}
@Entry
@Component
struct Parent {
build() {
Column() {
ForEach([1], (item: number)=>{
Column(){
Child() {
Text('example1')
}
Repeat([1])
.each((repeatItem: RepeatItem<number>)=>{
Child() {
Text('example2')
}
Text('example6')
.onClick(()=>{
func1()
{
let b = 1;
}
})
})
.key((item: number)=>{
func1()
{
let b = 1;
}
return item.toString()
})
.template('1', (repeatItem: RepeatItem<number>)=>{
Child() {
Text('example3')
}
Text('example4')
.onClick(()=>{
func1()
{
let b = 1;
}
})
})
}
}, (item: number)=>{
return item.toString()
})
}.onClick(()=>{
func1()
{
let b = 1;
}
})
}
}`;
exports.expectResult =
`"use strict";
if (!("finalizeConstruction" in ViewPU.prototype)) {
Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
function func1() { }
class Child extends ViewPU {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda = undefined, extraInfo) {
super(parent, __localStorage, elmtId, extraInfo);
if (typeof paramsLambda === "function") {
this.paramsGenerator_ = paramsLambda;
}
this.build1 = undefined;
this.setInitiallyProvidedValue(params);
this.finalizeConstruction();
}
setInitiallyProvidedValue(params) {
if (params.build1 !== undefined) {
this.build1 = params.build1;
}
}
updateStateVars(params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('Child');
}, Text);
Text.pop();
}
rerender() {
this.updateDirtyElements();
}
}
class Parent extends ViewPU {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda = undefined, extraInfo) {
super(parent, __localStorage, elmtId, extraInfo);
if (typeof paramsLambda === "function") {
this.paramsGenerator_ = paramsLambda;
}
this.setInitiallyProvidedValue(params);
this.finalizeConstruction();
}
setInitiallyProvidedValue(params) {
}
updateStateVars(params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
Column.onClick(() => {
func1();
{
let b = 1;
}
});
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
ForEach.create();
const forEachItemGenFunction = _item => {
const item = _item;
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new Child(this, {
build1: () => {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example1');
}, Text);
Text.pop();
}
}, undefined, elmtId, () => { }, { page: "build_ui_in_correct_place.ets", line: 19, col: 11 });
ViewPU.create(componentCall);
let paramsLambda = () => {
return {
build1: () => {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example1');
}, Text);
Text.pop();
}
};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {});
}
}, { name: "Child" });
}
this.observeComponentCreation2((elmtId, isInitialRender) => {
Repeat([1], this).each((repeatItem) => {
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new Child(this, {
build1: () => {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example2');
}, Text);
Text.pop();
}
}, undefined, elmtId, () => { }, { page: "build_ui_in_correct_place.ets", line: 24, col: 15 });
ViewPU.create(componentCall);
let paramsLambda = () => {
return {
build1: () => {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example2');
}, Text);
Text.pop();
}
};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {});
}
}, { name: "Child" });
}
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example6');
Text.onClick(() => {
func1();
{
let b = 1;
}
});
}, Text);
Text.pop();
})
.key((item) => {
func1();
{
let b = 1;
}
return item.toString();
})
.template('1', (repeatItem) => {
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new Child(this, {
build1: () => {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example3');
}, Text);
Text.pop();
}
}, undefined, elmtId, () => { }, { page: "build_ui_in_correct_place.ets", line: 43, col: 15 });
ViewPU.create(componentCall);
let paramsLambda = () => {
return {
build1: () => {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example3');
}, Text);
Text.pop();
}
};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {});
}
}, { name: "Child" });
}
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('example4');
Text.onClick(() => {
func1();
{
let b = 1;
}
});
}, Text);
Text.pop();
}).render(isInitialRender);
}, Repeat);
Column.pop();
};
this.forEachUpdateFunction(elmtId, [1], forEachItemGenFunction, (item) => {
return item.toString();
}, false, false);
}, ForEach);
ForEach.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new Parent(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`;

View File

@ -889,7 +889,19 @@
"concurrent": {
"decorator": "Concurrent"
},
"customComponent": "CustomComponent"
"customComponent": "CustomComponent",
"syntaxComponents": {
"paramsUICallback": [
"ForEach",
"LazyForEach"
],
"attrUICallback": [
{
"name": "Repeat",
"attributes": ["each", "template"]
}
]
}
},
"allowJs": true,
"allowSyntheticDefaultImports": true,