• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import ts from 'typescript';
17
18import {
19  COMPONENT_STATE_DECORATOR,
20  COMPONENT_PROVIDE_DECORATOR,
21  COMPONENT_LINK_DECORATOR,
22  COMPONENT_PROP_DECORATOR,
23  COMPONENT_STORAGE_LINK_DECORATOR,
24  COMPONENT_STORAGE_PROP_DECORATOR,
25  COMPONENT_OBJECT_LINK_DECORATOR,
26  COMPONENT_CONSUME_DECORATOR,
27  SYNCHED_PROPERTY_NESED_OBJECT,
28  SYNCHED_PROPERTY_SIMPLE_TWO_WAY,
29  SYNCHED_PROPERTY_SIMPLE_ONE_WAY,
30  OBSERVED_PROPERTY_OBJECT,
31  OBSERVED_PROPERTY_SIMPLE,
32  COMPONENT_BUILD_FUNCTION,
33  BASE_COMPONENT_NAME,
34  CREATE_CONSTRUCTOR_PARAMS,
35  COMPONENT_CONSTRUCTOR_UPDATE_PARAMS,
36  COMPONENT_CONSTRUCTOR_INITIAL_PARAMS,
37  COMPONENT_CONSTRUCTOR_PURGE_VARIABLE_DEP,
38  COMPONENT_CONSTRUCTOR_DELETE_PARAMS,
39  COMPONENT_DECORATOR_PREVIEW,
40  CREATE_CONSTRUCTOR_SUBSCRIBER_MANAGER,
41  ABOUT_TO_BE_DELETE_FUNCTION_ID,
42  ABOUT_TO_BE_DELETE_FUNCTION_ID__,
43  CREATE_CONSTRUCTOR_GET_FUNCTION,
44  CREATE_CONSTRUCTOR_DELETE_FUNCTION,
45  FOREACH_OBSERVED_OBJECT,
46  FOREACH_GET_RAW_OBJECT,
47  COMPONENT_BUILDER_DECORATOR,
48  COMPONENT_TRANSITION_FUNCTION,
49  COMPONENT_CREATE_FUNCTION,
50  GEOMETRY_VIEW,
51  COMPONENT_STYLES_DECORATOR,
52  STYLES,
53  INTERFACE_NAME_SUFFIX,
54  OBSERVED_PROPERTY_ABSTRACT,
55  COMPONENT_LOCAL_STORAGE_LINK_DECORATOR,
56  COMPONENT_LOCAL_STORAGE_PROP_DECORATOR,
57  COMPONENT_CONSTRUCTOR_LOCALSTORAGE,
58  COMPONENT_SET_AND_LINK,
59  COMPONENT_SET_AND_PROP,
60  COMPONENT_CONSTRUCTOR_UNDEFINED,
61  CUSTOM_COMPONENT,
62  COMPONENT_CONSTRUCTOR_PARENT,
63  NULL,
64  INNER_COMPONENT_MEMBER_DECORATORS,
65  COMPONENT_RERENDER_FUNCTION,
66  RMELMTID,
67  ABOUTTOBEDELETEDINTERNAL,
68  UPDATEDIRTYELEMENTS,
69  BASE_COMPONENT_NAME_PU,
70  OBSERVED_PROPERTY_SIMPLE_PU,
71  OBSERVED_PROPERTY_OBJECT_PU,
72  SYNCHED_PROPERTY_SIMPLE_TWO_WAY_PU,
73  SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
74  SYNCHED_PROPERTY_NESED_OBJECT_PU,
75  OBSERVED_PROPERTY_ABSTRACT_PU,
76  CREATE_LOCAL_STORAGE_LINK,
77  CREATE_LOCAL_STORAGE_PROP,
78  COMPONENT_UPDATE_STATE_VARS,
79  COMPONENT_WATCH_DECORATOR,
80  $$,
81  COMPONENT_UPDATE_ELMT_ID,
82  OLD_ELMT_ID,
83  NEW_ELMT_ID,
84  UPDATE_RECYCLE_ELMT_ID,
85  GET_ENTRYNAME,
86  COMPONENT_PARAMS_FUNCTION,
87  FUNCTION,
88  COMPONENT_PARAMS_LAMBDA_FUNCTION,
89  DECORATOR_COMPONENT_FREEZEWHENINACTIVE,
90  INIT_ALLOW_COMPONENT_FREEZE
91} from './pre_define';
92import {
93  BUILDIN_STYLE_NAMES,
94  CUSTOM_BUILDER_METHOD,
95  INNER_STYLE_FUNCTION,
96  INTERFACE_NODE_SET,
97  STYLES_ATTRIBUTE,
98  INNER_CUSTOM_BUILDER_METHOD
99} from './component_map';
100import {
101  componentCollection,
102  linkCollection,
103  localStorageLinkCollection,
104  localStoragePropCollection,
105  builderParamObjectCollection
106} from './validate_ui_syntax';
107import {
108  addConstructor,
109  getInitConstructor,
110  updateConstructor
111} from './process_component_constructor';
112import {
113  ControllerType,
114  processMemberVariableDecorators,
115  UpdateResult,
116  stateObjectCollection,
117  curPropMap,
118  decoratorParamSet,
119  isSimpleType,
120  isSingleKey,
121  findDecoratorIndex
122} from './process_component_member';
123import {
124  processComponentBuild,
125  processComponentBlock
126} from './process_component_build';
127import {
128  LogType,
129  LogInfo,
130  hasDecorator,
131  getPossibleBuilderTypeParameter,
132  storedFileInfo
133} from './utils';
134import {
135  partialUpdateConfig,
136  projectConfig
137} from '../main';
138import {
139  builderTypeParameter,
140  initializeMYIDS
141} from './process_ui_syntax';
142
143export function processComponentClass(node: ts.StructDeclaration, context: ts.TransformationContext,
144  log: LogInfo[], program: ts.Program): ts.ClassDeclaration {
145  const decoratorNode: readonly ts.Decorator[] = ts.getAllDecorators(node);
146  const memberNode: ts.ClassElement[] =
147    processMembers(node.members, node.name, context, decoratorNode, log, program, checkPreview(node));
148  return ts.factory.createClassDeclaration(ts.getModifiers(node), node.name,
149    node.typeParameters, updateHeritageClauses(node, log), memberNode);
150}
151
152function checkPreview(node: ts.StructDeclaration): boolean {
153  let hasPreview: boolean = false;
154  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
155  if (node && decorators) {
156    for (let i = 0; i < decorators.length; i++) {
157      const name: string = decorators[i].getText().replace(/\([^\(\)]*\)/, '').trim();
158      if (name === COMPONENT_DECORATOR_PREVIEW) {
159        hasPreview = true;
160        break;
161      }
162    }
163  }
164  return hasPreview;
165}
166
167type BuildCount = {
168  count: number;
169}
170type FreezeParamType = {
171  componentFreezeParam: ts.Expression;
172}
173function processMembers(members: ts.NodeArray<ts.ClassElement>, parentComponentName: ts.Identifier,
174  context: ts.TransformationContext, decoratorNode: readonly ts.Decorator[], log: LogInfo[],
175  program: ts.Program, hasPreview: boolean): ts.ClassElement[] {
176  const buildCount: BuildCount = { count: 0 };
177  let ctorNode: any = getInitConstructor(members, parentComponentName);
178  const newMembers: ts.ClassElement[] = [];
179  const watchMap: Map<string, ts.Node> = new Map();
180  const updateParamsStatements: ts.Statement[] = [];
181  const stateVarsStatements: ts.Statement[] = [];
182  const purgeVariableDepStatements: ts.Statement[] = [];
183  const rerenderStatements: ts.Statement[] = [];
184  const deleteParamsStatements: ts.PropertyDeclaration[] = [];
185  const checkController: ControllerType =
186    { hasController: !componentCollection.customDialogs.has(parentComponentName.getText()) };
187  const interfaceNode = ts.factory.createInterfaceDeclaration(undefined,
188    parentComponentName.getText() + INTERFACE_NAME_SUFFIX, undefined, undefined, []);
189  members.forEach((item: ts.ClassElement) => {
190    let updateItem: ts.ClassElement;
191    if (ts.isPropertyDeclaration(item)) {
192      if (isStaticProperty(item)) {
193        newMembers.push(item);
194        validateDecorators(item, log);
195      } else {
196        addPropertyMember(item, newMembers, program, parentComponentName.getText(), log);
197        const result: UpdateResult = processMemberVariableDecorators(parentComponentName, item,
198          ctorNode, watchMap, checkController, log, program, context, hasPreview, interfaceNode);
199        if (result.isItemUpdate()) {
200          updateItem = result.getProperity();
201        } else {
202          updateItem = item;
203        }
204        if (result.getVariableGet()) {
205          newMembers.push(result.getVariableGet());
206        }
207        if (result.getVariableSet()) {
208          newMembers.push(result.getVariableSet());
209        }
210        if (result.isCtorUpdate()) {
211          ctorNode = result.getCtor();
212        }
213        if (result.getUpdateParams()) {
214          updateParamsStatements.push(result.getUpdateParams());
215        }
216        if (result.getStateVarsParams()) {
217          stateVarsStatements.push(result.getStateVarsParams());
218        }
219        if (result.isDeleteParams()) {
220          deleteParamsStatements.push(item);
221        }
222        if (result.getControllerSet()) {
223          newMembers.push(result.getControllerSet());
224        }
225        processPropertyUnchanged(result, purgeVariableDepStatements);
226      }
227    }
228    if (ts.isMethodDeclaration(item) && item.name) {
229      updateItem =
230        processComponentMethod(item, parentComponentName, context, log, buildCount);
231    }
232    if (updateItem) {
233      newMembers.push(updateItem);
234    }
235  });
236  INTERFACE_NODE_SET.add(interfaceNode);
237  validateBuildMethodCount(buildCount, parentComponentName, log);
238  validateHasController(parentComponentName, checkController, log);
239  if (storedFileInfo.getCurrentArkTsFile().recycleComponents.has(parentComponentName.getText())) {
240    newMembers.unshift(addDeleteParamsFunc(deleteParamsStatements, true));
241  }
242  newMembers.unshift(addDeleteParamsFunc(deleteParamsStatements));
243  addIntoNewMembers(newMembers, parentComponentName, updateParamsStatements,
244    purgeVariableDepStatements, rerenderStatements, stateVarsStatements);
245  if (partialUpdateConfig.partialUpdateMode) {
246    const creezeParam: FreezeParamType = {
247      componentFreezeParam: undefined
248    };
249    const isFreezeComponent: boolean = decoratorAssignParams(decoratorNode, context, creezeParam);
250    ctorNode = updateConstructor(ctorNode, [], assignParams(parentComponentName.getText()),
251      isFreezeComponent ? decoratorComponentParam(creezeParam) : [], true);
252  }
253  newMembers.unshift(addConstructor(ctorNode, watchMap, parentComponentName));
254  if (componentCollection.entryComponent === parentComponentName.escapedText.toString() &&
255    partialUpdateConfig.partialUpdateMode && projectConfig.minAPIVersion > 10) {
256    newMembers.push(getEntryNameFunction(componentCollection.entryComponent));
257  }
258  curPropMap.clear();
259  return newMembers;
260}
261
262function decoratorAssignParams(decoratorNode: readonly ts.Decorator[], context: ts.TransformationContext,
263  creezeParam: FreezeParamType): boolean {
264  if (decoratorNode && Array.isArray(decoratorNode) && decoratorNode.length) {
265    return decoratorNode.some((item: ts.Decorator) => {
266      if (isFreezeComponents(item, context, creezeParam)) {
267        return true;
268      } else {
269        return false;
270      }
271    });
272  } else {
273    return false;
274  }
275}
276
277function isFreezeComponents(decorator: ts.Decorator, context: ts.TransformationContext,
278  creezeParam: FreezeParamType): boolean {
279  let isComponentAssignParent: boolean = false;
280  ts.visitNode(decorator, visitComponentParament);
281  function visitComponentParament(decorator: ts.Node): ts.Node {
282    if (ts.isPropertyAssignment(decorator) && decorator.name && decorator.name.text &&
283      decorator.name.text.toString() === DECORATOR_COMPONENT_FREEZEWHENINACTIVE) {
284      isComponentAssignParent = true;
285      creezeParam.componentFreezeParam = decorator.initializer;
286      return decorator;
287    }
288    return ts.visitEachChild(decorator, visitComponentParament, context);
289  }
290  return isComponentAssignParent;
291}
292
293function getEntryNameFunction(entryName: string): ts.MethodDeclaration {
294  return ts.factory.createMethodDeclaration(
295    [ts.factory.createToken(ts.SyntaxKind.StaticKeyword)],
296    undefined,
297    ts.factory.createIdentifier(GET_ENTRYNAME),
298    undefined,
299    undefined,
300    [],
301    ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
302    ts.factory.createBlock(
303      [ts.factory.createReturnStatement(ts.factory.createStringLiteral(entryName))],
304      true
305    )
306  );
307}
308
309function assignParams(parentComponentName: string): ts.Statement[] {
310  return [ts.factory.createIfStatement(
311    ts.factory.createBinaryExpression(
312      ts.factory.createTypeOfExpression(ts.factory.createIdentifier(COMPONENT_PARAMS_LAMBDA_FUNCTION)),
313      ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
314      ts.factory.createStringLiteral(FUNCTION)
315    ),
316    ts.factory.createBlock(
317      [ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(
318        ts.factory.createPropertyAccessExpression(
319          ts.factory.createThis(),
320          ts.factory.createIdentifier(COMPONENT_PARAMS_FUNCTION)
321        ),
322        ts.factory.createToken(ts.SyntaxKind.EqualsToken),
323        ts.factory.createIdentifier(COMPONENT_PARAMS_LAMBDA_FUNCTION)
324      ))],
325      true
326    )
327  )];
328}
329
330function decoratorComponentParam(freezeParam: FreezeParamType): ts.IfStatement[] {
331  return [ts.factory.createIfStatement(
332    ts.factory.createBinaryExpression(
333      ts.factory.createElementAccessExpression(
334        ts.factory.createSuper(),
335        ts.factory.createStringLiteral(INIT_ALLOW_COMPONENT_FREEZE)
336      ),
337      ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken),
338      ts.factory.createBinaryExpression(
339        ts.factory.createTypeOfExpression(ts.factory.createElementAccessExpression(
340          ts.factory.createSuper(),
341          ts.factory.createStringLiteral(INIT_ALLOW_COMPONENT_FREEZE)
342        )),
343        ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
344        ts.factory.createStringLiteral(FUNCTION)
345      )
346    ),
347    ts.factory.createBlock(
348      [ts.factory.createExpressionStatement(ts.factory.createCallExpression(
349        ts.factory.createElementAccessExpression(
350          ts.factory.createSuper(),
351          ts.factory.createStringLiteral(INIT_ALLOW_COMPONENT_FREEZE)
352        ),
353        undefined,
354        [freezeParam.componentFreezeParam]
355      ))],
356      true
357    ),
358    undefined
359  )];
360}
361
362function isStaticProperty(property: ts.PropertyDeclaration): boolean {
363  const modifiers: readonly ts.Modifier[] =
364    ts.canHaveModifiers(property) ? ts.getModifiers(property) : undefined;
365  return modifiers && modifiers.length && modifiers.some(modifier => {
366    return modifier.kind === ts.SyntaxKind.StaticKeyword;
367  });
368}
369
370function validateDecorators(item: ts.ClassElement, log: LogInfo[]): void {
371  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(item);
372  if (decorators && decorators.length) {
373    decorators.map((decorator: ts.Decorator) => {
374      const decoratorName: string = decorator.getText();
375      if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName)) {
376        log.push({
377          type: LogType.ERROR,
378          message: `The static variable of struct cannot be used together with built-in decorators.`,
379          pos: item.getStart()
380        });
381      }
382    });
383  }
384}
385
386function processPropertyUnchanged(
387  result: UpdateResult,
388  purgeVariableDepStatements: ts.Statement[]
389): void {
390  if (partialUpdateConfig.partialUpdateMode) {
391    if (result.getPurgeVariableDepStatement()) {
392      purgeVariableDepStatements.push(result.getPurgeVariableDepStatement());
393    }
394  }
395}
396
397function addIntoNewMembers(
398  newMembers: ts.ClassElement[],
399  parentComponentName: ts.Identifier,
400  updateParamsStatements: ts.Statement[],
401  purgeVariableDepStatements: ts.Statement[],
402  rerenderStatements: ts.Statement[],
403  stateVarsStatements: ts.Statement[]
404): void {
405  if (partialUpdateConfig.partialUpdateMode) {
406    newMembers.unshift(
407      addInitialParamsFunc(updateParamsStatements, parentComponentName),
408      addUpdateStateVarsFunc(stateVarsStatements, parentComponentName),
409      addPurgeVariableDepFunc(purgeVariableDepStatements)
410    );
411    newMembers.push(addRerenderFunc(rerenderStatements));
412  } else {
413    newMembers.unshift(addUpdateParamsFunc(updateParamsStatements, parentComponentName));
414  }
415}
416
417function addPropertyMember(item: ts.ClassElement, newMembers: ts.ClassElement[],
418  program: ts.Program, parentComponentName: string, log: LogInfo[]): void {
419  const propertyItem: ts.PropertyDeclaration = item as ts.PropertyDeclaration;
420  let decoratorName: string;
421  let updatePropertyItem: ts.PropertyDeclaration;
422  const type: ts.TypeNode = propertyItem.type;
423  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(propertyItem);
424  if (!decorators || decorators.length === 0) {
425    updatePropertyItem = createPropertyDeclaration(propertyItem, type, true);
426    newMembers.push(updatePropertyItem);
427  } else {
428    for (let i = 0; i < decorators.length; i++) {
429      let newType: ts.TypeNode;
430      decoratorName = decorators[i].getText().replace(/\(.*\)$/, '').trim();
431      let isLocalStorage: boolean = false;
432      if (!partialUpdateConfig.partialUpdateMode) {
433        newType = createTypeReference(decoratorName, type, log, program);
434      } else {
435        newType = createTypeReferencePU(decoratorName, type, log, program);
436      }
437      if (
438        decoratorName === COMPONENT_LOCAL_STORAGE_LINK_DECORATOR ||
439        decoratorName === COMPONENT_LOCAL_STORAGE_PROP_DECORATOR
440      ) {
441        isLocalStorage = true;
442      }
443      const newUpdatePropertyItem = createPropertyDeclaration(
444        propertyItem, newType, false, isLocalStorage, parentComponentName);
445      if (!updatePropertyItem) {
446        updatePropertyItem = newUpdatePropertyItem;
447      } else if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName) &&
448        decoratorName !== COMPONENT_WATCH_DECORATOR) {
449        updatePropertyItem = newUpdatePropertyItem;
450      }
451    }
452    if (updatePropertyItem) {
453      newMembers.push(updatePropertyItem);
454    }
455  }
456}
457
458function createPropertyDeclaration(propertyItem: ts.PropertyDeclaration, newType: ts.TypeNode | undefined,
459  normalVar: boolean, isLocalStorage: boolean = false, parentComponentName: string = null): ts.PropertyDeclaration {
460  if (typeof newType === undefined) {
461    return undefined;
462  }
463  let prefix: string = '';
464  if (!normalVar) {
465    prefix = '__';
466  }
467  const privateM: ts.ModifierToken<ts.SyntaxKind.PrivateKeyword> =
468    ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword);
469  const modifiers: readonly ts.Modifier[] =
470    ts.canHaveModifiers(propertyItem) ? ts.getModifiers(propertyItem) : undefined;
471  return ts.factory.updatePropertyDeclaration(propertyItem,
472    ts.concatenateDecoratorsAndModifiers(undefined, modifiers || [privateM]), prefix + propertyItem.name.getText(),
473    propertyItem.questionToken, newType, isLocalStorage ?
474      createLocalStroageCallExpression(propertyItem, propertyItem.name.getText(),
475        parentComponentName) : undefined);
476}
477
478function createLocalStroageCallExpression(node: ts.PropertyDeclaration, name: string,
479  parentComponentName: string): ts.CallExpression {
480  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
481  if (isSingleKey(node)) {
482    const localStorageLink: Set<string> = localStorageLinkCollection.get(parentComponentName).get(name);
483    const localStorageProp: Set<string> = localStoragePropCollection.get(parentComponentName).get(name);
484    let localFuncName: string;
485    const index: number = findDecoratorIndex(decorators,
486      [COMPONENT_LOCAL_STORAGE_LINK_DECORATOR, COMPONENT_LOCAL_STORAGE_PROP_DECORATOR]);
487    const localValue: ts.Expression[] = [
488      decorators[index].expression.arguments[0],
489      node.initializer ? node.initializer : ts.factory.createNumericLiteral(COMPONENT_CONSTRUCTOR_UNDEFINED),
490      ts.factory.createThis(),
491      ts.factory.createStringLiteral(name || COMPONENT_CONSTRUCTOR_UNDEFINED)
492    ];
493    if (!partialUpdateConfig.partialUpdateMode) {
494      localFuncName = localStorageLink && !localStorageProp ? COMPONENT_SET_AND_LINK :
495        COMPONENT_SET_AND_PROP;
496    } else {
497      localFuncName = localStorageLink && !localStorageProp ? CREATE_LOCAL_STORAGE_LINK :
498        CREATE_LOCAL_STORAGE_PROP;
499      localValue.splice(-2, 1);
500    }
501    return ts.factory.createCallExpression(
502      ts.factory.createPropertyAccessExpression(
503        !partialUpdateConfig.partialUpdateMode ?
504          ts.factory.createPropertyAccessExpression(
505            ts.factory.createThis(),
506            ts.factory.createIdentifier(`${COMPONENT_CONSTRUCTOR_LOCALSTORAGE}_`)
507          ) : ts.factory.createThis(),
508        ts.factory.createIdentifier(localFuncName)
509      ),
510      [node.type],
511      localValue
512    );
513  }
514}
515
516function processComponentMethod(node: ts.MethodDeclaration, parentComponentName: ts.Identifier,
517  context: ts.TransformationContext, log: LogInfo[], buildCount: BuildCount): ts.MethodDeclaration {
518  let updateItem: ts.MethodDeclaration = node;
519  const name: string = node.name.getText();
520  const customBuilder: ts.Decorator[] = [];
521  if (builderParamObjectCollection.get(componentCollection.currentClassName)) {
522    storedFileInfo.builderLikeCollection =
523      new Set([...builderParamObjectCollection.get(componentCollection.currentClassName), ...CUSTOM_BUILDER_METHOD]);
524  } else {
525    storedFileInfo.builderLikeCollection = CUSTOM_BUILDER_METHOD;
526  }
527  if (name === COMPONENT_BUILD_FUNCTION) {
528    storedFileInfo.processBuilder = false;
529    storedFileInfo.processGlobalBuilder = false;
530    buildCount.count = buildCount.count + 1;
531    if (node.parameters.length) {
532      log.push({
533        type: LogType.ERROR,
534        message: `The 'build' method can not have arguments.`,
535        pos: node.getStart()
536      });
537    }
538    const buildNode: ts.MethodDeclaration = processComponentBuild(node, log);
539    updateItem = processBuildMember(buildNode, context, log);
540  } else if (node.body && ts.isBlock(node.body)) {
541    if (name === COMPONENT_TRANSITION_FUNCTION) {
542      updateItem = ts.factory.updateMethodDeclaration(node, ts.getModifiers(node),
543        node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters,
544        node.type, processComponentBlock(node.body, false, log, true));
545    } else if (hasDecorator(node, COMPONENT_BUILDER_DECORATOR, customBuilder)) {
546      storedFileInfo.processBuilder = true;
547      storedFileInfo.processGlobalBuilder = false;
548      CUSTOM_BUILDER_METHOD.add(name);
549      INNER_CUSTOM_BUILDER_METHOD.add(name);
550      builderTypeParameter.params = getPossibleBuilderTypeParameter(node.parameters);
551      const parameters: ts.NodeArray<ts.ParameterDeclaration> = ts.factory.createNodeArray(Array.from(node.parameters));
552      parameters.push(createParentParameter());
553      if (projectConfig.optLazyForEach) {
554        parameters.push(initializeMYIDS());
555      }
556      const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
557      const builderNode: ts.MethodDeclaration = ts.factory.updateMethodDeclaration(node,
558        ts.concatenateDecoratorsAndModifiers(customBuilder, modifiers), node.asteriskToken, node.name, node.questionToken, node.typeParameters,
559        parameters, node.type, processComponentBlock(node.body, false, log, false, true));
560      builderTypeParameter.params = [];
561      updateItem = processBuildMember(builderNode, context, log, true);
562      storedFileInfo.processBuilder = false;
563    } else if (hasDecorator(node, COMPONENT_STYLES_DECORATOR)) {
564      if (node.parameters && node.parameters.length === 0) {
565        if (ts.isBlock(node.body) && node.body.statements && node.body.statements.length) {
566          INNER_STYLE_FUNCTION.set(name, node.body);
567          STYLES_ATTRIBUTE.add(name);
568          BUILDIN_STYLE_NAMES.add(name);
569          decoratorParamSet.add(STYLES);
570        }
571      } else {
572        log.push({
573          type: LogType.ERROR,
574          message: `@Styles can't have parameters.`,
575          pos: node.getStart()
576        });
577      }
578      return;
579    }
580  }
581  return updateItem;
582}
583
584export function createParentParameter(): ts.ParameterDeclaration {
585  return ts.factory.createParameterDeclaration(undefined, undefined,
586    ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT), undefined, undefined,
587    ts.factory.createIdentifier(NULL));
588}
589
590export function processBuildMember(node: ts.MethodDeclaration | ts.FunctionDeclaration, context: ts.TransformationContext,
591  log: LogInfo[], isBuilder = false): ts.MethodDeclaration | ts.FunctionDeclaration {
592  return ts.visitNode(node, visitBuild);
593  function visitBuild(node: ts.Node): ts.Node {
594    if (isGeometryView(node)) {
595      node = processGeometryView(node as ts.ExpressionStatement, log);
596    }
597    if (isProperty(node)) {
598      node = createReference(node as ts.PropertyAssignment, log, isBuilder);
599    }
600    if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) &&
601      stateObjectCollection.has(checkStateName(node)) && node.parent && ts.isCallExpression(node.parent) &&
602      ts.isPropertyAccessExpression(node.parent.expression) && node !== node.parent.expression &&
603      node.parent.expression.name.escapedText.toString() !== FOREACH_GET_RAW_OBJECT) {
604      return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
605        ts.factory.createIdentifier(FOREACH_OBSERVED_OBJECT),
606        ts.factory.createIdentifier(FOREACH_GET_RAW_OBJECT)), undefined, [node]);
607    }
608    return ts.visitEachChild(node, visitBuild, context);
609  }
610  function checkStateName(node: ts.PropertyAccessExpression): string {
611    if (node.expression && !node.expression.expression && node.name && ts.isIdentifier(node.name)) {
612      return node.name.escapedText.toString();
613    }
614    return null;
615  }
616}
617
618function isGeometryView(node: ts.Node): boolean {
619  if (ts.isExpressionStatement(node) && ts.isCallExpression(node.expression)) {
620    const call: ts.CallExpression = node.expression;
621    const exp: ts.Expression = call.expression;
622    const args: ts.NodeArray<ts.Expression> = call.arguments;
623    if (ts.isPropertyAccessExpression(exp) && ts.isIdentifier(exp.expression) &&
624      exp.expression.escapedText.toString() === GEOMETRY_VIEW && ts.isIdentifier(exp.name) &&
625      exp.name.escapedText.toString() === COMPONENT_CREATE_FUNCTION && args && args.length === 1 &&
626      (ts.isArrowFunction(args[0]) || ts.isFunctionExpression(args[0]))) {
627      return true;
628    }
629  }
630  return false;
631}
632
633function processGeometryView(node: ts.ExpressionStatement,
634  log: LogInfo[]): ts.ExpressionStatement {
635  const exp: ts.CallExpression = node.expression as ts.CallExpression;
636  const arg: ts.ArrowFunction | ts.FunctionExpression =
637    exp.arguments[0] as ts.ArrowFunction | ts.FunctionExpression;
638  return ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression(exp,
639    exp.expression, undefined, [ts.factory.createArrowFunction(undefined, undefined, arg.parameters,
640      undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
641      getGeometryReaderFunctionBlock(arg, log))]));
642}
643
644function getGeometryReaderFunctionBlock(node: ts.ArrowFunction | ts.FunctionExpression,
645  log: LogInfo[]): ts.Block {
646  let blockNode: ts.Block;
647  if (ts.isBlock(node.body)) {
648    blockNode = node.body;
649  } else if (ts.isArrowFunction(node) && ts.isCallExpression(node.body)) {
650    blockNode = ts.factory.createBlock([ts.factory.createExpressionStatement(node.body)]);
651  }
652  return processComponentBlock(blockNode, false, log);
653}
654
655function updateHeritageClauses(node: ts.StructDeclaration, log: LogInfo[])
656  : ts.NodeArray<ts.HeritageClause> {
657  if (node.heritageClauses && !checkHeritageClauses(node)) {
658    log.push({
659      type: LogType.ERROR,
660      message: 'The struct component is not allowed to extends other class or implements other interface.',
661      pos: node.heritageClauses.pos
662    });
663  }
664  const result: ts.HeritageClause[] = [];
665  const heritageClause: ts.HeritageClause = createHeritageClause();
666  result.push(heritageClause);
667  return ts.factory.createNodeArray(result);
668}
669
670function checkHeritageClauses(node: ts.StructDeclaration): boolean {
671  if (node.heritageClauses.length === 1 && node.heritageClauses[0].types &&
672    node.heritageClauses[0].types.length === 1) {
673    const expressionNode: ts.ExpressionWithTypeArguments = node.heritageClauses[0].types[0];
674    if (expressionNode.expression && ts.isIdentifier(expressionNode.expression) &&
675      expressionNode.expression.escapedText.toString() === CUSTOM_COMPONENT) {
676      return true;
677    }
678  }
679  return false;
680}
681
682export function isProperty(node: ts.Node): Boolean {
683  if (judgmentParentType(node)) {
684    if (node.parent.parent.expression && ts.isIdentifier(node.parent.parent.expression) &&
685      !BUILDIN_STYLE_NAMES.has(node.parent.parent.expression.escapedText.toString()) &&
686      componentCollection.customComponents.has(
687        node.parent.parent.expression.escapedText.toString())) {
688      return true;
689    } else if (ts.isPropertyAccessExpression(node.parent.parent.expression) &&
690      ts.isIdentifier(node.parent.parent.expression.expression) &&
691      componentCollection.customComponents.has(
692        node.parent.parent.expression.name.escapedText.toString())) {
693      return true;
694    }
695  }
696  return false;
697}
698
699function judgmentParentType(node: ts.Node): boolean {
700  return ts.isPropertyAssignment(node) && node.name && ts.isIdentifier(node.name) &&
701    node.parent && ts.isObjectLiteralExpression(node.parent) && node.parent.parent &&
702    (ts.isCallExpression(node.parent.parent) || ts.isEtsComponentExpression(node.parent.parent));
703}
704
705export function createReference(node: ts.PropertyAssignment, log: LogInfo[], isBuilder = false,
706  isParamsLambda: boolean = false, isRecycleComponent: boolean = false): ts.PropertyAssignment {
707  const linkParentComponent: string[] = getParentNode(node, linkCollection).slice(1);
708  const propertyName: ts.Identifier = node.name as ts.Identifier;
709  let initText: string;
710  const LINK_REG: RegExp = /^\$/g;
711  if (isRecycleComponent && ts.isShorthandPropertyAssignment(node)) {
712    return node;
713  }
714  const initExpression: ts.Expression = node.initializer;
715  let is$$: boolean = false;
716  if (ts.isIdentifier(initExpression) &&
717    initExpression.escapedText.toString().match(LINK_REG)) {
718    initText = initExpression.escapedText.toString().replace(LINK_REG, '');
719  } else if (ts.isPropertyAccessExpression(initExpression) && initExpression.expression &&
720    initExpression.expression.kind === ts.SyntaxKind.ThisKeyword &&
721    ts.isIdentifier(initExpression.name) && initExpression.name.escapedText.toString().match(LINK_REG)) {
722    initText = initExpression.name.escapedText.toString().replace(LINK_REG, '');
723  } else if (isBuilder && ts.isPropertyAccessExpression(initExpression) && initExpression.expression &&
724    ts.isIdentifier(initExpression.expression) && initExpression.expression.escapedText.toString() === $$ &&
725    ts.isIdentifier(initExpression.name) && linkParentComponent.includes(propertyName.escapedText.toString())) {
726    is$$ = true;
727    initText = initExpression.name.escapedText.toString();
728  } else if (isMatchInitExpression(initExpression) &&
729    linkParentComponent.includes(propertyName.escapedText.toString())) {
730    initText = initExpression.name.escapedText.toString().replace(LINK_REG, '');
731  }
732  if (initText) {
733    node = addDoubleUnderline(node, propertyName, initText, is$$, isParamsLambda, isRecycleComponent);
734  }
735  return node;
736}
737
738function isMatchInitExpression(initExpression: ts.Expression): boolean {
739  return ts.isPropertyAccessExpression(initExpression) &&
740    initExpression.expression &&
741    initExpression.expression.kind === ts.SyntaxKind.ThisKeyword &&
742    ts.isIdentifier(initExpression.name);
743}
744
745function addDoubleUnderline(node: ts.PropertyAssignment, propertyName: ts.Identifier,
746  initText: string, is$$ = false, isParamsLambda: boolean, isRecycleComponent: boolean): ts.PropertyAssignment {
747  return ts.factory.updatePropertyAssignment(node, propertyName,
748    ts.factory.createPropertyAccessExpression(
749      is$$ && partialUpdateConfig.partialUpdateMode ? ts.factory.createIdentifier($$) : ts.factory.createThis(),
750      isParamsLambda || isRecycleComponent ? ts.factory.createIdentifier(initText) : ts.factory.createIdentifier(`__${initText}`)));
751}
752
753function getParentNode(node: ts.PropertyAssignment, collection: Map<string, Set<string>>): string[] {
754  const grandparentNode: ts.NewExpression = node.parent.parent as ts.NewExpression;
755  const grandparentExpression: ts.Identifier | ts.PropertyAccessExpression =
756    grandparentNode.expression as ts.Identifier | ts.PropertyAccessExpression;
757  let parentComponent: Set<string> = new Set();
758  let grandparentName: string;
759  if (ts.isIdentifier(grandparentExpression)) {
760    grandparentName = grandparentExpression.escapedText.toString();
761    parentComponent = collection.get(grandparentName);
762  } else if (ts.isPropertyAccessExpression(grandparentExpression)) {
763    grandparentName = grandparentExpression.name.escapedText.toString();
764    parentComponent = collection.get(grandparentName);
765  } else {
766    // ignore
767  }
768  if (!parentComponent) {
769    parentComponent = new Set();
770  }
771  return [grandparentName, ...parentComponent];
772}
773
774function addUpdateParamsFunc(statements: ts.Statement[], parentComponentName: ts.Identifier):
775  ts.MethodDeclaration {
776  return createParamsInitBlock(COMPONENT_CONSTRUCTOR_UPDATE_PARAMS, statements, parentComponentName);
777}
778
779function addInitialParamsFunc(statements: ts.Statement[], parentComponentName: ts.Identifier): ts.MethodDeclaration {
780  return createParamsInitBlock(COMPONENT_CONSTRUCTOR_INITIAL_PARAMS, statements, parentComponentName);
781}
782
783function addUpdateStateVarsFunc(statements: ts.Statement[], parentComponentName: ts.Identifier): ts.MethodDeclaration {
784  return createParamsInitBlock(COMPONENT_UPDATE_STATE_VARS, statements, parentComponentName);
785}
786
787function addPurgeVariableDepFunc(statements: ts.Statement[]): ts.MethodDeclaration {
788  return ts.factory.createMethodDeclaration(
789    undefined, undefined,
790    ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PURGE_VARIABLE_DEP),
791    undefined, undefined, [ts.factory.createParameterDeclaration(undefined, undefined,
792      ts.factory.createIdentifier(RMELMTID), undefined, undefined, undefined)], undefined,
793    ts.factory.createBlock(statements, true));
794}
795
796function addDeleteParamsFunc(statements: ts.PropertyDeclaration[],
797  updateRecyle: boolean = false): ts.MethodDeclaration {
798  const deleteStatements: ts.ExpressionStatement[] = [];
799  const updateStatements: ts.ExpressionStatement[] = [];
800  statements.forEach((statement: ts.PropertyDeclaration) => {
801    const name: ts.Identifier = statement.name as ts.Identifier;
802    let paramsStatement: ts.ExpressionStatement;
803    const decorators: readonly ts.Decorator[] = ts.getAllDecorators(statement);
804    if (!partialUpdateConfig.partialUpdateMode || decorators && decorators.length !== 0) {
805      paramsStatement = createParamsWithUnderlineStatement(name);
806    }
807    if (partialUpdateConfig.partialUpdateMode && decorators && decorators.length !== 0) {
808      updateStatements.push(createElmtIdWithUnderlineStatement(name));
809    }
810    deleteStatements.push(paramsStatement);
811  });
812  if (partialUpdateConfig.partialUpdateMode && updateRecyle) {
813    return createRecycleElmt(updateStatements);
814  }
815  const defaultStatement: ts.ExpressionStatement =
816    ts.factory.createExpressionStatement(ts.factory.createCallExpression(
817      ts.factory.createPropertyAccessExpression(
818        ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
819          ts.factory.createIdentifier(CREATE_CONSTRUCTOR_SUBSCRIBER_MANAGER),
820          ts.factory.createIdentifier(CREATE_CONSTRUCTOR_GET_FUNCTION)), undefined, []),
821        ts.factory.createIdentifier(CREATE_CONSTRUCTOR_DELETE_FUNCTION)),
822      undefined, [ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
823        ts.factory.createThis(), ts.factory.createIdentifier(
824          !partialUpdateConfig.partialUpdateMode ?
825            ABOUT_TO_BE_DELETE_FUNCTION_ID : ABOUT_TO_BE_DELETE_FUNCTION_ID__)),
826      undefined, [])]));
827  deleteStatements.push(defaultStatement);
828  if (partialUpdateConfig.partialUpdateMode) {
829    const aboutToBeDeletedInternalStatement: ts.ExpressionStatement = createDeletedInternalStatement();
830    deleteStatements.push(aboutToBeDeletedInternalStatement);
831  }
832  const deleteParamsMethod: ts.MethodDeclaration =
833    createParamsInitBlock(COMPONENT_CONSTRUCTOR_DELETE_PARAMS, deleteStatements);
834  return deleteParamsMethod;
835}
836
837function createRecycleElmt(statements: ts.Statement[]): ts.MethodDeclaration {
838  return ts.factory.createMethodDeclaration(undefined, undefined,
839    ts.factory.createIdentifier(UPDATE_RECYCLE_ELMT_ID), undefined, undefined, [
840      ts.factory.createParameterDeclaration(undefined, undefined,
841        ts.factory.createIdentifier(OLD_ELMT_ID)),
842      ts.factory.createParameterDeclaration(undefined, undefined,
843        ts.factory.createIdentifier(NEW_ELMT_ID))
844    ], undefined, ts.factory.createBlock(statements, true));
845}
846
847function createParamsWithUnderlineStatement(name: ts.Identifier): ts.ExpressionStatement {
848  return ts.factory.createExpressionStatement(
849    ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
850      ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
851        ts.factory.createIdentifier(`__${name.escapedText.toString()}`)),
852      ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_DELETE_PARAMS)), undefined, []));
853}
854
855function createElmtIdWithUnderlineStatement(name: ts.Identifier): ts.ExpressionStatement {
856  return ts.factory.createExpressionStatement(
857    ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
858      ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
859        ts.factory.createIdentifier(`__${name.escapedText.toString()}`)),
860      ts.factory.createIdentifier(COMPONENT_UPDATE_ELMT_ID)), undefined, [
861      ts.factory.createIdentifier(OLD_ELMT_ID), ts.factory.createIdentifier(NEW_ELMT_ID)
862    ]));
863}
864
865function createDeletedInternalStatement(): ts.ExpressionStatement {
866  return ts.factory.createExpressionStatement(ts.factory.createCallExpression(
867    ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
868      ts.factory.createIdentifier(ABOUTTOBEDELETEDINTERNAL)), undefined, []));
869}
870
871function addRerenderFunc(statements: ts.Statement[]): ts.MethodDeclaration {
872  const updateDirtyElementStatement: ts.Statement = ts.factory.createExpressionStatement(
873    ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(
874      ts.factory.createThis(), ts.factory.createIdentifier(UPDATEDIRTYELEMENTS)), undefined, []));
875  statements.push(updateDirtyElementStatement);
876  return ts.factory.createMethodDeclaration(undefined, undefined,
877    ts.factory.createIdentifier(COMPONENT_RERENDER_FUNCTION), undefined, undefined, [], undefined,
878    ts.factory.createBlock(statements, true));
879}
880
881function createParamsInitBlock(express: string, statements: ts.Statement[],
882  parentComponentName?: ts.Identifier): ts.MethodDeclaration {
883  const methodDeclaration: ts.MethodDeclaration = ts.factory.createMethodDeclaration(
884    undefined, undefined, ts.factory.createIdentifier(express), undefined, undefined,
885    [ts.factory.createParameterDeclaration(undefined, undefined,
886      express === COMPONENT_CONSTRUCTOR_DELETE_PARAMS ? undefined :
887        ts.factory.createIdentifier(CREATE_CONSTRUCTOR_PARAMS), undefined,
888      express === COMPONENT_CONSTRUCTOR_DELETE_PARAMS ? undefined :
889        ts.factory.createTypeReferenceNode(
890          ts.factory.createIdentifier(parentComponentName.getText() + INTERFACE_NAME_SUFFIX), undefined),
891      undefined)], undefined, ts.factory.createBlock(statements, true));
892  return methodDeclaration;
893}
894
895function validateBuildMethodCount(buildCount: BuildCount, parentComponentName: ts.Identifier,
896  log: LogInfo[]): void {
897  if (buildCount.count !== 1) {
898    log.push({
899      type: LogType.ERROR,
900      message: `struct '${parentComponentName.getText()}' must be at least or at most one 'build' method.`,
901      pos: parentComponentName.getStart()
902    });
903  }
904}
905
906function validateHasController(componentName: ts.Identifier, checkController: ControllerType,
907  log: LogInfo[]): void {
908  if (!checkController.hasController) {
909    log.push({
910      type: LogType.ERROR,
911      message: '@CustomDialog component should have a property of the CustomDialogController type.',
912      pos: componentName.pos
913    });
914  }
915}
916
917function createHeritageClause(): ts.HeritageClause {
918  if (partialUpdateConfig.partialUpdateMode) {
919    return ts.factory.createHeritageClause(
920      ts.SyntaxKind.ExtendsKeyword,
921      [ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(BASE_COMPONENT_NAME_PU), [])]
922    );
923  }
924  return ts.factory.createHeritageClause(
925    ts.SyntaxKind.ExtendsKeyword,
926    [ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(BASE_COMPONENT_NAME), [])]
927  );
928}
929
930function createTypeReference(decoratorName: string, type: ts.TypeNode, log: LogInfo[],
931  program: ts.Program): ts.TypeNode {
932  let newType: ts.TypeNode;
933  switch (decoratorName) {
934    case COMPONENT_STATE_DECORATOR:
935    case COMPONENT_PROVIDE_DECORATOR:
936      newType = ts.factory.createTypeReferenceNode(
937        isSimpleType(type, program, log) ?
938          OBSERVED_PROPERTY_SIMPLE :
939          OBSERVED_PROPERTY_OBJECT,
940        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
941      );
942      break;
943    case COMPONENT_LINK_DECORATOR:
944    case COMPONENT_CONSUME_DECORATOR:
945      newType = ts.factory.createTypeReferenceNode(
946        isSimpleType(type, program, log) ?
947          SYNCHED_PROPERTY_SIMPLE_TWO_WAY :
948          SYNCHED_PROPERTY_SIMPLE_ONE_WAY,
949        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
950      );
951      break;
952    case COMPONENT_PROP_DECORATOR:
953      newType = ts.factory.createTypeReferenceNode(
954        SYNCHED_PROPERTY_SIMPLE_ONE_WAY,
955        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
956      );
957      break;
958    case COMPONENT_OBJECT_LINK_DECORATOR:
959      newType = ts.factory.createTypeReferenceNode(
960        SYNCHED_PROPERTY_NESED_OBJECT,
961        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
962      );
963      break;
964    case COMPONENT_STORAGE_PROP_DECORATOR:
965    case COMPONENT_STORAGE_LINK_DECORATOR:
966      newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [
967        type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
968      ]);
969      break;
970    case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR:
971    case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR:
972      newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT, [
973        type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
974      ]);
975      break;
976  }
977  return newType;
978}
979
980function createTypeReferencePU(decoratorName: string, type: ts.TypeNode, log: LogInfo[],
981  program: ts.Program): ts.TypeNode {
982  let newType: ts.TypeNode;
983  switch (decoratorName) {
984    case COMPONENT_STATE_DECORATOR:
985    case COMPONENT_PROVIDE_DECORATOR:
986      newType = ts.factory.createTypeReferenceNode(
987        isSimpleType(type, program, log) ?
988          OBSERVED_PROPERTY_SIMPLE_PU :
989          OBSERVED_PROPERTY_OBJECT_PU,
990        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
991      );
992      break;
993    case COMPONENT_LINK_DECORATOR:
994      newType = ts.factory.createTypeReferenceNode(
995        isSimpleType(type, program, log) ?
996          SYNCHED_PROPERTY_SIMPLE_TWO_WAY_PU :
997          SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
998        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
999      );
1000      break;
1001    case COMPONENT_PROP_DECORATOR:
1002      newType = ts.factory.createTypeReferenceNode(
1003        SYNCHED_PROPERTY_SIMPLE_ONE_WAY_PU,
1004        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
1005      );
1006      break;
1007    case COMPONENT_OBJECT_LINK_DECORATOR:
1008      newType = ts.factory.createTypeReferenceNode(
1009        SYNCHED_PROPERTY_NESED_OBJECT_PU,
1010        [type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)]
1011      );
1012      break;
1013    case COMPONENT_CONSUME_DECORATOR:
1014    case COMPONENT_STORAGE_PROP_DECORATOR:
1015    case COMPONENT_STORAGE_LINK_DECORATOR:
1016      newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT_PU, [
1017        type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
1018      ]);
1019      break;
1020    case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR:
1021    case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR:
1022      newType = ts.factory.createTypeReferenceNode(OBSERVED_PROPERTY_ABSTRACT_PU, [
1023        type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
1024      ]);
1025      break;
1026  }
1027  return newType;
1028}
1029