diff --git a/compiler/src/compile_info.ts b/compiler/src/compile_info.ts index 6e5fdb4f160bfd58eda8ae95f3b13dfe7e40e7a1..4312b7f40d716dd014e1507e1705836965d5220f 100644 --- a/compiler/src/compile_info.ts +++ b/compiler/src/compile_info.ts @@ -75,7 +75,6 @@ export class ResultStates { private modulePaths: Set = new Set([]); public apply(compiler: Compiler): void { - compiler.hooks.compilation.tap('SourcemapFixer', compilation => { compilation.hooks.afterProcessAssets.tap('SourcemapFixer', assets => { Reflect.ownKeys(assets).forEach(key => { @@ -110,14 +109,14 @@ export class ResultStates { stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS }, (assets) => { - const GLOBAL_COMMON_MODULE_CACHE = ` + const GLOBAL_COMMON_MODULE_CACHE = ` globalThis["__common_module_cache__${projectConfig.hashProjectPath}"] =` + ` globalThis["__common_module_cache__${projectConfig.hashProjectPath}"] || {}; globalThis["webpackChunk${projectConfig.hashProjectPath}"].forEach((item)=> { Object.keys(item[1]).forEach((element) => { globalThis["__common_module_cache__${projectConfig.hashProjectPath}"][element] = null; }) - });` + });`; if (assets['commons.js']) { assets['commons.js'] = new CachedSource( diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index 2acba62299d9d81131c222cfa7747e1cc6f63557..ab39086214152868bf55c9015e8697590c1829a6 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -37,13 +37,16 @@ export const COMPONENT_CONSUME_DECORATOR: string = '@Consume'; export const COMPONENT_OBJECT_LINK_DECORATOR: string = '@ObjectLink'; export const COMPONENT_WATCH_DECORATOR: string = '@Watch'; export const COMPONENT_BUILDERPARAM_DECORATOR: string = '@BuilderParam'; +export const COMPONENT_LOCAL_STORAGE_LINK_DECORATOR: string = '@LocalStorageLink'; +export const COMPONENT_LOCAL_STORAGE_PROP_DECORATOR: string = '@LocalStorageProp'; export const INNER_COMPONENT_DECORATORS: Set = new Set([COMPONENT_DECORATOR_ENTRY, COMPONENT_DECORATOR_PREVIEW, COMPONENT_DECORATOR_COMPONENT, COMPONENT_DECORATOR_CUSTOM_DIALOG]); export const INNER_COMPONENT_MEMBER_DECORATORS: Set = new Set([COMPONENT_STATE_DECORATOR, COMPONENT_PROP_DECORATOR, COMPONENT_LINK_DECORATOR, COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_STORAGE_LINK_DECORATOR, COMPONENT_PROVIDE_DECORATOR, COMPONENT_CONSUME_DECORATOR, - COMPONENT_OBJECT_LINK_DECORATOR, COMPONENT_WATCH_DECORATOR, COMPONENT_BUILDERPARAM_DECORATOR]); + COMPONENT_OBJECT_LINK_DECORATOR, COMPONENT_WATCH_DECORATOR, COMPONENT_BUILDERPARAM_DECORATOR, + COMPONENT_LOCAL_STORAGE_LINK_DECORATOR, COMPONENT_LOCAL_STORAGE_PROP_DECORATOR]); export const COMPONENT_OBSERVED_DECORATOR: string = '@Observed'; export const COMPONENT_BUILDER_DECORATOR: string = '@Builder'; @@ -105,6 +108,9 @@ export const COMPONENT_CONSTRUCTOR_ID: string = 'compilerAssignedUniqueChildId'; export const COMPONENT_CONSTRUCTOR_PARENT: string = 'parent'; export const COMPONENT_CONSTRUCTOR_PARAMS: string = 'params'; export const COMPONENT_CONSTRUCTOR_UNDEFINED: string = 'undefined'; +export const COMPONENT_CONSTRUCTOR_LOCALSTORAGE: string = 'localStorage'; +export const COMPONENT_SET_AND_LINK: string = 'setAndLink'; +export const COMPONENT_SET_AND_PROP: string = 'setAndProp'; export const BUILD_ON: string = 'on'; export const BUILD_OFF: string = 'off'; diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index d8db918fd416a9323798ec6d057af6ac9af0115c..5729b3898ff6ffa1b17ee7a31403955a4ce79701 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -622,7 +622,7 @@ function processDragStartBuilder(node: ts.CallExpression): ts.CallExpression { // @ts-ignore for (let i = 0; i < node.arguments[0].body.statements.length; i++) { // @ts-ignore - let statement: ts.Statement = node.arguments[0].body.statements[i]; + const statement: ts.Statement = node.arguments[0].body.statements[i]; newStatements.push(checkStatement(statement)); } node = ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [ts.factory.updateArrowFunction( @@ -644,7 +644,7 @@ function checkStatement(statement: ts.Statement): ts.Statement { if (ts.isObjectLiteralExpression(statement.expression)) { const newProperties: ts.ObjectLiteralElementLike[] = []; for (let j = 0; j < statement.expression.properties.length; j++) { - let property: ts.ObjectLiteralElementLike = statement.expression.properties[j]; + const property: ts.ObjectLiteralElementLike = statement.expression.properties[j]; checkProperty(property); newProperties.push(property); } diff --git a/compiler/src/process_component_class.ts b/compiler/src/process_component_class.ts index 38f0c8ef8d0a622afd6fad45bc594c182bd788fe..299ce972583058dd9ce32caa5dc47f1e3a0bf9e7 100644 --- a/compiler/src/process_component_class.ts +++ b/compiler/src/process_component_class.ts @@ -31,8 +31,6 @@ import { OBSERVED_PROPERTY_SIMPLE, COMPONENT_BUILD_FUNCTION, BASE_COMPONENT_NAME, - ATTRIBUTE_ANIMATETO, - GLOBAL_CONTEXT, CREATE_CONSTRUCTOR_PARAMS, COMPONENT_CONSTRUCTOR_UPDATE_PARAMS, COMPONENT_CONSTRUCTOR_DELETE_PARAMS, @@ -50,7 +48,13 @@ import { COMPONENT_STYLES_DECORATOR, STYLES, INTERFACE_NAME_SUFFIX, - OBSERVED_PROPERTY_ABSTRACT + OBSERVED_PROPERTY_ABSTRACT, + COMPONENT_LOCAL_STORAGE_LINK_DECORATOR, + COMPONENT_LOCAL_STORAGE_PROP_DECORATOR, + COMPONENT_CONSTRUCTOR_LOCALSTORAGE, + COMPONENT_SET_AND_LINK, + COMPONENT_SET_AND_PROP, + COMPONENT_CONSTRUCTOR_UNDEFINED } from './pre_define'; import { BUILDIN_STYLE_NAMES, @@ -61,7 +65,9 @@ import { } from './component_map'; import { componentCollection, - linkCollection + linkCollection, + localStorageLinkCollection, + localStoragePropCollection } from './validate_ui_syntax'; import { addConstructor, @@ -128,9 +134,9 @@ function processMembers(members: ts.NodeArray, parentComponentN members.forEach((item: ts.ClassElement) => { let updateItem: ts.ClassElement; if (ts.isPropertyDeclaration(item)) { - addPropertyMember(item, newMembers, program); const result: UpdateResult = processMemberVariableDecorators(parentComponentName, item, ctorNode, watchMap, checkController, log, program, context, hasPreview, interfaceNode); + addPropertyMember(item, newMembers, program, parentComponentName.getText()); if (result.isItemUpdate()) { updateItem = result.getProperity(); } else { @@ -173,7 +179,7 @@ function processMembers(members: ts.NodeArray, parentComponentN } function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[], - program: ts.Program):void { + program: ts.Program, parentComponentName: string):void { const propertyItem: ts.PropertyDeclaration = item as ts.PropertyDeclaration; let decoratorName: string; let updatePropertyItem: ts.PropertyDeclaration; @@ -185,6 +191,7 @@ function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[], for (let i = 0; i < propertyItem.decorators.length; i++) { 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: @@ -206,8 +213,15 @@ function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[], case COMPONENT_STORAGE_LINK_DECORATOR: newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [type]); break; + case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR: + case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR: + newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [type? type : + ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)]); + isLocalStorage = true; + break; } - updatePropertyItem = createPropertyDeclaration(propertyItem, newType, false); + updatePropertyItem = createPropertyDeclaration(propertyItem, newType, false, + isLocalStorage, parentComponentName); if (updatePropertyItem) { newMembers.push(updatePropertyItem); } @@ -216,7 +230,8 @@ function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[], } function createPropertyDeclaration(propertyItem: ts.PropertyDeclaration, newType: ts.TypeNode | undefined, - normalVar: boolean): ts.PropertyDeclaration { + normalVar: boolean, isLocalStorage: boolean = false, parentComponentName: string = null + ): ts.PropertyDeclaration { if (typeof newType === undefined) { return undefined; } @@ -228,7 +243,33 @@ function createPropertyDeclaration(propertyItem: ts.PropertyDeclaration, newType ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword); return ts.factory.updatePropertyDeclaration(propertyItem, undefined, propertyItem.modifiers || [privateM], prefix + propertyItem.name.getText(), - propertyItem.questionToken, newType, undefined); + propertyItem.questionToken, newType, isLocalStorage ? + createLocalStroageCallExpression(propertyItem, propertyItem.name.getText(), + parentComponentName) : undefined); +} + +function createLocalStroageCallExpression(node: ts.PropertyDeclaration, name: string, + parentComponentName: string): ts.CallExpression { + const localStorageLink: Set = localStorageLinkCollection.get(parentComponentName).get(name); + const localStorageProp: Set = localStoragePropCollection.get(parentComponentName).get(name); + return ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createThis(), + ts.factory.createIdentifier(`${COMPONENT_CONSTRUCTOR_LOCALSTORAGE}_`) + ), + ts.factory.createIdentifier(localStorageLink && !localStorageProp ? COMPONENT_SET_AND_LINK : + COMPONENT_SET_AND_PROP) + ), + [node.type], + [ + ts.factory.createStringLiteral(localStorageLink && !localStorageProp ? + Array.from(localStorageLink)[0] : Array.from(localStorageProp)[0]), + ts.factory.createNumericLiteral(node.initializer ? node.initializer.getText() + : COMPONENT_CONSTRUCTOR_UNDEFINED), ts.factory.createThis(), + ts.factory.createStringLiteral(name || COMPONENT_CONSTRUCTOR_UNDEFINED) + ] + ); } function processComponentMethod(node: ts.MethodDeclaration, parentComponentName: ts.Identifier, diff --git a/compiler/src/process_component_constructor.ts b/compiler/src/process_component_constructor.ts index 36f56baa33f1625bd7efaa4c19c954e28a904ca5..0b1b383107d3c173d37e7f5d5b8eb434f8a3cd86 100644 --- a/compiler/src/process_component_constructor.ts +++ b/compiler/src/process_component_constructor.ts @@ -18,6 +18,7 @@ import ts from 'typescript'; import { COMPONENT_CONSTRUCTOR_ID, COMPONENT_CONSTRUCTOR_PARENT, + COMPONENT_CONSTRUCTOR_LOCALSTORAGE, COMPONENT_CONSTRUCTOR_PARAMS, COMPONENT_CONSTRUCTOR_UPDATE_PARAMS, COMPONENT_WATCH_FUNCTION, @@ -25,6 +26,11 @@ import { INTERFACE_NAME_SUFFIX } from './pre_define'; +import { + localStorageLinkCollection, + localStoragePropCollection +} from './validate_ui_syntax'; + export function getInitConstructor(members: ts.NodeArray): ts.ConstructorDeclaration { let ctorNode: any = members.find(item => { return ts.isConstructorDeclaration(item); @@ -74,6 +80,8 @@ function addParamsType(ctorNode: ts.ConstructorDeclaration, modifyPara: ts.Param const tsPara: ts.ParameterDeclaration[] | ts.NodeArray = modifyPara || ctorNode.parameters; const newTSPara: ts.ParameterDeclaration[] = []; + const localStorageLink: number = localStorageLinkCollection.get(parentComponentName.getText()).size; + const localStorageProp: number = localStoragePropCollection.get(parentComponentName.getText()).size; tsPara.forEach((item) => { let parameter: ts.ParameterDeclaration = item; switch (item.getText()) { @@ -94,8 +102,18 @@ 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 + '?': + localStorageLink + localStorageProp > 0 ? + parameter = ts.factory.updateParameterDeclaration(item, item.decorators, item.modifiers, + item.dotDotDotToken, item.name, item.questionToken, + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_LOCALSTORAGE + .toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase())), undefined), item.initializer) : + parameter = undefined; + break; + } + if (parameter) { + newTSPara.push(parameter); } - newTSPara.push(parameter); }); return newTSPara; } @@ -103,6 +121,8 @@ function addParamsType(ctorNode: ts.ConstructorDeclaration, modifyPara: ts.Param export function addConstructor(ctorNode: any, watchMap: Map, parentComponentName: ts.Identifier): ts.ConstructorDeclaration { const watchStatements: ts.ExpressionStatement[] = []; + const localStorageLink: number = localStorageLinkCollection.get(parentComponentName.getText()).size; + const localStorageProp: number = localStoragePropCollection.get(parentComponentName.getText()).size; watchMap.forEach((value, key) => { const watchNode: ts.ExpressionStatement = ts.factory.createExpressionStatement( ts.factory.createCallExpression( @@ -122,8 +142,11 @@ export function addConstructor(ctorNode: any, watchMap: Map, }); const callSuperStatement: ts.Statement = ts.factory.createExpressionStatement( ts.factory.createCallExpression(ts.factory.createSuper(), undefined, - [ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_ID), - ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT)])); + [ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_ID), + localStorageLink + localStorageProp > 0 ? + (ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT), + ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_LOCALSTORAGE)): + 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)), diff --git a/compiler/src/process_component_member.ts b/compiler/src/process_component_member.ts index 77ddab7d4e8dbd827a2f642c0f7a354fa478884c..20477643fbaa264ec14a900564058dc09969dceb 100644 --- a/compiler/src/process_component_member.ts +++ b/compiler/src/process_component_member.ts @@ -52,7 +52,9 @@ import { CUSTOM_DIALOG_CONTROLLER_BUILDER, BASE_COMPONENT_NAME, COMPONENT_CREATE_FUNCTION, - COMPONENT_BUILDERPARAM_DECORATOR + COMPONENT_BUILDERPARAM_DECORATOR, + COMPONENT_LOCAL_STORAGE_LINK_DECORATOR, + COMPONENT_LOCAL_STORAGE_PROP_DECORATOR } from './pre_define'; import { forbiddenUseStateType, @@ -87,7 +89,8 @@ export const propAndLinkDecorators: Set = new Set([COMPONENT_PROP_DECORATOR, COMPONENT_LINK_DECORATOR]); export const appStorageDecorators: Set = - new Set([COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_STORAGE_LINK_DECORATOR]); + new Set([COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_STORAGE_LINK_DECORATOR, + COMPONENT_LOCAL_STORAGE_LINK_DECORATOR, COMPONENT_LOCAL_STORAGE_PROP_DECORATOR]); export const mandatorySpecifyDefaultValueDecorators: Set = new Set([...observedPropertyDecorators, ...appStorageDecorators]); diff --git a/compiler/src/process_ui_syntax.ts b/compiler/src/process_ui_syntax.ts index e3221796c198461c2af668be4c13f3bd4de13940..5e87fb901bff65275d65475db6f191e9d87eab50 100644 --- a/compiler/src/process_ui_syntax.ts +++ b/compiler/src/process_ui_syntax.ts @@ -443,12 +443,18 @@ function isAttributeBlockNode(node: ts.ExpressionStatement, arr: ts.Statement[], function createEntryFunction(name: string, context: ts.TransformationContext) : ts.ExpressionStatement { + let localStorageName: string; + if (componentCollection.entryComponent === name && componentCollection.localStorageName) { + localStorageName = componentCollection.localStorageName; + } 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.createStringLiteral((++componentInfo.id).toString()), context.factory.createIdentifier(COMPONENT_CONSTRUCTOR_UNDEFINED), - context.factory.createObjectLiteralExpression([], false)])])); + localStorageName ? (context.factory.createObjectLiteralExpression([], false), + context.factory.createIdentifier(localStorageName)) : + context.factory.createObjectLiteralExpression([], false)])])); } export function resetLog(): void { diff --git a/compiler/src/validate_ui_syntax.ts b/compiler/src/validate_ui_syntax.ts index 5dd4474de06c4905656f6b5f87e39dea53bcb593..791de79a338bcc55ea4caef0c0c9d0a30f6e2eac 100644 --- a/compiler/src/validate_ui_syntax.ts +++ b/compiler/src/validate_ui_syntax.ts @@ -39,8 +39,11 @@ import { COMPONENT_CONSUME_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR, COMPONENT_CONSTRUCTOR_ID, + COMPONENT_CONSTRUCTOR_LOCALSTORAGE, COMPONENT_CONSTRUCTOR_PARENT, COMPONENT_CONSTRUCTOR_PARAMS, + COMPONENT_LOCAL_STORAGE_LINK_DECORATOR, + COMPONENT_LOCAL_STORAGE_PROP_DECORATOR, COMPONENT_OBSERVED_DECORATOR, STYLES, VALIDATE_MODULE, @@ -68,6 +71,7 @@ import { projectConfig } from '../main'; const parser = require('../syntax_parser/dist/exclude_comment.js'); export interface ComponentCollection { + localStorageName: string; entryComponent: string; previewComponent: string; customDialogs: Set; @@ -86,9 +90,12 @@ export interface IComponentSet { provides: Set; consumes: Set; objectLinks: Set; + localStorageLink: Map>; + localStorageProp: Map>; } export const componentCollection: ComponentCollection = { + localStorageName: null, entryComponent: null, previewComponent: null, customDialogs: new Set([]), @@ -111,6 +118,8 @@ export const storageLinkCollection: Map> = new Map(); export const provideCollection: Map> = new Map(); export const consumeCollection: Map> = new Map(); export const objectLinkCollection: Map> = new Map(); +export const localStorageLinkCollection: Map>> = new Map(); +export const localStoragePropCollection: Map>> = new Map(); export const isStaticViewCollection: Map = new Map(); @@ -278,6 +287,7 @@ function checkDecorators(node: ts.MissingDeclaration | ts.ExportAssignment, resu case COMPONENT_DECORATOR_ENTRY: result.entryCount++; componentCollection.entryComponent = componentName; + collectLocalStorageName(element); break; case COMPONENT_DECORATOR_PREVIEW: result.previewCount++; @@ -313,6 +323,19 @@ function checkDecorators(node: ts.MissingDeclaration | ts.ExportAssignment, resu } } +function collectLocalStorageName(node: ts.Decorator): void { + if (node && node.expression && ts.isCallExpression(node.expression) && node.expression.arguments + && node.expression.arguments.length) { + node.expression.arguments.forEach((item: ts.Identifier, index: number) => { + if (ts.isIdentifier(item) && index === 0) { + componentCollection.localStorageName = item.getText(); + } + }); + } else { + componentCollection.localStorageName = null; + } +} + function checkUISyntax(filePath: string, allComponentNames: Set, content: string, log: LogInfo[]): void { const sourceFile: ts.SourceFile = ts.createSourceFile(filePath, content, @@ -641,7 +664,8 @@ function collectComponentProps(node: ts.ClassDeclaration): void { storageLinkCollection.set(componentName, ComponentSet.storageLinks); provideCollection.set(componentName, ComponentSet.provides); consumeCollection.set(componentName, ComponentSet.consumes); - objectLinkCollection.set(componentName, ComponentSet.objectLinks); + localStorageLinkCollection.set(componentName, ComponentSet.localStorageLink); + localStoragePropCollection.set(componentName, ComponentSet.localStorageProp); } export function getComponentSet(node: ts.ClassDeclaration): IComponentSet { @@ -655,18 +679,21 @@ export function getComponentSet(node: ts.ClassDeclaration): IComponentSet { const provides: Set = new Set(); const consumes: Set = new Set(); const objectLinks: Set = new Set(); + const localStorageLink: Map> = new Map(); + const localStorageProp: Map> = new Map(); traversalComponentProps(node, propertys, regulars, states, links, props, storageProps, - storageLinks, provides, consumes, objectLinks); + storageLinks, provides, consumes, objectLinks, localStorageLink, localStorageProp); return { propertys, regulars, states, links, props, storageProps, storageLinks, provides, - consumes, objectLinks + consumes, objectLinks, localStorageLink, localStorageProp }; } function traversalComponentProps(node: ts.ClassDeclaration, propertys: Set, regulars: Set, states: Set, links: Set, props: Set, storageProps: Set, storageLinks: Set, provides: Set, - consumes: Set, objectLinks: Set): void { + consumes: Set, objectLinks: Set, + localStorageLink: Map>, localStorageProp: Map>): void { let isStatic: boolean = true; if (node.members) { const currentMethodCollection: Set = new Set(); @@ -682,8 +709,8 @@ function traversalComponentProps(node: ts.ClassDeclaration, propertys: Set, links: Set, - props: Set, storageProps: Set, storageLinks: Set, provides: Set, - consumes: Set, objectLinks: Set): void { +function collectionStates(node: ts.Decorator, decorator: string, name: string, + states: Set, links: Set, props: Set, storageProps: Set, + storageLinks: Set, provides: Set, consumes: Set, objectLinks: Set, + localStorageLink: Map>, localStorageProp: Map>): void { switch (decorator) { case COMPONENT_STATE_DECORATOR: states.add(name); @@ -725,6 +753,22 @@ function collectionStates(decorator: string, name: string, states: Set, case COMPONENT_OBJECT_LINK_DECORATOR: objectLinks.add(name); break; + case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR : + collectionlocalStorageParam(node, name, localStorageLink); + break; + case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR: + collectionlocalStorageParam(node, name, localStorageProp); + break; + } +} + +function collectionlocalStorageParam(node: ts.Decorator, name: string, + localStorage: Map>): void { + const localStorageParam: Set = new Set(); + if (node && ts.isCallExpression(node.expression) && node.expression.arguments && + node.expression.arguments.length && ts.isStringLiteral(node.expression.arguments[0])) { + localStorage.set(name, localStorageParam.add( + node.expression.arguments[0].getText().replace(/\"/g, ''))); } } @@ -740,7 +784,8 @@ export function sourceReplace(source: string, sourcePath: string): ReplaceResult content = content.replace( new RegExp('\\b' + STRUCT + '\\b.+\\{', 'g'), item => { item = item.replace(new RegExp('\\b' + STRUCT + '\\b', 'g'), `${CLASS} `); - return `${item} constructor(${COMPONENT_CONSTRUCTOR_ID}?, ${COMPONENT_CONSTRUCTOR_PARENT}?, ${COMPONENT_CONSTRUCTOR_PARAMS}?) {}`; + return `${item} constructor(${COMPONENT_CONSTRUCTOR_ID}?, ${COMPONENT_CONSTRUCTOR_PARENT}?, + ${COMPONENT_CONSTRUCTOR_PARAMS}? ,${COMPONENT_CONSTRUCTOR_LOCALSTORAGE}?) {}`; }); content = preprocessExtend(content, sourcePath, log); diff --git a/compiler/test/ut/localStorage/localStorage.ts b/compiler/test/ut/localStorage/localStorage.ts new file mode 100644 index 0000000000000000000000000000000000000000..fa7920178c0d9ef5d498fb4992be3ffb8558f028 --- /dev/null +++ b/compiler/test/ut/localStorage/localStorage.ts @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +exports.source = ` +let storage = LocalStorage.GetShared(); + +class ClassA { + public id: number = 1; + public type: number = 2; + public a: string = "aaa"; + constructor(a: string){ + this.a = a; + } +} + +@Entry(storage) +@Component +struct LocalStorageComponent { + @LocalStorageLink("storageSimpleProp") simpleVarName: number = 0; + @LocalStorageProp("storageObjectProp") objectName: ClassA = new ClassA("x"); + build() { + Column() { + Text(this.objectName.a) + .onClick(()=>{ + this.simpleVarName +=1; + this.objectName.a = this.objectName.a === 'x' ? 'yex' : 'no'; + }) + } + .height(500) + } +} +` +exports.expectResult = +`let storage = LocalStorage.GetShared(); +class ClassA { + constructor(a) { + this.id = 1; + this.type = 2; + this.a = "aaa"; + this.a = a; + } +} +class LocalStorageComponent extends View { + constructor(compilerAssignedUniqueChildId, parent, params, localStorage) { + super(compilerAssignedUniqueChildId, localStorage); + this.__simpleVarName = this.localStorage_.setAndLink("storageSimpleProp", 0, this, "simpleVarName"); + this.__objectName = this.localStorage_.setAndProp("storageObjectProp", new ClassA("x"), this, "objectName"); + this.updateWithValueParams(params); + } + updateWithValueParams(params) { + } + aboutToBeDeleted() { + this.__simpleVarName.aboutToBeDeleted(); + this.__objectName.aboutToBeDeleted(); + SubscriberManager.Get().delete(this.id()); + } + get simpleVarName() { + return this.__simpleVarName.get(); + } + set simpleVarName(newValue) { + this.__simpleVarName.set(newValue); + } + get objectName() { + return this.__objectName.get(); + } + set objectName(newValue) { + this.__objectName.set(newValue); + } + render() { + Column.create(); + Column.height(500); + Text.create(this.objectName.a); + Text.onClick(() => { + this.simpleVarName += 1; + this.objectName.a = this.objectName.a === 'x' ? 'yex' : 'no'; + }); + Text.pop(); + Column.pop(); + } +} +loadDocument(new LocalStorageComponent("1", undefined, storage)); +` diff --git a/compiler/test/ut/struct/struct_02.ts b/compiler/test/ut/struct/struct_02.ts index 175a1085d27a9c70852b6fe7277399ad305e9d3f..258c6fda5418a0713eedc4e97d8ab381d5d19f0b 100644 --- a/compiler/test/ut/struct/struct_02.ts +++ b/compiler/test/ut/struct/struct_02.ts @@ -21,7 +21,7 @@ struct MyComponent { exports.expectResult = `class MyComponent { - constructor(compilerAssignedUniqueChildId, parent, params) { } + constructor(compilerAssignedUniqueChildId, parent, params, localStorage) { } build() { } }