!886 Update for Partial-Update

Merge pull request !886 from laibo102/partial-update-temp
This commit is contained in:
openharmony_ci
2022-09-05 08:48:55 +00:00
committed by Gitee
21 changed files with 3008 additions and 144 deletions
+8
View File
@@ -380,6 +380,9 @@ function loadModuleInfo(projectConfig, envArgs) {
projectConfig.nodeModulesPath = buildJsonInfo.nodeModulesPath;
}
projectConfig.pandaMode = buildJsonInfo.pandaMode;
if (buildJsonInfo.compatibleSdkVersion >= 9) {
partialUpdateConfig.partialUpdateMode = true;
}
}
}
@@ -430,6 +433,10 @@ const globalProgram = {
watchProgram: null
};
const partialUpdateConfig = {
partialUpdateMode: false
};
exports.globalProgram = globalProgram;
exports.projectConfig = projectConfig;
exports.loadEntryObj = loadEntryObj;
@@ -443,3 +450,4 @@ exports.loadModuleInfo = loadModuleInfo;
exports.systemModules = systemModules;
exports.checkAppResourcePath = checkAppResourcePath;
exports.addSDKBuildDependencies = addSDKBuildDependencies;
exports.partialUpdateConfig = partialUpdateConfig;
+1 -1
View File
@@ -13,7 +13,7 @@
"build": "npm run generateSyntaxParser && npm run generateDeclarations && ./node_modules/.bin/babel ./src --out-dir lib --extensions .ts && node uglify-source.js lib",
"create": "node ./lib/create.js --env projectName",
"compile": "webpack --config webpack.config.js --env buildMode=debug projectName",
"test": "npm run build && mocha -r mocha-context/register test/test.js",
"test": "npm run build && mocha -r mocha-context/register test/test.js && mocha -r mocha-context/register test/test.js --partialUpdate",
"generateDeclarations": "node ./build_declarations_file.js ../../../interface/sdk-js/api/@internal/component/ets ./declarations ./lib",
"generateSyntaxParser": "node build_parser.js ./syntax_parser/dist",
"postinstall": "node npm-install.js"
+50
View File
@@ -275,3 +275,53 @@ export const ES2ABC: string = 'es2abc';
export const GENERATE_ID = 'generateId';
export const _GENERATE_ID = '__generate__Id';
export const COMPONENT_CONSTRUCTOR_INITIAL_PARAMS: string = 'setInitiallyProvidedValue';
export const COMPONENT_RERENDER_FUNCTION: string = 'rerender';
export const COMPONENT_CONSTRUCTOR_PURGE_VARIABLE_DEP: string = 'purgeVariableDependenciesOnElmtId';
export const MARKDEPENDENTELEMENTSDIRTY: string = 'markDependentElementsDirty';
export const ABOUT_TO_BE_DELETE_FUNCTION_ID__: string = 'id__';
export const RMELMTID: string = 'rmElmtId';
export const PURGEDEPENDENCYONELMTID: string = 'purgeDependencyOnElmtId';
export const SETPROPERTYUNCHANGED: string = 'SetPropertyUnchanged';
export const ABOUTTOBEDELETEDINTERNAL: string = 'aboutToBeDeletedInternal';
export const UPDATEDIRTYELEMENTS: string = 'updateDirtyElements';
export const BASICDECORATORS: Set<string> = new Set([COMPONENT_STATE_DECORATOR, COMPONENT_PROP_DECORATOR,
COMPONENT_LINK_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR]);
export const LINKS_DECORATORS: Set<string> = new Set([COMPONENT_LINK_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR]);
export const ISINITIALRENDER: string = 'isInitialRender';
export const ELMTID: string = 'elmtId';
export const STARTGETACCESSRECORDINGFOR: string = 'StartGetAccessRecordingFor';
export const STOPGETACCESSRECORDING: string = 'StopGetAccessRecording';
export const VIEWSTACKPROCESSOR: string = 'ViewStackProcessor';
export const OBSERVECOMPONENTCREATION: string = 'observeComponentCreation';
export const ISLAZYCREATE: string = 'isLazyCreate';
export const DEEPRENDERFUNCTION: string = 'deepRenderFunction';
export const ITEMCREATION: string = 'itemCreation';
export const OBSERVEDSHALLOWRENDER: string = 'observedShallowRender';
export const OBSERVEDDEEPRENDER:string = 'observedDeepRender';
export const ItemComponents: string[] = ['ListItem', 'GridItem'];
export const FOREACHITEMGENFUNCTION: string = 'forEachItemGenFunction';
export const __LAZYFOREACHITEMGENFUNCTION: string = '__lazyForEachItemGenFunction';
export const _ITEM: string = '_item';
export const FOREACHITEMIDFUNC: string = 'forEachItemIdFunc';
export const __LAZYFOREACHITEMIDFUNC: string = '__lazyForEachItemIdFunc';
export const FOREACHUPDATEFUNCTION: string = 'forEachUpdateFunction';
export const ALLOCATENEWELMETIDFORNEXTCOMPONENT: string = 'AllocateNewElmetIdForNextComponent';
export const STATE_OBJECTLINK_DECORATORS: string[] = [COMPONENT_STATE_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR];
export const COMPONENT_INITIAl_RENDER_FUNCTION: string = 'initialRender';
export const GRID_COMPONENT: string = 'Grid';
export const GRIDITEM_COMPONENT: string = 'GridItem';
export const WILLUSEPROXY: string = 'willUseProxy';
export const TABCONTENT_COMPONENT: string = 'TabContent';
export const BASE_COMPONENT_NAME_PU: string = 'ViewPU';
export const GLOBAL_THIS: string = 'globalThis';
export const OBSERVED_PROPERTY_SIMPLE_PU: string = 'ObservedPropertySimplePU';
export const OBSERVED_PROPERTY_OBJECT_PU: string = 'ObservedPropertyObjectPU';
export const SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU: string = 'SynchedPropertySimpleOneWayPU';
export const SYNCHED_PROPERTY_SIMPLE_TWO_WAY_PU: string = 'SynchedPropertySimpleTwoWayPU';
export const SYNCHED_PROPERTY_OBJECT_TWO_WAY_PU: string = 'SynchedPropertyObjectTwoWayPU';
export const SYNCHED_PROPERTY_NESED_OBJECT_PU: string = 'SynchedPropertyNesedObjectPU';
export const OBSERVED_PROPERTY_ABSTRACT_PU:string = 'ObservedPropertyAbstractPU';
export const COMPONENT_CONSTRUCTOR_LOCALSTORAGE_PU: string = '__localStorage';
export const COMPONENT_CONSTRUCTOR_LOCALSTORAGE_TYPE_PU: string = 'LocalStorage';
+667 -44
View File
@@ -61,7 +61,31 @@ import {
$$,
PROPERTIES_ADD_DOUBLE_DOLLAR,
ATTRIBUTE_ID,
RESOURCE
RESOURCE,
ISINITIALRENDER,
ELMTID,
VIEWSTACKPROCESSOR,
STOPGETACCESSRECORDING,
STARTGETACCESSRECORDINGFOR,
OBSERVECOMPONENTCREATION,
ISLAZYCREATE,
DEEPRENDERFUNCTION,
ITEMCREATION,
OBSERVEDSHALLOWRENDER,
OBSERVEDDEEPRENDER,
ItemComponents,
FOREACHITEMGENFUNCTION,
__LAZYFOREACHITEMGENFUNCTION,
_ITEM,
FOREACHITEMIDFUNC,
__LAZYFOREACHITEMIDFUNC,
FOREACHUPDATEFUNCTION,
COMPONENT_INITIAl_RENDER_FUNCTION,
GRIDITEM_COMPONENT,
GRID_COMPONENT,
WILLUSEPROXY,
TABCONTENT_COMPONENT,
GLOBAL_THIS
} from './pre_define';
import {
INNER_COMPONENT_NAMES,
@@ -92,7 +116,7 @@ import {
componentInfo,
createFunction
} from './utils';
import { projectConfig } from '../main';
import { partialUpdateConfig, projectConfig } from '../main';
import { transformLog, contextGlobal } from './process_ui_syntax';
import { props } from './compile_info';
import { CUSTOM_COMPONENT } from '../lib/pre_define';
@@ -100,7 +124,12 @@ import { CUSTOM_COMPONENT } from '../lib/pre_define';
export function processComponentBuild(node: ts.MethodDeclaration,
log: LogInfo[]): ts.MethodDeclaration {
let newNode: ts.MethodDeclaration;
const renderNode: ts.Identifier = ts.factory.createIdentifier(COMPONENT_RENDER_FUNCTION);
let renderNode: ts.Identifier;
if (!partialUpdateConfig.partialUpdateMode) {
renderNode = ts.factory.createIdentifier(COMPONENT_RENDER_FUNCTION);
} else {
renderNode = ts.factory.createIdentifier(COMPONENT_INITIAl_RENDER_FUNCTION);
}
if (node.body && node.body.statements && node.body.statements.length &&
validateRootNode(node, log)) {
newNode = ts.factory.updateMethodDeclaration(node, node.decorators, node.modifiers,
@@ -119,7 +148,7 @@ export function processComponentBlock(node: ts.Block, isLazy: boolean, log: LogI
const newStatements: ts.Statement[] = [];
processComponentChild(node, newStatements, log,
{isAcceleratePreview: false, line: 0, column: 0, fileName: ''}, isInnerBuilder, parent);
if (isLazy) {
if (isLazy && !partialUpdateConfig.partialUpdateMode) {
newStatements.unshift(createRenderingInProgress(true));
}
if (isTransition) {
@@ -130,7 +159,7 @@ export function processComponentBlock(node: ts.Block, isLazy: boolean, log: LogI
createFunction(ts.factory.createIdentifier(COMPONENT_TRANSITION_NAME),
ts.factory.createIdentifier(COMPONENT_POP_FUNCTION), null)));
}
if (isLazy) {
if (isLazy && !partialUpdateConfig.partialUpdateMode) {
newStatements.push(createRenderingInProgress(false));
}
return ts.factory.updateBlock(node, newStatements);
@@ -254,7 +283,11 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
break;
case ComponentType.forEachComponent:
parent = undefined;
processForEachComponent(item, newStatements, log, isInnerBuilder);
if (!partialUpdateConfig.partialUpdateMode) {
processForEachComponent(item, newStatements, log, isInnerBuilder);
} else {
processForEachComponentNew(item, newStatements, log);
}
break;
case ComponentType.customBuilderMethod:
parent = undefined;
@@ -374,38 +407,28 @@ function parseEtsComponentExpression(node: ts.ExpressionStatement): EtsComponent
return { etsComponentNode: etsComponentNode, hasAttr: hasAttr };
}
function processInnerComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[],
function processInnerComponent(node: ts.ExpressionStatement, innerCompStatements: ts.Statement[],
log: LogInfo[], parent: string = undefined): void {
const newStatements: ts.Statement[] = [];
const res: CreateResult = createComponent(node, COMPONENT_CREATE_FUNCTION);
newStatements.push(res.newNode);
const nameResult: NameResult = { name: null };
validateEtsComponentNode(node.expression as ts.EtsComponentExpression, nameResult);
if (projectConfig.isPreview && nameResult.name && !NO_DEBUG_LINE_COMPONENT.has(nameResult.name)) {
let posOfNode: ts.LineAndCharacter;
let curFileName: string;
let line: number = 1;
let col: number = 1;
if (newsupplement.isAcceleratePreview) {
posOfNode = sourceNode.getLineAndCharacterOfPosition(getRealNodePos(node));
curFileName = newsupplement.fileName;
if (posOfNode.line === 0) {
col = newsupplement.column - 15;
}
line = newsupplement.line;
} else {
posOfNode = transformLog.sourceFile.getLineAndCharacterOfPosition(getRealNodePos(node));
curFileName = transformLog.sourceFile.fileName.replace(/\.ts$/, '');
}
const projectPath: string = projectConfig.projectPath;
const debugInfo: string =
`${path.relative(projectPath, curFileName).replace(/\\+/g, '/')}` +
`(${posOfNode.line + line}:${posOfNode.character + col})`;
const debugNode: ts.ExpressionStatement = ts.factory.createExpressionStatement(
createFunction(ts.factory.createIdentifier(nameResult.name),
ts.factory.createIdentifier(COMPONENT_DEBUGLINE_FUNCTION),
ts.factory.createNodeArray([ts.factory.createStringLiteral(debugInfo)])));
newStatements.push(debugNode);
if (partialUpdateConfig.partialUpdateMode && ItemComponents.includes(nameResult.name)) {
processItemComponent(node, nameResult, innerCompStatements, log);
} else if (partialUpdateConfig.partialUpdateMode && TABCONTENT_COMPONENT.includes(nameResult.name)) {
processTabContent(node, innerCompStatements, log);
} else {
processNormalComponent(node, nameResult, innerCompStatements, log, parent);
}
}
function processNormalComponent(node: ts.ExpressionStatement, nameResult: NameResult,
innerCompStatements: ts.Statement[], log: LogInfo[], parent: string = undefined): void {
const newStatements: ts.Statement[] = [];
const res: CreateResult = createComponent(node, COMPONENT_CREATE_FUNCTION);
newStatements.push(res.newNode);
processDebug(node, nameResult, newStatements);
const etsComponentResult: EtsComponentResult = parseEtsComponentExpression(node);
if (PROPERTIES_ADD_DOUBLE_DOLLAR.has(res.identifierNode.getText()) &&
etsComponentResult.etsComponentNode.arguments && etsComponentResult.etsComponentNode.arguments.length) {
@@ -424,16 +447,426 @@ function processInnerComponent(node: ts.ExpressionStatement, newStatements: ts.S
if (etsComponentResult.hasAttr) {
bindComponentAttr(node, res.identifierNode, newStatements, log);
}
processComponentChild(etsComponentResult.etsComponentNode.body, newStatements, log,
processInnerCompStatements(innerCompStatements, newStatements, node);
processComponentChild(etsComponentResult.etsComponentNode.body, innerCompStatements, log,
{isAcceleratePreview: false, line: 0, column: 0, fileName: ''}, false, parent);
} else {
bindComponentAttr(node, res.identifierNode, newStatements, log);
processInnerCompStatements(innerCompStatements, newStatements, node);
}
if (res.isContainerComponent || res.needPop) {
newStatements.push(createComponent(node, COMPONENT_POP_FUNCTION).newNode);
innerCompStatements.push(createComponent(node, COMPONENT_POP_FUNCTION).newNode);
}
}
function processDebug(node: ts.Statement, nameResult: NameResult, newStatements: ts.Statement[]): void {
if (projectConfig.isPreview && nameResult.name && !NO_DEBUG_LINE_COMPONENT.has(nameResult.name)) {
let posOfNode: ts.LineAndCharacter;
let curFileName: string;
let line: number = 1;
let col: number = 1;
if (newsupplement.isAcceleratePreview) {
posOfNode = sourceNode.getLineAndCharacterOfPosition(getRealNodePos(node));
curFileName = newsupplement.fileName;
if (posOfNode.line === 0) {
col = newsupplement.column - 15;
}
line = newsupplement.line;
} else {
posOfNode = transformLog.sourceFile.getLineAndCharacterOfPosition(getRealNodePos(node));
curFileName = transformLog.sourceFile.fileName.replace(/\.ts$/, '');
}
const projectPath: string = projectConfig.projectPath;
const debugInfo: string = `${path.relative(projectPath, curFileName).replace(/\\+/g, '/')}` +
`(${posOfNode.line + line}:${posOfNode.character + col})`;
const debugNode: ts.ExpressionStatement = ts.factory.createExpressionStatement(
createFunction(ts.factory.createIdentifier(nameResult.name),
ts.factory.createIdentifier(COMPONENT_DEBUGLINE_FUNCTION),
ts.factory.createNodeArray([ts.factory.createStringLiteral(debugInfo)])));
newStatements.push(debugNode);
}
}
function processInnerCompStatements(
innerCompStatements: ts.Statement[],
newStatements: ts.Statement[],
node: ts.Statement
): void {
if (!partialUpdateConfig.partialUpdateMode) {
innerCompStatements.push(...newStatements);
} else {
innerCompStatements.push(createComponentCreationStatement(node, newStatements));
}
}
function createComponentCreationStatement(node: ts.Statement, innerStatements: ts.Statement[]): ts.Statement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(OBSERVECOMPONENTCREATION)
), undefined,
[ts.factory.createArrowFunction(undefined, undefined,
[
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ELMTID), undefined, undefined, undefined),
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ISINITIALRENDER), undefined, undefined, undefined)
], undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock(
[
createViewStackProcessorStatement(STARTGETACCESSRECORDINGFOR, ELMTID),
...innerStatements,
createInitRenderStatement(node),
createViewStackProcessorStatement(STOPGETACCESSRECORDING)
],
true
)
)]
)
);
}
function createViewStackProcessorStatement(propertyAccessName: string, elmtId?: string): ts.Statement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(VIEWSTACKPROCESSOR),
ts.factory.createIdentifier(propertyAccessName)
),
undefined,
elmtId ? [ts.factory.createIdentifier(ELMTID)] : []
)
);
}
function createInitRenderStatement(node: ts.Statement): ts.Statement {
return ts.factory.createIfStatement(
ts.factory.createPrefixUnaryExpression(
ts.SyntaxKind.ExclamationToken,
ts.factory.createIdentifier(ISINITIALRENDER)
),
ts.factory.createBlock(
[
ts.isExpressionStatement(node) ?
createComponent(node, COMPONENT_POP_FUNCTION).newNode : createIfPop()
],
true
)
);
}
function processItemComponent(node: ts.ExpressionStatement, nameResult: NameResult, innerCompStatements: ts.Statement[],
log: LogInfo[]): void {
const itemRenderInnerStatements: ts.Statement[] = [];
const deepItemRenderInnerStatements: ts.Statement[] = [];
const res: CreateResult = createComponent(node, COMPONENT_CREATE_FUNCTION);
const itemCreateStatement: ts.Statement = createItemCreate(nameResult);
itemRenderInnerStatements.push(itemCreateStatement);
processDebug(node, nameResult, innerCompStatements);
const etsComponentResult: EtsComponentResult = parseEtsComponentExpression(node);
if (etsComponentResult.etsComponentNode.body && ts.isBlock(etsComponentResult.etsComponentNode.body)) {
if (etsComponentResult.hasAttr) {
bindComponentAttr(node, res.identifierNode, itemRenderInnerStatements, log);
}
processComponentChild(etsComponentResult.etsComponentNode.body, deepItemRenderInnerStatements, log);
} else {
bindComponentAttr(node, res.identifierNode, itemRenderInnerStatements, log);
}
innerCompStatements.push(createItemBlock(node, itemRenderInnerStatements, deepItemRenderInnerStatements));
}
function createItemCreate(nameResult: NameResult): ts.Statement {
return ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(nameResult.name),
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION)), undefined,
[ts.factory.createIdentifier(DEEPRENDERFUNCTION), ts.factory.createIdentifier(ISLAZYCREATE)]));
}
function createItemBlock(
node: ts.ExpressionStatement,
itemRenderInnerStatements: ts.Statement[],
deepItemRenderInnerStatements: ts.Statement[]
): ts.Block {
return ts.factory.createBlock(
[
createIsLazyCreate(node),
createItemCreation(node, itemRenderInnerStatements),
createObservedShallowRender(node, itemRenderInnerStatements),
createObservedDeepRender(node, deepItemRenderInnerStatements),
createDeepRenderFunction(node, deepItemRenderInnerStatements),
ts.factory.createIfStatement(
ts.factory.createIdentifier(ISLAZYCREATE),
ts.factory.createBlock(
[ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createIdentifier(OBSERVEDSHALLOWRENDER), undefined, []))], true),
ts.factory.createBlock(
[ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createIdentifier(OBSERVEDDEEPRENDER), undefined, []))], true)
)
],
true
);
}
function createIsLazyCreate(node: ts.ExpressionStatement): ts.VariableStatement {
const etsComponent: ts.EtsComponentExpression = getEtsComponentExpression(node);
if (etsComponent) {
if ((etsComponent.expression as ts.Identifier).escapedText.toString() === GRIDITEM_COMPONENT) {
if (etsComponent.arguments[0] && (etsComponent.arguments[0] as ts.StringLiteral).text === 'false') {
return createIsLazyWithValue(false);
} else if (isLazyForEachChild(node)) {
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(ISLAZYCREATE), undefined, undefined,
ts.factory.createBinaryExpression(ts.factory.createBinaryExpression(
ts.factory.createParenthesizedExpression(ts.factory.createBinaryExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(GLOBAL_THIS),
ts.factory.createIdentifier(__LAZYFOREACHITEMGENFUNCTION)), ts.factory.createToken(
ts.SyntaxKind.ExclamationEqualsEqualsToken), ts.factory.createIdentifier(COMPONENT_IF_UNDEFINED))),
ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken), ts.factory.createTrue()),
ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken),
ts.factory.createParenthesizedExpression(ts.factory.createBinaryExpression(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(GRID_COMPONENT), ts.factory.createIdentifier(WILLUSEPROXY)),
undefined, []), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
ts.factory.createTrue()))))],ts.NodeFlags.Const));
} else {
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(ISLAZYCREATE), undefined, undefined,
ts.factory.createBinaryExpression(
ts.factory.createTrue(), ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken),
ts.factory.createParenthesizedExpression(ts.factory.createBinaryExpression(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(GRID_COMPONENT), ts.factory.createIdentifier(WILLUSEPROXY)
), undefined, []), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
ts.factory.createTrue()))))], ts.NodeFlags.Const));
}
} else {
if (etsComponent.arguments[0] && (etsComponent.arguments[0] as ts.StringLiteral).text === 'false') {
return createIsLazyWithValue(false);
} else if (isLazyForEachChild(node)) {
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(ISLAZYCREATE), undefined, undefined,
ts.factory.createBinaryExpression(ts.factory.createParenthesizedExpression(
ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(
GLOBAL_THIS), ts.factory.createIdentifier(__LAZYFOREACHITEMGENFUNCTION)), ts.factory.createToken(
ts.SyntaxKind.ExclamationEqualsEqualsToken), ts.factory.createIdentifier(COMPONENT_IF_UNDEFINED))),
ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken), ts.factory.createTrue()))],
ts.NodeFlags.Const));
} else {
return createIsLazyWithValue(true);
}
}
}
}
function createItemCreation(
node: ts.ExpressionStatement,
itemRenderInnerStatements: ts.Statement[]
): ts.VariableStatement {
return ts.factory.createVariableStatement(
undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(ITEMCREATION), undefined, undefined,
ts.factory.createArrowFunction(undefined, undefined,
[
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ELMTID), undefined, undefined, undefined),
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ISINITIALRENDER), undefined, undefined, undefined)
], undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock(
[
createViewStackProcessorStatement(STARTGETACCESSRECORDINGFOR, ELMTID),
...itemRenderInnerStatements,
ts.factory.createIfStatement(
ts.factory.createPrefixUnaryExpression(
ts.SyntaxKind.ExclamationToken,
ts.factory.createIdentifier(ISINITIALRENDER)
),
ts.factory.createBlock(
[createComponent(node, COMPONENT_POP_FUNCTION).newNode],
true
)
),
createViewStackProcessorStatement(STOPGETACCESSRECORDING)
],
true
)
)
)],
ts.NodeFlags.Const
)
);
}
function createDeepRenderFunction(
node: ts.ExpressionStatement,
deepItemRenderInnerStatements: ts.Statement[]
): ts.VariableStatement {
return ts.factory.createVariableStatement(
undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(DEEPRENDERFUNCTION), undefined, undefined,
ts.factory.createArrowFunction(undefined, undefined,
[
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ELMTID), undefined, undefined, undefined),
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ISINITIALRENDER), undefined, undefined, undefined)
], undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock(
[
ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createIdentifier(ITEMCREATION), undefined,
[
ts.factory.createIdentifier(ELMTID),
ts.factory.createIdentifier(ISINITIALRENDER)
]
)),
ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier('updateFuncByElmtId')
),
ts.factory.createIdentifier('set')
), undefined,
[ts.factory.createIdentifier(ELMTID), ts.factory.createIdentifier(ITEMCREATION)]
)),
...deepItemRenderInnerStatements,
createComponent(node, COMPONENT_POP_FUNCTION).newNode
],
true
)
)
)],
ts.NodeFlags.Const
)
);
}
function createObservedShallowRender(
node: ts.ExpressionStatement,
itemRenderInnerStatements: ts.Statement[]
): ts.VariableStatement {
return ts.factory.createVariableStatement(undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(OBSERVEDSHALLOWRENDER), undefined, undefined,
ts.factory.createArrowFunction(undefined, undefined, [], undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock(
[
ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(OBSERVECOMPONENTCREATION)
), undefined,
[ts.factory.createArrowFunction(undefined, undefined,
[
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ELMTID), undefined, undefined, undefined),
ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(ISINITIALRENDER), undefined, undefined, undefined)
], undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock(
[createViewStackProcessorStatement(STARTGETACCESSRECORDINGFOR, ELMTID),
itemRenderInnerStatements[0],
ts.factory.createIfStatement(
ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.ExclamationToken,
ts.factory.createIdentifier(ISINITIALRENDER)),
ts.factory.createBlock(
[createComponent(node, COMPONENT_POP_FUNCTION).newNode], true)),
createViewStackProcessorStatement(STOPGETACCESSRECORDING)], true
)
)]
)),
createComponent(node, COMPONENT_POP_FUNCTION).newNode
],
true
)
)
)],
ts.NodeFlags.Const
)
);
}
function createObservedDeepRender(
node: ts.ExpressionStatement,
deepItemRenderInnerStatements: ts.Statement[]
): ts.VariableStatement {
return ts.factory.createVariableStatement(
undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(OBSERVEDDEEPRENDER),
undefined,
undefined,
ts.factory.createArrowFunction(
undefined,
undefined,
[],
undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock(
[
ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(OBSERVECOMPONENTCREATION)
),
undefined,
[ts.factory.createIdentifier(ITEMCREATION)]
)),
...deepItemRenderInnerStatements,
createComponent(node, COMPONENT_POP_FUNCTION).newNode
],
true
)
)
)],
ts.NodeFlags.Const
)
);
}
function processTabContent(node: ts.ExpressionStatement, innerCompStatements: ts.Statement[], log: LogInfo[]): void {
const TabContentComp: ts.EtsComponentExpression = getEtsComponentExpression(node);
const TabContentBody: ts.Block = TabContentComp.body;
let tabContentCreation: ts.Statement;
const tabContentPop: ts.Statement = ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(TABCONTENT_COMPONENT),
ts.factory.createIdentifier(COMPONENT_POP_FUNCTION)), undefined, []));
const tabAttrs: ts.Statement[] = [];
if (TabContentBody && TabContentBody.statements.length) {
const newTabContentChildren: ts.Statement[] = [];
processComponentChild(TabContentBody, newTabContentChildren, log);
tabContentCreation = ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(TABCONTENT_COMPONENT), ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION)),
undefined, [ts.factory.createArrowFunction(undefined, undefined, [], undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock([...newTabContentChildren], true))]));
bindComponentAttr(node, ts.factory.createIdentifier(TABCONTENT_COMPONENT), tabAttrs, log);
processInnerCompStatements(innerCompStatements, [tabContentCreation, ...tabAttrs], node);
} else {
tabContentCreation = ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(TABCONTENT_COMPONENT),
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION)), undefined, []));
bindComponentAttr(node, ts.factory.createIdentifier(TABCONTENT_COMPONENT), tabAttrs, log);
processInnerCompStatements(innerCompStatements, [tabContentCreation, ...tabAttrs], node);
}
innerCompStatements.push(tabContentPop);
}
function getRealNodePos(node: ts.Node): number {
// @ts-ignore
if (node.pos === -1 && node.expression) {
@@ -463,7 +896,8 @@ function processForEachComponent(node: ts.ExpressionStatement, newStatements: ts
ts.factory.createIdentifier(FOREACH_GET_RAW_OBJECT)), undefined, [argumentsArray[0]]);
}
argumentsArray.splice(0, 1, arrayObserveredObject);
const newArrowNode: ts.ArrowFunction = processForEachBlock(node.expression, log, isInnerBuilder);
const newArrowNode: ts.ArrowFunction =
processForEachBlock(node.expression, log, isInnerBuilder) as ts.ArrowFunction;
if (newArrowNode) {
argumentsArray.splice(1, 1, newArrowNode);
}
@@ -473,6 +907,160 @@ function processForEachComponent(node: ts.ExpressionStatement, newStatements: ts
newStatements.push(node, popNode);
}
function processForEachComponentNew(node: ts.ExpressionStatement, newStatements: ts.Statement[],
log: LogInfo[]): void {
const newForEachStatements: ts.Statement[] = [];
const popNode: ts.ExpressionStatement = ts.factory.createExpressionStatement(createFunction(
(node.expression as ts.CallExpression).expression as ts.Identifier,
ts.factory.createIdentifier(COMPONENT_POP_FUNCTION), null));
if (ts.isCallExpression(node.expression)) {
const argumentsArray: ts.Expression[] = Array.from(node.expression.arguments);
const propertyNode: ts.ExpressionStatement = ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
node.expression.expression as ts.Identifier,
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION)), undefined, []));
const newArrowNode: ts.NodeArray<ts.Statement> =
processForEachBlock(node.expression, log) as ts.NodeArray<ts.Statement>;
const itemGenFunctionStatement: ts.VariableStatement = createItemGenFunctionStatement(node.expression,
argumentsArray, newArrowNode);
const itemIdFuncStatement: ts.VariableStatement = createItemIdFuncStatement(node.expression, argumentsArray);
const updateFunctionStatement: ts.ExpressionStatement = createUpdateFunctionStatement(argumentsArray);
const lazyForEachStatement: ts.ExpressionStatement = createLazyForEachStatement(argumentsArray);
if (node.expression.expression.getText() === COMPONENT_FOREACH) {
if (argumentsArray[2]) {
newForEachStatements.push(propertyNode, itemGenFunctionStatement, itemIdFuncStatement, updateFunctionStatement);
} else {
newForEachStatements.push(propertyNode, itemGenFunctionStatement, updateFunctionStatement);
}
newStatements.push(createComponentCreationStatement(node, newForEachStatements), popNode);
} else {
if (argumentsArray[2]) {
newStatements.push(ts.factory.createBlock([itemGenFunctionStatement, itemIdFuncStatement, lazyForEachStatement,
popNode], true));
} else {
newStatements.push(ts.factory.createBlock([itemGenFunctionStatement, lazyForEachStatement, popNode], true));
}
}
}
}
function createItemGenFunctionStatement(
node: ts.CallExpression,
argumentsArray: ts.Expression[],
newArrowNode: ts.NodeArray<ts.Statement>
): ts.VariableStatement {
if (argumentsArray[1] && ts.isArrowFunction(argumentsArray[1])) {
return ts.factory.createVariableStatement(
undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(node.expression.getText() === COMPONENT_FOREACH ?
FOREACHITEMGENFUNCTION : __LAZYFOREACHITEMGENFUNCTION),
undefined, undefined,
ts.factory.createArrowFunction(
undefined, undefined,
[ts.factory.createParameterDeclaration(
undefined, undefined, undefined, ts.factory.createIdentifier(_ITEM))],
undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createBlock(
[ts.factory.createVariableStatement(
undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(
argumentsArray[1].parameters[0] && argumentsArray[1].parameters[0].name.getText()),
undefined,
undefined,
ts.factory.createIdentifier(_ITEM)
)],
ts.NodeFlags.Const
)
),
...newArrowNode
],
true
)
)
)
],
ts.NodeFlags.Const
)
);
}
}
function createItemIdFuncStatement(
node: ts.CallExpression,
argumentsArray: ts.Expression[]
): ts.VariableStatement {
if (argumentsArray[2] && ts.isArrowFunction(argumentsArray[2])) {
return ts.factory.createVariableStatement(
undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(node.expression.getText() === COMPONENT_FOREACH ?
FOREACHITEMIDFUNC : __LAZYFOREACHITEMIDFUNC), undefined, undefined,
ts.factory.createArrowFunction(
undefined, undefined,
[ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(
argumentsArray[2].parameters[0] ? argumentsArray[2].parameters[0].name.escapedText : ''
)
)], undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createIdentifier(argumentsArray[2].body ? argumentsArray[2].body.getText() : '')
)
)],
ts.NodeFlags.Const
)
);
}
}
function createUpdateFunctionStatement(argumentsArray: ts.Expression[]): ts.ExpressionStatement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(FOREACHUPDATEFUNCTION)
),
undefined,
addForEachIdFuncParameter(argumentsArray)
)
);
}
function addForEachIdFuncParameter(argumentsArray: ts.Expression[]): ts.Identifier[] {
const addForEachIdFuncParameterArr: ts.Identifier[] = [];
addForEachIdFuncParameterArr.push(
ts.factory.createIdentifier(ELMTID),
ts.factory.createIdentifier(argumentsArray[0] && argumentsArray[0].getText())
);
addForEachIdFuncParameterArr.push(ts.factory.createIdentifier(FOREACHITEMGENFUNCTION));
if (argumentsArray[2]) {
addForEachIdFuncParameterArr.push(ts.factory.createIdentifier(FOREACHITEMIDFUNC));
}
return addForEachIdFuncParameterArr;
}
function createLazyForEachStatement(argumentsArray: ts.Expression[]): ts.ExpressionStatement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(COMPONENT_LAZYFOREACH),
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION)
),
undefined,
[ts.factory.createStringLiteral(componentInfo.id.toString()),
ts.factory.createThis(),
argumentsArray[0],
ts.factory.createIdentifier(__LAZYFOREACHITEMGENFUNCTION),
ts.factory.createIdentifier(__LAZYFOREACHITEMIDFUNC)
]
)
);
}
function addForEachId(node: ts.ExpressionStatement): ts.ExpressionStatement {
const forEachComponent: ts.CallExpression = node.expression as ts.CallExpression;
return ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression(
@@ -482,7 +1070,7 @@ function addForEachId(node: ts.ExpressionStatement): ts.ExpressionStatement {
}
function processForEachBlock(node: ts.CallExpression, log: LogInfo[],
isInnerBuilder: boolean = false): ts.ArrowFunction {
isInnerBuilder: boolean = false): ts.NodeArray<ts.Statement> | ts.ArrowFunction {
if (node.arguments.length > 1 && ts.isArrowFunction(node.arguments[1])) {
const isLazy: boolean = node.expression.getText() === COMPONENT_LAZYFOREACH;
const arrowNode: ts.ArrowFunction = node.arguments[1] as ts.ArrowFunction;
@@ -498,14 +1086,22 @@ function processForEachBlock(node: ts.CallExpression, log: LogInfo[],
const blockNode: ts.Block = ts.factory.createBlock([statement], true);
// @ts-ignore
statement.parent = blockNode;
return ts.factory.updateArrowFunction(
arrowNode, arrowNode.modifiers, arrowNode.typeParameters, arrowNode.parameters,
arrowNode.type, arrowNode.equalsGreaterThanToken, processComponentBlock(blockNode, isLazy, log));
if (!partialUpdateConfig.partialUpdateMode) {
return ts.factory.updateArrowFunction(
arrowNode, arrowNode.modifiers, arrowNode.typeParameters, arrowNode.parameters,
arrowNode.type, arrowNode.equalsGreaterThanToken, processComponentBlock(blockNode, isLazy, log));
} else {
return processComponentBlock(blockNode, isLazy, log).statements;
}
} else {
return ts.factory.updateArrowFunction(
arrowNode, arrowNode.modifiers, arrowNode.typeParameters, arrowNode.parameters,
arrowNode.type, arrowNode.equalsGreaterThanToken,
processComponentBlock(body, isLazy, log, false, isInnerBuilder));
if (!partialUpdateConfig.partialUpdateMode) {
return ts.factory.updateArrowFunction(
arrowNode, arrowNode.modifiers, arrowNode.typeParameters, arrowNode.parameters,
arrowNode.type, arrowNode.equalsGreaterThanToken,
processComponentBlock(body, isLazy, log, false, isInnerBuilder));
} else {
return processComponentBlock(body, isLazy, log).statements;
}
}
}
return null;
@@ -527,7 +1123,11 @@ function processIfStatement(node: ts.IfStatement, newStatements: ts.Statement[],
const ifCreate: ts.ExpressionStatement = createIfCreate();
const newIfNode: ts.IfStatement = processInnerIfStatement(node, 0, log, isInnerBuilder);
const ifPop: ts.ExpressionStatement = createIfPop();
newStatements.push(ifCreate, newIfNode, ifPop);
if (!partialUpdateConfig.partialUpdateMode) {
newStatements.push(ifCreate, newIfNode, ifPop);
} else {
newStatements.push(createComponentCreationStatement(node, [ifCreate, newIfNode]), ifPop);
}
}
function processInnerIfStatement(node: ts.IfStatement, id: number, log: LogInfo[],
@@ -1404,3 +2004,26 @@ function checkButtonParamHasLabel(node: ts.EtsComponentExpression, log: LogInfo[
}
}
}
function isLazyForEachChild(node: ts.ExpressionStatement): boolean {
let temp: any = node.parent;
while(temp && !ts.isEtsComponentExpression(temp) && !ts.isCallExpression(temp)) {
temp = temp.parent;
}
if (temp && temp.expression && (temp.expression as ts.Identifier).escapedText.toString() === COMPONENT_LAZYFOREACH) {
return true;
}
return false;
}
function createIsLazyWithValue(value: boolean): ts.VariableStatement {
if (value) {
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(ISLAZYCREATE),
undefined, undefined, ts.factory.createTrue())], ts.NodeFlags.Const));
} else {
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(ISLAZYCREATE),
undefined, undefined, ts.factory.createFalse())], ts.NodeFlags.Const));
}
}
+246 -45
View File
@@ -33,10 +33,13 @@ import {
BASE_COMPONENT_NAME,
CREATE_CONSTRUCTOR_PARAMS,
COMPONENT_CONSTRUCTOR_UPDATE_PARAMS,
COMPONENT_CONSTRUCTOR_INITIAL_PARAMS,
COMPONENT_CONSTRUCTOR_PURGE_VARIABLE_DEP,
COMPONENT_CONSTRUCTOR_DELETE_PARAMS,
COMPONENT_DECORATOR_PREVIEW,
CREATE_CONSTRUCTOR_SUBSCRIBER_MANAGER,
ABOUT_TO_BE_DELETE_FUNCTION_ID,
ABOUT_TO_BE_DELETE_FUNCTION_ID__,
CREATE_CONSTRUCTOR_GET_FUNCTION,
CREATE_CONSTRUCTOR_DELETE_FUNCTION,
FOREACH_OBSERVED_OBJECT,
@@ -58,7 +61,19 @@ import {
CUSTOM_COMPONENT,
COMPONENT_CONSTRUCTOR_PARENT,
COMPONENT_IF_UNDEFINED,
INNER_COMPONENT_MEMBER_DECORATORS
INNER_COMPONENT_MEMBER_DECORATORS,
COMPONENT_RERENDER_FUNCTION,
RMELMTID,
ABOUTTOBEDELETEDINTERNAL,
UPDATEDIRTYELEMENTS,
LINKS_DECORATORS,
BASE_COMPONENT_NAME_PU,
OBSERVED_PROPERTY_SIMPLE_PU,
OBSERVED_PROPERTY_OBJECT_PU,
SYNCHED_PROPERTY_SIMPLE_TWO_WAY_PU,
SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
SYNCHED_PROPERTY_NESED_OBJECT_PU,
OBSERVED_PROPERTY_ABSTRACT_PU
} from './pre_define';
import {
BUILDIN_STYLE_NAMES,
@@ -72,7 +87,8 @@ import {
componentCollection,
linkCollection,
localStorageLinkCollection,
localStoragePropCollection
localStoragePropCollection,
propCollection
} from './validate_ui_syntax';
import {
addConstructor,
@@ -96,6 +112,7 @@ import {
LogInfo,
hasDecorator
} from './utils';
import { partialUpdateConfig } from '../main';
export function processComponentClass(node: ts.StructDeclaration, context: ts.TransformationContext,
log: LogInfo[], program: ts.Program): ts.ClassDeclaration {
@@ -130,6 +147,8 @@ function processMembers(members: ts.NodeArray<ts.ClassElement>, parentComponentN
const newMembers: ts.ClassElement[] = [];
const watchMap: Map<string, ts.Node> = new Map();
const updateParamsStatements: ts.Statement[] = [];
const purgeVariableDepStatements: ts.Statement[] = [];
const rerenderStatements: ts.Statement[] = [];
const deleteParamsStatements: ts.PropertyDeclaration[] = [];
const checkController: ControllerType =
{ hasController: !componentCollection.customDialogs.has(parentComponentName.getText()) };
@@ -168,6 +187,7 @@ function processMembers(members: ts.NodeArray<ts.ClassElement>, parentComponentN
if (result.getControllerSet()) {
newMembers.push(result.getControllerSet());
}
processPropertyUnchanged(result, purgeVariableDepStatements, rerenderStatements);
}
}
if (ts.isMethodDeclaration(item) && item.name) {
@@ -182,7 +202,8 @@ function processMembers(members: ts.NodeArray<ts.ClassElement>, parentComponentN
validateBuildMethodCount(buildCount, parentComponentName, log);
validateHasController(parentComponentName, checkController, log);
newMembers.unshift(addDeleteParamsFunc(deleteParamsStatements));
newMembers.unshift(addUpdateParamsFunc(updateParamsStatements, parentComponentName));
addIntoNewMembers(newMembers, parentComponentName, updateParamsStatements,
purgeVariableDepStatements, rerenderStatements);
newMembers.unshift(addConstructor(ctorNode, watchMap, parentComponentName));
return newMembers;
}
@@ -202,6 +223,39 @@ function validateDecorators(item: ts.ClassElement, log: LogInfo[]): void {
}
}
function processPropertyUnchanged(
result: UpdateResult,
purgeVariableDepStatements: ts.Statement[],
rerenderStatements: ts.Statement[]
): void {
if (partialUpdateConfig.partialUpdateMode) {
if(result.getPurgeVariableDepStatement()) {
purgeVariableDepStatements.push(result.getPurgeVariableDepStatement());
}
if(result.getRerenderStatement()) {
rerenderStatements.push(result.getRerenderStatement());
}
}
}
function addIntoNewMembers(
newMembers: ts.ClassElement[],
parentComponentName: ts.Identifier,
updateParamsStatements: ts.Statement[],
purgeVariableDepStatements: ts.Statement[],
rerenderStatements: ts.Statement[]
): void {
if (partialUpdateConfig.partialUpdateMode) {
newMembers.unshift(
addInitialParamsFunc(updateParamsStatements, parentComponentName),
addPurgeVariableDepFunc(purgeVariableDepStatements)
);
newMembers.push(addRerenderFunc(rerenderStatements));
} else {
newMembers.unshift(addUpdateParamsFunc(updateParamsStatements, parentComponentName));
}
}
function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[],
program: ts.Program, parentComponentName: string, log: LogInfo[]): void {
const propertyItem: ts.PropertyDeclaration = item as ts.PropertyDeclaration;
@@ -216,38 +270,16 @@ function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[],
let newType: ts.TypeNode;
decoratorName = propertyItem.decorators[i].getText().replace(/\(.*\)$/, '').trim();
let isLocalStorage: boolean = false;
switch (decoratorName) {
case COMPONENT_STATE_DECORATOR:
case COMPONENT_PROVIDE_DECORATOR:
newType = ts.factory.createTypeReferenceNode(isSimpleType(type, program, log) ?
OBSERVED_PROPERTY_SIMPLE : OBSERVED_PROPERTY_OBJECT, [type ||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]);
break;
case COMPONENT_LINK_DECORATOR:
case COMPONENT_CONSUME_DECORATOR:
newType = ts.factory.createTypeReferenceNode(isSimpleType(type, program, log) ?
SYNCHED_PROPERTY_SIMPLE_TWO_WAY : SYNCHED_PROPERTY_SIMPLE_ONE_WAY, [type ||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]);
break;
case COMPONENT_PROP_DECORATOR:
newType = ts.factory.createTypeReferenceNode(SYNCHED_PROPERTY_SIMPLE_ONE_WAY, [type ||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]);
break;
case COMPONENT_OBJECT_LINK_DECORATOR:
newType = ts.factory.createTypeReferenceNode(SYNCHED_PROPERTY_NESED_OBJECT, [type ||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]);
break;
case COMPONENT_STORAGE_PROP_DECORATOR:
case COMPONENT_STORAGE_LINK_DECORATOR:
newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [type ||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]);
break;
case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR:
case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR:
newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [type ||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]);
isLocalStorage = true;
break;
if (!partialUpdateConfig.partialUpdateMode) {
newType = createTypeReference(decoratorName, type, log, program);
} else {
newType = createTypeReferencePU(decoratorName, type, log, program);
}
if (
decoratorName === COMPONENT_LOCAL_STORAGE_LINK_DECORATOR ||
decoratorName === COMPONENT_LOCAL_STORAGE_PROP_DECORATOR
) {
isLocalStorage = true;
}
updatePropertyItem = createPropertyDeclaration(propertyItem, newType, false,
isLocalStorage, parentComponentName);
@@ -430,10 +462,7 @@ function updateHeritageClauses(node: ts.StructDeclaration, log: LogInfo[])
});
}
const result:ts.HeritageClause[] = [];
const heritageClause:ts.HeritageClause = ts.factory.createHeritageClause(
ts.SyntaxKind.ExtendsKeyword,
[ts.factory.createExpressionWithTypeArguments(
ts.factory.createIdentifier(BASE_COMPONENT_NAME), [])]);
const heritageClause:ts.HeritageClause = createHeritageClause();
result.push(heritageClause);
return ts.factory.createNodeArray(result);
}
@@ -475,6 +504,7 @@ function judgmentParentType(node: ts.Node): boolean {
export function createReference(node: ts.PropertyAssignment, log: LogInfo[]): ts.PropertyAssignment {
const linkParentComponent: string[] = getParentNode(node, linkCollection).slice(1);
const propParentComponent: string[] = getParentNode(node, propCollection).slice(1);
const propertyName: ts.Identifier = node.name as ts.Identifier;
let initText: string;
const LINK_REG: RegExp = /^\$/g;
@@ -492,6 +522,9 @@ export function createReference(node: ts.PropertyAssignment, log: LogInfo[]): ts
pos: initExpression.getStart()
});
}
} else if (partialUpdateConfig.partialUpdateMode && isMatchInitExpression(initExpression) &&
propParentComponent.includes(propertyName.escapedText.toString())) {
initText = initExpression.name.escapedText.toString();
}
if (initText) {
node = addDoubleUnderline(node, propertyName, initText);
@@ -539,15 +572,29 @@ function addUpdateParamsFunc(statements: ts.Statement[], parentComponentName: ts
return createParamsInitBlock(COMPONENT_CONSTRUCTOR_UPDATE_PARAMS, statements, parentComponentName);
}
function addInitialParamsFunc(statements: ts.Statement[], parentComponentName: ts.Identifier): ts.MethodDeclaration {
return createParamsInitBlock(COMPONENT_CONSTRUCTOR_INITIAL_PARAMS, statements, parentComponentName);
}
function addPurgeVariableDepFunc(statements: ts.Statement[]): ts.MethodDeclaration {
return ts.factory.createMethodDeclaration(
undefined, undefined, undefined,
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PURGE_VARIABLE_DEP),
undefined, undefined, [ts.factory.createParameterDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(RMELMTID), undefined, undefined, undefined)], undefined,
ts.factory.createBlock(statements, true));
}
function addDeleteParamsFunc(statements: ts.PropertyDeclaration[]): ts.MethodDeclaration {
const deleteStatements: ts.ExpressionStatement[] = [];
statements.forEach((statement: ts.PropertyDeclaration) => {
const name: ts.Identifier = statement.name as ts.Identifier;
const paramsStatement: ts.ExpressionStatement = ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
ts.factory.createIdentifier(`__${name.escapedText.toString()}`)),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_DELETE_PARAMS)), undefined, []));
let paramsStatement: ts.ExpressionStatement;
if (partialUpdateConfig.partialUpdateMode && !statement.decorators) {
paramsStatement = createParamsStatement(name);
} else {
paramsStatement = createParamsWithUnderlineStatement(name);
}
deleteStatements.push(paramsStatement);
});
const defaultStatement: ts.ExpressionStatement =
@@ -558,14 +605,55 @@ function addDeleteParamsFunc(statements: ts.PropertyDeclaration[]): ts.MethodDec
ts.factory.createIdentifier(CREATE_CONSTRUCTOR_GET_FUNCTION)), undefined, []),
ts.factory.createIdentifier(CREATE_CONSTRUCTOR_DELETE_FUNCTION)),
undefined, [ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createThis(), ts.factory.createIdentifier(ABOUT_TO_BE_DELETE_FUNCTION_ID)),
ts.factory.createThis(), ts.factory.createIdentifier(
!partialUpdateConfig.partialUpdateMode ?
ABOUT_TO_BE_DELETE_FUNCTION_ID : ABOUT_TO_BE_DELETE_FUNCTION_ID__)),
undefined, [])]));
deleteStatements.push(defaultStatement);
if (partialUpdateConfig.partialUpdateMode) {
const aboutToBeDeletedInternalStatement: ts.ExpressionStatement = createDeletedInternalStatement();
deleteStatements.push(aboutToBeDeletedInternalStatement);
}
const deleteParamsMethod: ts.MethodDeclaration =
createParamsInitBlock(COMPONENT_CONSTRUCTOR_DELETE_PARAMS, deleteStatements);
return deleteParamsMethod;
}
function createParamsStatement(name: ts.Identifier): ts.ExpressionStatement {
return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(`${name.escapedText.toString()}`)
),
ts.factory.createToken(ts.SyntaxKind.EqualsToken),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_UNDEFINED)
));
}
function createParamsWithUnderlineStatement(name: ts.Identifier): ts.ExpressionStatement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
ts.factory.createIdentifier(`__${name.escapedText.toString()}`)),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_DELETE_PARAMS)), undefined, []));
}
function createDeletedInternalStatement(): ts.ExpressionStatement {
return ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
ts.factory.createIdentifier(ABOUTTOBEDELETEDINTERNAL)), undefined, []));
}
function addRerenderFunc(statements: ts.Statement[]): ts.MethodDeclaration {
let updateDirtyElementStatement: ts.Statement = ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createThis(), ts.factory.createIdentifier(UPDATEDIRTYELEMENTS)), undefined, []));
statements.push(updateDirtyElementStatement);
return ts.factory.createMethodDeclaration(undefined, undefined, undefined,
ts.factory.createIdentifier(COMPONENT_RERENDER_FUNCTION), undefined, undefined, [], undefined,
ts.factory.createBlock(statements, true));
}
function createParamsInitBlock(express: string, statements: ts.Statement[],
parentComponentName?: ts.Identifier): ts.MethodDeclaration {
const methodDeclaration: ts.MethodDeclaration = ts.factory.createMethodDeclaration(undefined,
@@ -601,3 +689,116 @@ function validateHasController(componentName: ts.Identifier, checkController: Co
});
}
}
function createHeritageClause(): ts.HeritageClause {
if (partialUpdateConfig.partialUpdateMode) {
return ts.factory.createHeritageClause(
ts.SyntaxKind.ExtendsKeyword,
[ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(BASE_COMPONENT_NAME_PU), [])]
);
}
return ts.factory.createHeritageClause(
ts.SyntaxKind.ExtendsKeyword,
[ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(BASE_COMPONENT_NAME), [])]
);
}
function createTypeReference(decoratorName: string, type: ts.TypeNode, log: LogInfo[],
program: ts.Program): ts.TypeNode {
let newType: ts.TypeNode;
switch (decoratorName) {
case COMPONENT_STATE_DECORATOR:
case COMPONENT_PROVIDE_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
isSimpleType(type, program, log)
? OBSERVED_PROPERTY_SIMPLE
: OBSERVED_PROPERTY_OBJECT,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_LINK_DECORATOR:
case COMPONENT_CONSUME_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
isSimpleType(type, program, log)
? SYNCHED_PROPERTY_SIMPLE_TWO_WAY
: SYNCHED_PROPERTY_SIMPLE_ONE_WAY,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_PROP_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
SYNCHED_PROPERTY_SIMPLE_ONE_WAY,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_OBJECT_LINK_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
SYNCHED_PROPERTY_NESED_OBJECT,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_STORAGE_PROP_DECORATOR:
case COMPONENT_STORAGE_LINK_DECORATOR:
newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [
type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
]);
break;
case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR:
case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR:
newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [
type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
]);
break;
}
return newType;
}
function createTypeReferencePU(decoratorName: string, type: ts.TypeNode, log: LogInfo[],
program: ts.Program): ts.TypeNode {
let newType: ts.TypeNode;
switch (decoratorName) {
case COMPONENT_STATE_DECORATOR:
case COMPONENT_PROVIDE_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
isSimpleType(type, program, log)
? OBSERVED_PROPERTY_SIMPLE_PU
: OBSERVED_PROPERTY_OBJECT_PU,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_LINK_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
isSimpleType(type, program, log)
? SYNCHED_PROPERTY_SIMPLE_TWO_WAY_PU
: SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_PROP_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_OBJECT_LINK_DECORATOR:
newType = ts.factory.createTypeReferenceNode(
SYNCHED_PROPERTY_NESED_OBJECT_PU,
[type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
);
break;
case COMPONENT_CONSUME_DECORATOR:
case COMPONENT_STORAGE_PROP_DECORATOR:
case COMPONENT_STORAGE_LINK_DECORATOR:
newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT_PU, [
type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
]);
break;
case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR:
case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR:
newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT_PU, [
type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
]);
break;
}
return newType;
}
+59 -18
View File
@@ -20,10 +20,14 @@ import {
COMPONENT_CONSTRUCTOR_PARENT,
COMPONENT_CONSTRUCTOR_PARAMS,
COMPONENT_CONSTRUCTOR_UPDATE_PARAMS,
COMPONENT_CONSTRUCTOR_INITIAL_PARAMS,
COMPONENT_WATCH_FUNCTION,
BASE_COMPONENT_NAME,
INTERFACE_NAME_SUFFIX,
COMPONENT_CONSTRUCTOR_LOCALSTORAGE
COMPONENT_CONSTRUCTOR_LOCALSTORAGE,
BASE_COMPONENT_NAME_PU,
COMPONENT_CONSTRUCTOR_LOCALSTORAGE_PU,
COMPONENT_CONSTRUCTOR_LOCALSTORAGE_TYPE_PU
} from './pre_define';
import {
@@ -31,6 +35,8 @@ import {
localStoragePropCollection
} from './validate_ui_syntax';
import { partialUpdateConfig } from '../main';
export function getInitConstructor(members: ts.NodeArray<ts.Node>, parentComponentName: ts.Identifier
): ts.ConstructorDeclaration {
let ctorNode: any = members.find(item => {
@@ -83,9 +89,16 @@ function initConstructorParams(node: ts.ConstructorDeclaration, parentComponentN
}
const localStorageNum: number = localStorageLinkCollection.get(parentComponentName.getText()).size +
localStoragePropCollection.get(parentComponentName.getText()).size;
const paramNames: Set<string> = new Set([COMPONENT_CONSTRUCTOR_ID, COMPONENT_CONSTRUCTOR_PARENT,
COMPONENT_CONSTRUCTOR_PARAMS, localStorageNum ? COMPONENT_CONSTRUCTOR_LOCALSTORAGE :
COMPONENT_CONSTRUCTOR_PARAMS]);
const paramNames: Set<string> = !partialUpdateConfig.partialUpdateMode ? new Set([
COMPONENT_CONSTRUCTOR_ID,
COMPONENT_CONSTRUCTOR_PARENT,
COMPONENT_CONSTRUCTOR_PARAMS,
localStorageNum ? COMPONENT_CONSTRUCTOR_LOCALSTORAGE : COMPONENT_CONSTRUCTOR_PARAMS
]) : new Set([
COMPONENT_CONSTRUCTOR_PARENT,
COMPONENT_CONSTRUCTOR_PARAMS,
COMPONENT_CONSTRUCTOR_LOCALSTORAGE_PU
]);
const newParameters: ts.ParameterDeclaration[] = Array.from(node.parameters);
if (newParameters.length !== 0) {
// @ts-ignore
@@ -117,7 +130,8 @@ function addParamsType(ctorNode: ts.ConstructorDeclaration, modifyPara: ts.Param
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),
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(
!partialUpdateConfig.partialUpdateMode ? BASE_COMPONENT_NAME : BASE_COMPONENT_NAME_PU), undefined),
item.initializer);
break;
case COMPONENT_CONSTRUCTOR_PARAMS:
@@ -126,6 +140,11 @@ function addParamsType(ctorNode: ts.ConstructorDeclaration, modifyPara: ts.Param
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(
parentComponentName.getText() + INTERFACE_NAME_SUFFIX), undefined), item.initializer);
break;
case COMPONENT_CONSTRUCTOR_LOCALSTORAGE_PU:
parameter = ts.factory.createParameterDeclaration(item.decorators, item.modifiers, item.dotDotDotToken,
item.name, ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_LOCALSTORAGE_TYPE_PU), undefined), item.initializer);
break;
}
newTSPara.push(parameter);
});
@@ -154,19 +173,41 @@ export function addConstructor(ctorNode: any, watchMap: Map<string, ts.Node>,
));
watchStatements.push(watchNode);
});
const callSuperStatement: ts.Statement = ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createSuper(), undefined,
localStorageNum ?
[ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_ID),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_LOCALSTORAGE)] :
[ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_ID),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT)]
));
const updateWithValueParamsStatement: ts.Statement = ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createThis(), ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_UPDATE_PARAMS)),
undefined, [ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS)]));
const callSuperStatement: ts.Statement = createCallSuperStatement(localStorageNum);
const updateWithValueParamsStatement: ts.Statement = createUPdWithValStatement();
return updateConstructor(updateConstructor(ctorNode, [], [callSuperStatement], true), [],
[...watchStatements, updateWithValueParamsStatement], false, true, parentComponentName);
}
function createCallSuperStatement(localStorageNum: number): ts.Statement{
if (!partialUpdateConfig.partialUpdateMode) {
return ts.factory.createExpressionStatement(ts.factory.createCallExpression(
ts.factory.createSuper(), undefined,
localStorageNum ? [ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_ID),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_LOCALSTORAGE)] :
[ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_ID),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT)]));
} else {
return (ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createSuper(), undefined,
[ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_LOCALSTORAGE_PU)])));
}
}
function createUPdWithValStatement(): ts.Statement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(
!partialUpdateConfig.partialUpdateMode ?
COMPONENT_CONSTRUCTOR_UPDATE_PARAMS : COMPONENT_CONSTRUCTOR_INITIAL_PARAMS
)
),
undefined,
[ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS)]
)
);
}
+155 -16
View File
@@ -55,7 +55,19 @@ import {
COMPONENT_LOCAL_STORAGE_PROP_DECORATOR,
COMPONENT_CONSTRUCTOR_PARENT,
EXTNAME_ETS,
_GENERATE_ID
_GENERATE_ID,
MARKDEPENDENTELEMENTSDIRTY,
RMELMTID,
PURGEDEPENDENCYONELMTID,
SETPROPERTYUNCHANGED,
BASICDECORATORS,
BASE_COMPONENT_NAME_PU,
OBSERVED_PROPERTY_SIMPLE_PU,
OBSERVED_PROPERTY_OBJECT_PU,
SYNCHED_PROPERTY_SIMPLE_TWO_WAY_PU,
SYNCHED_PROPERTY_OBJECT_TWO_WAY_PU,
SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
SYNCHED_PROPERTY_NESED_OBJECT_PU
} from './pre_define';
import {
forbiddenUseStateType,
@@ -81,6 +93,8 @@ import {
import { transformLog } from './process_ui_syntax';
import { globalProgram, projectConfig } from '../main';
import { partialUpdateConfig } from '../main';
export type ControllerType = {
hasController: boolean
}
@@ -129,6 +143,9 @@ export class UpdateResult {
private updateParams: ts.Statement;
private deleteParams: boolean = false;
private controllerSet: ts.MethodDeclaration;
private purgeVariableDepStatement: ts.Statement;
private rerenderStatement: ts.Statement;
private decoratorName: string;
public setProperity(updateItem: ts.PropertyDeclaration) {
this.itemUpdate = true;
@@ -164,6 +181,18 @@ export class UpdateResult {
this.deleteParams = deleteParams;
}
public setPurgeVariableDepStatement(purgeVariableDepStatement: ts.Statement) {
this.purgeVariableDepStatement = purgeVariableDepStatement;
}
public setRerenderStatement(rerenderStatement: ts.Statement) {
this.rerenderStatement = rerenderStatement;
}
public setDecoratorName(decoratorName: string) {
this.decoratorName = decoratorName;
}
public isItemUpdate(): boolean {
return this.itemUpdate;
}
@@ -184,6 +213,14 @@ export class UpdateResult {
return this.updateParams;
}
public getPurgeVariableDepStatement(): ts.Statement {
return this.purgeVariableDepStatement;
}
public getRerenderStatement(): ts.Statement {
return this.rerenderStatement;
}
public getVariableGet(): ts.GetAccessorDeclaration {
return this.variableGet;
}
@@ -192,6 +229,10 @@ export class UpdateResult {
return this.variableSet;
}
public getDecoratorName(): string {
return this.decoratorName;
}
public isDeleteParams(): boolean {
return this.deleteParams;
}
@@ -213,6 +254,9 @@ export function processMemberVariableDecorators(parentName: ts.Identifier,
createVariableInitStatement(item, COMPONENT_NON_DECORATOR, log, program, context, hasPreview,
interfaceNode)]));
updateResult.setControllerSet(createControllerSet(item, parentName, name, checkController));
if (partialUpdateConfig.partialUpdateMode) {
updateResult.setDeleteParams(true);
}
} else if (!item.type) {
validatePropertyNonType(name, log);
return updateResult;
@@ -317,6 +361,44 @@ function processStateDecorators(node: ts.PropertyDeclaration, decorator: string,
if (setUpdateParamsDecorators.has(decorator)) {
updateResult.setUpdateParams(createUpdateParams(name, decorator));
}
if (partialUpdateConfig.partialUpdateMode && BASICDECORATORS.has(decorator)) {
const variableWithUnderLink: string = '__' + name.escapedText.toString();
updateResult.setDecoratorName(decorator);
updateResult.setPurgeVariableDepStatement(createPurgeVariableDepStatement(variableWithUnderLink));
updateResult.setRerenderStatement(createRerenderStatement(variableWithUnderLink));
}
}
function createPurgeVariableDepStatement(variableWithUnderLink: string): ts.Statement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(variableWithUnderLink)
),
ts.factory.createIdentifier(PURGEDEPENDENCYONELMTID)
),
undefined,
[ts.factory.createIdentifier(RMELMTID)]
)
);
}
function createRerenderStatement(variableWithUnderLink: string): ts.Statement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
ts.factory.createIdentifier(variableWithUnderLink)
),
ts.factory.createIdentifier(MARKDEPENDENTELEMENTSDIRTY)
),
undefined,
[ts.factory.createThis()]
)
);
}
function processWatch(node: ts.PropertyDeclaration, decorator: ts.Decorator,
@@ -368,15 +450,19 @@ function createVariableInitStatement(node: ts.PropertyDeclaration, decorator: st
break;
case COMPONENT_STATE_DECORATOR:
case COMPONENT_PROVIDE_DECORATOR:
updateState = updateObservedProperty(node, name, type, program);
updateState = !partialUpdateConfig.partialUpdateMode ?
updateObservedProperty(node, name, type, program) : updateObservedPropertyPU(node, name, type, program);
break;
case COMPONENT_LINK_DECORATOR:
wrongDecoratorInPreview(node, COMPONENT_LINK_DECORATOR, hasPreview, log);
updateState = updateSynchedPropertyTwoWay(name, type, program);
updateState = !partialUpdateConfig.partialUpdateMode ?
updateSynchedPropertyTwoWay(name, type, program) : updateSynchedPropertyTwoWayPU(name, type, program);
break;
case COMPONENT_PROP_DECORATOR:
wrongDecoratorInPreview(node, COMPONENT_PROP_DECORATOR, hasPreview, log);
updateState = updateSynchedPropertyOneWay(name, type, decorator, log, program);
updateState = !partialUpdateConfig.partialUpdateMode
? updateSynchedPropertyOneWay(name, type, decorator, log, program)
: updateSynchedPropertyOneWayPU(name, type, decorator, log, program);
break;
case COMPONENT_STORAGE_PROP_DECORATOR:
case COMPONENT_STORAGE_LINK_DECORATOR:
@@ -385,7 +471,9 @@ function createVariableInitStatement(node: ts.PropertyDeclaration, decorator: st
updateState = updateStoragePropAndLinkProperty(node, name, setFuncName, log);
break;
case COMPONENT_OBJECT_LINK_DECORATOR:
updateState = updateSynchedPropertyNesedObject(name, type, decorator, log);
updateState = !partialUpdateConfig.partialUpdateMode
? updateSynchedPropertyNesedObject(name, type, decorator, log)
: updateSynchedPropertyNesedObjectPU(name, type, decorator, log);
break;
case COMPONENT_CONSUME_DECORATOR:
wrongDecoratorInPreview(node, COMPONENT_CONSUME_DECORATOR, hasPreview, log);
@@ -422,6 +510,10 @@ function createUpdateParams(name: ts.Identifier, decorator: string): ts.Statemen
updateParamsNode = createUpdateParamsWithIf(name);
break;
case COMPONENT_PROP_DECORATOR:
if (!partialUpdateConfig.partialUpdateMode) {
updateParamsNode = createUpdateParamsWithoutIf(name);
}
break;
case COMPONENT_BUILDERPARAM_DECORATOR:
updateParamsNode = createUpdateParamsWithoutIf(name);
break;
@@ -570,6 +662,10 @@ function createCustomComponentBuilderArrowFunction(parent: ts.PropertyDeclaratio
}
export function createViewCreate(node: ts.NewExpression | ts.Identifier): ts.CallExpression {
if (partialUpdateConfig.partialUpdateMode) {
return createFunction(ts.factory.createIdentifier(BASE_COMPONENT_NAME_PU),
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION), ts.factory.createNodeArray([node]));
}
return createFunction(ts.factory.createIdentifier(BASE_COMPONENT_NAME),
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION), ts.factory.createNodeArray([node]));
}
@@ -595,17 +691,21 @@ function addCustomComponentId(node: ts.NewExpression, componentName: string,
if (!argumentsArray) {
argumentsArray = [ts.factory.createObjectLiteralExpression([], true)];
}
++componentInfo.id;
argumentsArray.unshift(isInnerBuilder ? ts.factory.createBinaryExpression(
ts.factory.createStringLiteral(path.basename(transformLog.sourceFile.fileName, EXTNAME_ETS) + '_'),
ts.factory.createToken(ts.SyntaxKind.PlusToken), ts.factory.createIdentifier(_GENERATE_ID)) :
ts.factory.createStringLiteral(componentInfo.id.toString()),
isInnerBuilder ? ts.factory.createConditionalExpression(
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT),
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT),
ts.factory.createToken(ts.SyntaxKind.ColonToken), ts.factory.createThis()
) : ts.factory.createThis());
if (!partialUpdateConfig.partialUpdateMode) {
++componentInfo.id;
argumentsArray.unshift(isInnerBuilder ? ts.factory.createBinaryExpression(
ts.factory.createStringLiteral(path.basename(transformLog.sourceFile.fileName, EXTNAME_ETS) + '_'),
ts.factory.createToken(ts.SyntaxKind.PlusToken), ts.factory.createIdentifier(_GENERATE_ID)) :
ts.factory.createStringLiteral(componentInfo.id.toString()),
isInnerBuilder ? ts.factory.createConditionalExpression(
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT),
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT),
ts.factory.createToken(ts.SyntaxKind.ColonToken), ts.factory.createThis()
) : ts.factory.createThis());
} else {
argumentsArray.unshift(ts.factory.createThis());
}
node =
ts.factory.updateNewExpression(node, node.expression, node.typeArguments, argumentsArray);
} else if (argumentsArray) {
@@ -900,3 +1000,42 @@ function validateVariableType(typeNode: ts.TypeNode, log: LogInfo[]): void {
});
}
function updateObservedPropertyPU(item: ts.PropertyDeclaration, name: ts.Identifier,
type: ts.TypeNode, program: ts.Program): ts.ExpressionStatement {
return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(
createPropertyAccessExpressionWithThis(`__${name.getText()}`),
ts.factory.createToken(ts.SyntaxKind.EqualsToken), ts.factory.createNewExpression(
ts.factory.createIdentifier(isSimpleType(type, program) ? OBSERVED_PROPERTY_SIMPLE_PU :
OBSERVED_PROPERTY_OBJECT_PU), undefined, [item.initializer, ts.factory.createThis(),
ts.factory.createStringLiteral(name.escapedText.toString())])));
}
function updateSynchedPropertyTwoWayPU(nameIdentifier: ts.Identifier, type: ts.TypeNode,
program: ts.Program): ts.ExpressionStatement {
const name: string = nameIdentifier.escapedText.toString();
const functionName: string = isSimpleType(type, program) ?
SYNCHED_PROPERTY_SIMPLE_TWO_WAY_PU : SYNCHED_PROPERTY_OBJECT_TWO_WAY_PU;
return createInitExpressionStatementForDecorator(name, functionName,
createPropertyAccessExpressionWithParams(name));
}
function updateSynchedPropertyOneWayPU(nameIdentifier: ts.Identifier, type: ts.TypeNode,
decoractor: string, log: LogInfo[], program: ts.Program): ts.ExpressionStatement {
const name: string = nameIdentifier.escapedText.toString();
if (isSimpleType(type, program)) {
return createInitExpressionStatementForDecorator(name, SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
createPropertyAccessExpressionWithParams(name));
} else {
validateNonSimpleType(nameIdentifier, decoractor, log);
}
}
function updateSynchedPropertyNesedObjectPU(nameIdentifier: ts.Identifier,
type: ts.TypeNode, decoractor: string, log: LogInfo[]): ts.ExpressionStatement {
if (isObservedClassType(type)) {
return createInitExpressionStatementForDecorator(nameIdentifier.getText(), SYNCHED_PROPERTY_NESED_OBJECT_PU,
createPropertyAccessExpressionWithParams(nameIdentifier.getText()));
} else {
validateNonObservedClassType(nameIdentifier, decoractor, log);
}
}
+66 -6
View File
@@ -34,7 +34,14 @@ import {
CUSTOM_COMPONENT_MARK_STATIC_FUNCTION,
COMPONENT_COMMON,
COMPONENT_CONSTRUCTOR_PARENT,
GENERATE_ID
GENERATE_ID,
ELMTID,
VIEWSTACKPROCESSOR,
STARTGETACCESSRECORDINGFOR,
STOPGETACCESSRECORDING,
ALLOCATENEWELMETIDFORNEXTCOMPONENT,
STATE_OBJECTLINK_DECORATORS,
BASE_COMPONENT_NAME_PU
} from './pre_define';
import {
propertyCollection,
@@ -64,6 +71,7 @@ import {
createFunction
} from './utils';
import { bindComponentAttr } from './process_component_build';
import { partialUpdateConfig } from '../main';
const localArray: string[] = [...observedPropertyDecorators, COMPONENT_NON_DECORATOR,
COMPONENT_PROP_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR];
@@ -155,10 +163,60 @@ function addCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Stat
function addCustomComponentStatements(node: ts.ExpressionStatement, newStatements: ts.Statement[],
newNode: ts.NewExpression, name: string, props: ts.ObjectLiteralElementLike[],
isInnerBuilder: boolean = false): void {
const id: string = componentInfo.id.toString();
newStatements.push(createFindChildById(id, name, isInnerBuilder), createCustomComponentIfStatement(id,
ts.factory.updateExpressionStatement(node, createViewCreate(newNode)),
ts.factory.createObjectLiteralExpression(props, true), name));
if (!partialUpdateConfig.partialUpdateMode) {
const id: string = componentInfo.id.toString();
newStatements.push(createFindChildById(id, name, isInnerBuilder), createCustomComponentIfStatement(id,
ts.factory.updateExpressionStatement(node, createViewCreate(newNode)),
ts.factory.createObjectLiteralExpression(props, true), name));
} else {
newStatements.push(createCustomComponent(newNode));
}
}
function createCustomComponent(newNode: ts.NewExpression): ts.Block {
return ts.factory.createBlock(
[
ts.factory.createVariableStatement(undefined,
ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(
ts.factory.createIdentifier(ELMTID), undefined, undefined,
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(VIEWSTACKPROCESSOR),
ts.factory.createIdentifier(ALLOCATENEWELMETIDFORNEXTCOMPONENT)
), undefined, []))],
ts.NodeFlags.Const
)
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(VIEWSTACKPROCESSOR),
ts.factory.createIdentifier(STARTGETACCESSRECORDINGFOR)
), undefined,
[ts.factory.createIdentifier(ELMTID)]
)
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(BASE_COMPONENT_NAME_PU),
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION)
), undefined,
[newNode]
)
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier(VIEWSTACKPROCESSOR),
ts.factory.createIdentifier(STOPGETACCESSRECORDING)
), undefined, []
)
)
],
true
);
}
function validateCustomComponentPrams(node: ts.CallExpression, name: string,
@@ -344,7 +402,9 @@ function isCorrectInitFormParent(parent: string, child: string): boolean {
}
break;
case COMPONENT_OBJECT_LINK_DECORATOR:
if (parent === COMPONENT_STATE_DECORATOR) {
if (!partialUpdateConfig.partialUpdateMode && parent === COMPONENT_STATE_DECORATOR) {
return true;
} else if (partialUpdateConfig.partialUpdateMode && STATE_OBJECTLINK_DECORATORS.includes(parent)) {
return true;
}
break;
+85 -13
View File
@@ -54,7 +54,11 @@ import {
COMPONENT_COMMON,
EXTNAME_ETS,
GENERATE_ID,
_GENERATE_ID
_GENERATE_ID,
VIEWSTACKPROCESSOR,
STARTGETACCESSRECORDINGFOR,
ALLOCATENEWELMETIDFORNEXTCOMPONENT,
STOPGETACCESSRECORDING
} from './pre_define';
import {
componentInfo,
@@ -84,7 +88,8 @@ import {
} from './validate_ui_syntax';
import {
resources,
projectConfig
projectConfig,
partialUpdateConfig
} from '../main';
import { createCustomComponentNewExpression, createViewCreate } from './process_component_member';
@@ -115,7 +120,9 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
});
GLOBAL_STYLE_FUNCTION.clear();
const statements: ts.Statement[] = Array.from(node.statements);
generateId(statements, node);
if (!partialUpdateConfig.partialUpdateMode) {
generateId(statements, node);
}
INTERFACE_NODE_SET.forEach(item => {
statements.unshift(item);
});
@@ -581,9 +588,15 @@ export function isExtendFunction(node: ts.FunctionDeclaration): string {
function createEntryNode(node: ts.SourceFile, context: ts.TransformationContext): ts.SourceFile {
if (componentCollection.previewComponent.size === 0 || !projectConfig.isPreview) {
if (componentCollection.entryComponent) {
const entryNode: ts.ExpressionStatement =
createEntryFunction(componentCollection.entryComponent, context);
return context.factory.updateSourceFile(node, [...node.statements, entryNode]);
if (!partialUpdateConfig.partialUpdateMode) {
const entryNode: ts.ExpressionStatement =
createEntryFunction(componentCollection.entryComponent, context) as ts.ExpressionStatement;
return context.factory.updateSourceFile(node, [...node.statements, entryNode]);
} else {
const entryNodes: ts.ExpressionStatement[] =
createEntryFunction(componentCollection.entryComponent, context) as ts.ExpressionStatement[];
return context.factory.updateSourceFile(node, [...node.statements, ...entryNodes]);
}
} else {
return node;
}
@@ -595,7 +608,7 @@ function createEntryNode(node: ts.SourceFile, context: ts.TransformationContext)
}
function createEntryFunction(name: string, context: ts.TransformationContext)
: ts.ExpressionStatement {
: ts.ExpressionStatement | ts.ExpressionStatement[] {
let localStorageName: string;
const localStorageNum: number = localStorageLinkCollection.get(name).size +
localStoragePropCollection.get(name).size;
@@ -619,12 +632,71 @@ function createEntryFunction(name: string, context: ts.TransformationContext)
if (localStorageName) {
newArray.push(context.factory.createIdentifier(localStorageName));
}
const newExpressionStatement: ts.ExpressionStatement =
context.factory.createExpressionStatement(context.factory.createCallExpression(
context.factory.createIdentifier(PAGE_ENTRY_FUNCTION_NAME), undefined,
[context.factory.createNewExpression(context.factory.createIdentifier(name),
undefined, newArray)]));
return newExpressionStatement;
if (!partialUpdateConfig.partialUpdateMode) {
const newExpressionStatement: ts.ExpressionStatement =
context.factory.createExpressionStatement(context.factory.createCallExpression(
context.factory.createIdentifier(PAGE_ENTRY_FUNCTION_NAME), undefined,
[context.factory.createNewExpression(context.factory.createIdentifier(name),
undefined, newArray)]));
return newExpressionStatement;
} else {
return [
createStartGetAccessRecording(context),
createLoadDocument(context, name),
createStopGetAccessRecording(context)
];
}
}
function createStartGetAccessRecording(context: ts.TransformationContext): ts.ExpressionStatement {
return context.factory.createExpressionStatement(
context.factory.createCallExpression(
context.factory.createPropertyAccessExpression(
context.factory.createIdentifier(VIEWSTACKPROCESSOR),
context.factory.createIdentifier(STARTGETACCESSRECORDINGFOR)
),
undefined,
[context.factory.createCallExpression(
context.factory.createPropertyAccessExpression(
context.factory.createIdentifier(VIEWSTACKPROCESSOR),
context.factory.createIdentifier(ALLOCATENEWELMETIDFORNEXTCOMPONENT)
),
undefined,
[]
)]
)
);
}
function createLoadDocument(context: ts.TransformationContext, name: string): ts.ExpressionStatement {
return context.factory.createExpressionStatement(
context.factory.createCallExpression(
context.factory.createIdentifier(PAGE_ENTRY_FUNCTION_NAME),
undefined,
[context.factory.createNewExpression(
context.factory.createIdentifier(name),
undefined,
[context.factory.createIdentifier('undefined'),
context.factory.createObjectLiteralExpression(
[],
false
)]
)]
)
);
}
function createStopGetAccessRecording(context: ts.TransformationContext): ts.ExpressionStatement {
return context.factory.createExpressionStatement(
context.factory.createCallExpression(
context.factory.createPropertyAccessExpression(
context.factory.createIdentifier(VIEWSTACKPROCESSOR),
context.factory.createIdentifier(STOPGETACCESSRECORDING)
),
undefined,
[]
)
);
}
function createPreviewComponentFunction(name: string, context: ts.TransformationContext)
+8 -1
View File
@@ -35,6 +35,9 @@ const {
NATIVE_MODULE,
SYSTEM_PLUGIN
} = require('../lib/pre_define');
const {
partialUpdateConfig
} = require('../main');
function expectActual(name, filePath) {
const content = require(filePath);
@@ -59,7 +62,11 @@ function expectActual(name, filePath) {
}
mocha.describe('compiler', () => {
const utPath = path.resolve(__dirname, './ut');
let utPath = path.resolve(__dirname, './ut');
if (process.argv.includes('--partialUpdate')) {
partialUpdateConfig.partialUpdateMode = true;
utPath = path.resolve(__dirname, './utForPartialUpdate');
}
const utFiles = [];
readFile(utPath, utFiles);
utFiles.forEach((item) => {
@@ -0,0 +1,173 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Component
@Entry
struct MyComponent {
build() {
Column() {
Banner()
Banner()
.width(100)
Banner()
.width(100)
.height(200)
Banner({value: "Hello"})
Banner({value: "Hello"})
.width(100)
Banner({value: "Hello"})
.width(100)
.height(200)
}
}
}
@Component
struct Banner {
value: string = "Hello"
build() {
Column() {
Text(this.value)
}
}
}`
exports.expectResult =
`"use strict";
class MyComponent extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new Banner(this, {}));
ViewStackProcessor.StopGetAccessRecording();
}
__Common__.create();
__Common__.width(100);
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new Banner(this, {}));
ViewStackProcessor.StopGetAccessRecording();
}
__Common__.pop();
__Common__.create();
__Common__.width(100);
__Common__.height(200);
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new Banner(this, {}));
ViewStackProcessor.StopGetAccessRecording();
}
__Common__.pop();
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new Banner(this, { value: "Hello" }));
ViewStackProcessor.StopGetAccessRecording();
}
__Common__.create();
__Common__.width(100);
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new Banner(this, { value: "Hello" }));
ViewStackProcessor.StopGetAccessRecording();
}
__Common__.pop();
__Common__.create();
__Common__.width(100);
__Common__.height(200);
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new Banner(this, { value: "Hello" }));
ViewStackProcessor.StopGetAccessRecording();
}
__Common__.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
class Banner extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.value = "Hello";
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.value !== undefined) {
this.value = params.value;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
this.value = undefined;
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create(this.value);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new MyComponent(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Entry
@Component
struct ParentView {
@State arr: string[] = ['1', '2', '3'];
build() {
List() {
ForEach(this.arr,
item => {
Text(item)
},
item => item.toString()
)
}
}
}
`
exports.expectResult =
`"use strict";
class ParentView extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__arr = new ObservedPropertyObjectPU(['1', '2', '3'], this, "arr");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.arr !== undefined) {
this.arr = params.arr;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__arr.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__arr.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get arr() {
return this.__arr.get();
}
set arr(newValue) {
this.__arr.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
List.create();
if (!isInitialRender) {
List.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ForEach.create();
const forEachItemGenFunction = _item => {
const item = _item;
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create(item);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
};
const forEachItemIdFunc = item => item.toString();
this.forEachUpdateFunction(elmtId, this.arr, forEachItemGenFunction, forEachItemIdFunc);
if (!isInitialRender) {
ForEach.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
ForEach.pop();
List.pop();
}
rerender() {
this.__arr.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new ParentView(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,168 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Entry
@Component
struct IFView {
@State toggle1: boolean = false;
@State toggle2: boolean = false;
@State toggle3: boolean = false;
build() {
Column() {
if (this.toggle1) {
Text('toggle1')
} else if(this.toggle2) {
Text('toggle2')
} else if (this.toggle3) {
Text('toggle3')
} else {
Text('toggle no thing')
}
}
}
}
`
exports.expectResult =
`"use strict";
class IFView extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__toggle1 = new ObservedPropertySimplePU(false, this, "toggle1");
this.__toggle2 = new ObservedPropertySimplePU(false, this, "toggle2");
this.__toggle3 = new ObservedPropertySimplePU(false, this, "toggle3");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.toggle1 !== undefined) {
this.toggle1 = params.toggle1;
}
if (params.toggle2 !== undefined) {
this.toggle2 = params.toggle2;
}
if (params.toggle3 !== undefined) {
this.toggle3 = params.toggle3;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__toggle1.purgeDependencyOnElmtId(rmElmtId);
this.__toggle2.purgeDependencyOnElmtId(rmElmtId);
this.__toggle3.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__toggle1.aboutToBeDeleted();
this.__toggle2.aboutToBeDeleted();
this.__toggle3.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get toggle1() {
return this.__toggle1.get();
}
set toggle1(newValue) {
this.__toggle1.set(newValue);
}
get toggle2() {
return this.__toggle2.get();
}
set toggle2(newValue) {
this.__toggle2.set(newValue);
}
get toggle3() {
return this.__toggle3.get();
}
set toggle3(newValue) {
this.__toggle3.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
If.create();
if (this.toggle1) {
If.branchId(0);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('toggle1');
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
}
else if (this.toggle2) {
If.branchId(1);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('toggle2');
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
}
else if (this.toggle3) {
If.branchId(2);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('toggle3');
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
}
else {
If.branchId(3);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('toggle no thing');
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
}
if (!isInitialRender) {
If.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
If.pop();
Column.pop();
}
rerender() {
this.__toggle1.markDependentElementsDirty(this);
this.__toggle2.markDependentElementsDirty(this);
this.__toggle3.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new IFView(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Entry
@Component
struct ParentView {
build() {
Grid() {
GridItem('true') {
Text('xx').width(100)
}.width(200).height(100)
}
}
}
`
exports.expectResult =
`"use strict";
class ParentView extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Grid.create();
if (!isInitialRender) {
Grid.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
{
const isLazyCreate = true && (Grid.willUseProxy() === true);
const itemCreation = (elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
GridItem.create(deepRenderFunction, isLazyCreate);
GridItem.width(200);
GridItem.height(100);
if (!isInitialRender) {
GridItem.pop();
}
ViewStackProcessor.StopGetAccessRecording();
};
const observedShallowRender = () => {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
GridItem.create(deepRenderFunction, isLazyCreate);
if (!isInitialRender) {
GridItem.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
GridItem.pop();
};
const observedDeepRender = () => {
this.observeComponentCreation(itemCreation);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('xx');
Text.width(100);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
GridItem.pop();
};
const deepRenderFunction = (elmtId, isInitialRender) => {
itemCreation(elmtId, isInitialRender);
this.updateFuncByElmtId.set(elmtId, itemCreation);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('xx');
Text.width(100);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
GridItem.pop();
};
if (isLazyCreate) {
observedShallowRender();
}
else {
observedDeepRender();
}
}
Grid.pop();
}
rerender() {
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new ParentView(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Entry
@Component
struct ParentView {
build() {
List() {
ListItem('true') {
Text('xx').width(100)
}.width(200).height(100)
}
}
}
`
exports.expectResult =
`"use strict";
class ParentView extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
List.create();
if (!isInitialRender) {
List.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
{
const isLazyCreate = true;
const itemCreation = (elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ListItem.create(deepRenderFunction, isLazyCreate);
ListItem.width(200);
ListItem.height(100);
if (!isInitialRender) {
ListItem.pop();
}
ViewStackProcessor.StopGetAccessRecording();
};
const observedShallowRender = () => {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ListItem.create(deepRenderFunction, isLazyCreate);
if (!isInitialRender) {
ListItem.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
ListItem.pop();
};
const observedDeepRender = () => {
this.observeComponentCreation(itemCreation);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('xx');
Text.width(100);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
ListItem.pop();
};
const deepRenderFunction = (elmtId, isInitialRender) => {
itemCreation(elmtId, isInitialRender);
this.updateFuncByElmtId.set(elmtId, itemCreation);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('xx');
Text.width(100);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
ListItem.pop();
};
if (isLazyCreate) {
observedShallowRender();
}
else {
observedDeepRender();
}
}
List.pop();
}
rerender() {
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new ParentView(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,275 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = []
public totalCount(): number {
return 0
}
public getData(index: number): any {
return undefined
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener')
this.listeners.push(listener)
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener')
this.listeners.splice(pos, 1)
}
}
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
})
}
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index)
})
}
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index)
})
}
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index)
})
}
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to)
})
}
}
class MyDataSource extends BasicDataSource {
private dataArray: string[] = ['/path/image0', '/path/image1', '/path/image2', '/path/image3']
public totalCount(): number {
return this.dataArray.length
}
public getData(index: number): any {
return this.dataArray[index]
}
public addData(index: number, data: string): void {
this.dataArray.splice(index, 0, data)
this.notifyDataAdd(index)
}
public pushData(data: string): void {
this.dataArray.push(data)
this.notifyDataAdd(this.dataArray.length - 1)
}
}
@Entry
@Component
struct Test {
private data: MyDataSource = new MyDataSource()
build() {
Grid() {
LazyForEach (this.data,
(row) => {
GridItem() {
Text(row)
}
},
row => row)
}
}
}
`
exports.expectResult =
`"use strict";
class BasicDataSource {
constructor() {
this.listeners = [];
}
totalCount() {
return 0;
}
getData(index) {
return undefined;
}
registerDataChangeListener(listener) {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
unregisterDataChangeListener(listener) {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
notifyDataReload() {
this.listeners.forEach(listener => {
listener.onDataReloaded();
});
}
notifyDataAdd(index) {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
});
}
notifyDataChange(index) {
this.listeners.forEach(listener => {
listener.onDataChange(index);
});
}
notifyDataDelete(index) {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
});
}
notifyDataMove(from, to) {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
});
}
}
class MyDataSource extends BasicDataSource {
constructor() {
super(...arguments);
this.dataArray = ['/path/image0', '/path/image1', '/path/image2', '/path/image3'];
}
totalCount() {
return this.dataArray.length;
}
getData(index) {
return this.dataArray[index];
}
addData(index, data) {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
pushData(data) {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
class Test extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.data = new MyDataSource();
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.data !== undefined) {
this.data = params.data;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
this.data = undefined;
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Grid.create();
if (!isInitialRender) {
Grid.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
{
const __lazyForEachItemGenFunction = _item => {
const row = _item;
{
const isLazyCreate = (globalThis.__lazyForEachItemGenFunction !== undefined) && true && (Grid.willUseProxy() === true);
const itemCreation = (elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
GridItem.create(deepRenderFunction, isLazyCreate);
if (!isInitialRender) {
GridItem.pop();
}
ViewStackProcessor.StopGetAccessRecording();
};
const observedShallowRender = () => {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
GridItem.create(deepRenderFunction, isLazyCreate);
if (!isInitialRender) {
GridItem.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
GridItem.pop();
};
const observedDeepRender = () => {
this.observeComponentCreation(itemCreation);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create(row);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
GridItem.pop();
};
const deepRenderFunction = (elmtId, isInitialRender) => {
itemCreation(elmtId, isInitialRender);
this.updateFuncByElmtId.set(elmtId, itemCreation);
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create(row);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
GridItem.pop();
};
if (isLazyCreate) {
observedShallowRender();
}
else {
observedDeepRender();
}
}
};
const __lazyForEachItemIdFunc = row => row;
LazyForEach.create("1", this, this.data, __lazyForEachItemGenFunction, __lazyForEachItemIdFunc);
LazyForEach.pop();
}
Grid.pop();
}
rerender() {
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new Test(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,180 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Entry
@Component
struct TabSimple {
private controller: TabsController = new TabsController();
build() {
Column() {
Tabs({ barPosition: BarPosition.Start, index: 1, controller: this.controller}) {
TabContent() {
Flex() {
Column() {
Text('text1')
.height(100)
.width(200)
Text('xxx')
.height(100)
.width(200)
}
.height(100)
.width(200)
}
.height(100)
.width(200)
}
.tabBar("TabBar")
.height(100)
.width(200)
TabContent() {
Text('text2')
}
.tabBar("TabBar 2")
.height(100)
.width(200)
}
}
}
}
`
exports.expectResult =
`"use strict";
class TabSimple extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.controller = new TabsController();
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.controller !== undefined) {
this.controller = params.controller;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
this.controller = undefined;
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Tabs.create({ barPosition: BarPosition.Start, index: 1, controller: this.controller });
if (!isInitialRender) {
Tabs.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
TabContent.create(() => {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Flex.create();
Flex.height(100);
Flex.width(200);
if (!isInitialRender) {
Flex.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
Column.height(100);
Column.width(200);
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('text1');
Text.height(100);
Text.width(200);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('xxx');
Text.height(100);
Text.width(200);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
Column.pop();
Flex.pop();
});
TabContent.tabBar("TabBar");
TabContent.height(100);
TabContent.width(200);
if (!isInitialRender) {
TabContent.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
TabContent.pop();
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
TabContent.create(() => {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create('text2');
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
});
TabContent.tabBar("TabBar 2");
TabContent.height(100);
TabContent.width(200);
if (!isInitialRender) {
TabContent.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
TabContent.pop();
Tabs.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new TabSimple(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Component
struct LinkComponent {
@Link counter: string
build() {
Text(this.counter)
}
}
@Entry
@Component
struct ParentComponent {
@State value: string = 'first init content';
build() {
Column() {
LinkComponent({counter: this.$value})
}
}
}
`
exports.expectResult =
`"use strict";
class LinkComponent extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__counter = new SynchedPropertySimpleTwoWayPU(params.counter, this, "counter");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__counter.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__counter.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get counter() {
return this.__counter.get();
}
set counter(newValue) {
this.__counter.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create(this.counter);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
}
rerender() {
this.__counter.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
class ParentComponent extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__value = new ObservedPropertySimplePU('first init content', this, "value");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.value !== undefined) {
this.value = params.value;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__value.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__value.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get value() {
return this.__value.get();
}
set value(newValue) {
this.__value.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new LinkComponent(this, { counter: this.__value }));
ViewStackProcessor.StopGetAccessRecording();
}
Column.pop();
}
rerender() {
this.__value.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new ParentComponent(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,188 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
var nextID: number = 0;
@Observed
class Model {
text : string = '';
color: string = '#00ff00';
constructor(t: string, c: string) {
this.text = t;
this.color = c;
}
}
@Component
struct CustomText {
@ObjectLink model: Model;
build() {
Row() {
Text(this.model.text)
}
}
}
@Entry
@Component
struct Parent {
nextId: number = 1;
@State models : Model[] = [ new Model('0', '#ffffff'), new Model('1', '#fff456') ];
build() {
Column() {
ForEach (this.models, (item) => {
CustomText({model: item})
},
(item) => item.text
)
}
}
}
`
exports.expectResult =
`"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var nextID = 0;
let Model = class Model {
constructor(t, c) {
this.text = '';
this.color = '#00ff00';
this.text = t;
this.color = c;
}
};
Model = __decorate([
Observed
], Model);
class CustomText extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__model = new SynchedPropertyNesedObjectPU(params.model, this, "model");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
this.__model.set(params.model);
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__model.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__model.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get model() {
return this.__model.get();
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Row.create();
if (!isInitialRender) {
Row.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create(this.model.text);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
Row.pop();
}
rerender() {
this.__model.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
class Parent extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.nextId = 1;
this.__models = new ObservedPropertyObjectPU([new Model('0', '#ffffff'), new Model('1', '#fff456')], this, "models");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.nextId !== undefined) {
this.nextId = params.nextId;
}
if (params.models !== undefined) {
this.models = params.models;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__models.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.nextId = undefined;
this.__models.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get models() {
return this.__models.get();
}
set models(newValue) {
this.__models.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ForEach.create();
const forEachItemGenFunction = _item => {
const item = _item;
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new CustomText(this, { model: item }));
ViewStackProcessor.StopGetAccessRecording();
}
};
const forEachItemIdFunc = item => item.text;
this.forEachUpdateFunction(elmtId, this.models, forEachItemGenFunction, forEachItemIdFunc);
if (!isInitialRender) {
ForEach.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
ForEach.pop();
Column.pop();
}
rerender() {
this.__models.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new Parent(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Component
struct PropComponent {
@Prop counter: string
build() {
Text(this.counter)
}
}
@Entry
@Component
struct ParentComponent {
@State value: string = 'first init content';
build() {
Column() {
PropComponent({counter: this.value})
}
}
}
`
exports.expectResult =
`"use strict";
class PropComponent extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__counter = new SynchedPropertySimpleOneWayPU(params.counter, this, "counter");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__counter.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__counter.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get counter() {
return this.__counter.get();
}
set counter(newValue) {
this.__counter.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create(this.counter);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
}
rerender() {
this.__counter.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
class ParentComponent extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__value = new ObservedPropertySimplePU('first init content', this, "value");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.value !== undefined) {
this.value = params.value;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__value.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__value.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get value() {
return this.__value.get();
}
set value(newValue) {
this.__value.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
{
const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
ViewPU.create(new PropComponent(this, { counter: this.__value }));
ViewStackProcessor.StopGetAccessRecording();
}
Column.pop();
}
rerender() {
this.__value.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new ParentComponent(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
exports.source = `
@Entry
@Component
struct StatePage {
@State counter: number = 0;
build() {
Column() {
Text("counter:" + this.counter)
}
}
}
`
exports.expectResult =
`"use strict";
class StatePage extends ViewPU {
constructor(parent, params, __localStorage) {
super(parent, __localStorage);
this.__counter = new ObservedPropertySimplePU(0, this, "counter");
this.setInitiallyProvidedValue(params);
}
setInitiallyProvidedValue(params) {
if (params.counter !== undefined) {
this.counter = params.counter;
}
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__counter.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__counter.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
get counter() {
return this.__counter.get();
}
set counter(newValue) {
this.__counter.set(newValue);
}
initialRender() {
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Column.create();
if (!isInitialRender) {
Column.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
this.observeComponentCreation((elmtId, isInitialRender) => {
ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
Text.create("counter:" + this.counter);
if (!isInitialRender) {
Text.pop();
}
ViewStackProcessor.StopGetAccessRecording();
});
Text.pop();
Column.pop();
}
rerender() {
this.__counter.markDependentElementsDirty(this);
this.updateDirtyElements();
}
}
ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent());
loadDocument(new StatePage(undefined, {}));
ViewStackProcessor.StopGetAccessRecording();
`