107ac75b1Sopenharmony_ci/*
207ac75b1Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
307ac75b1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
407ac75b1Sopenharmony_ci * you may not use this file except in compliance with the License.
507ac75b1Sopenharmony_ci * You may obtain a copy of the License at
607ac75b1Sopenharmony_ci *
707ac75b1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
807ac75b1Sopenharmony_ci *
907ac75b1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1007ac75b1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1107ac75b1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1207ac75b1Sopenharmony_ci * See the License for the specific language governing permissions and
1307ac75b1Sopenharmony_ci * limitations under the License.
1407ac75b1Sopenharmony_ci */
1507ac75b1Sopenharmony_ci
1607ac75b1Sopenharmony_ciimport ts from 'typescript';
1707ac75b1Sopenharmony_ci
1807ac75b1Sopenharmony_ciimport {
1907ac75b1Sopenharmony_ci  LogInfo,
2007ac75b1Sopenharmony_ci  LogType,
2107ac75b1Sopenharmony_ci  addLog,
2207ac75b1Sopenharmony_ci  removeDecorator
2307ac75b1Sopenharmony_ci} from './utils';
2407ac75b1Sopenharmony_ciimport {
2507ac75b1Sopenharmony_ci  COMPONENT_CONSTRUCTOR_PARENT,
2607ac75b1Sopenharmony_ci  COMPONENT_CONSTRUCTOR_PARAMS,
2707ac75b1Sopenharmony_ci  COMPONENT_CONSTRUCTOR_LOCALSTORAGE_PU,
2807ac75b1Sopenharmony_ci  ELMTID,
2907ac75b1Sopenharmony_ci  COMPONENT_PARAMS_LAMBDA_FUNCTION,
3007ac75b1Sopenharmony_ci  CUSTOM_COMPONENT_EXTRAINFO,
3107ac75b1Sopenharmony_ci  COMPONENT_CONSTRUCTOR_UNDEFINED
3207ac75b1Sopenharmony_ci} from './pre_define';
3307ac75b1Sopenharmony_ciimport constantDefine from './constant_define';
3407ac75b1Sopenharmony_ciimport createAstNodeUtils from './create_ast_node_utils';
3507ac75b1Sopenharmony_ciimport {
3607ac75b1Sopenharmony_ci  updateHeritageClauses,
3707ac75b1Sopenharmony_ci  processComponentMethod,
3807ac75b1Sopenharmony_ci  BuildCount,
3907ac75b1Sopenharmony_ci  addRerenderFunc,
4007ac75b1Sopenharmony_ci  validateBuildMethodCount,
4107ac75b1Sopenharmony_ci  getEntryNameFunction,
4207ac75b1Sopenharmony_ci  FreezeParamType,
4307ac75b1Sopenharmony_ci  decoratorAssignParams
4407ac75b1Sopenharmony_ci} from './process_component_class';
4507ac75b1Sopenharmony_ciimport { judgeBuilderParamAssignedByBuilder } from './process_component_member';
4607ac75b1Sopenharmony_ciimport {
4707ac75b1Sopenharmony_ci  componentCollection,
4807ac75b1Sopenharmony_ci  builderParamObjectCollection
4907ac75b1Sopenharmony_ci} from './validate_ui_syntax';
5007ac75b1Sopenharmony_ci
5107ac75b1Sopenharmony_ciexport class ParamDecoratorInfo {
5207ac75b1Sopenharmony_ci  initializer: ts.Expression;
5307ac75b1Sopenharmony_ci  hasRequire: boolean = false;
5407ac75b1Sopenharmony_ci}
5507ac75b1Sopenharmony_ci
5607ac75b1Sopenharmony_ciexport class StructInfo {
5707ac75b1Sopenharmony_ci  isComponentV1: boolean = false;
5807ac75b1Sopenharmony_ci  isComponentV2: boolean = false;
5907ac75b1Sopenharmony_ci  isCustomDialog: boolean = false;
6007ac75b1Sopenharmony_ci  isReusable: boolean = false;
6107ac75b1Sopenharmony_ci  structName: string = '';
6207ac75b1Sopenharmony_ci  updatePropsDecoratorsV1: string[] = [];
6307ac75b1Sopenharmony_ci  linkDecoratorsV1: string[] = [];
6407ac75b1Sopenharmony_ci  paramDecoratorMap: Map<string, ParamDecoratorInfo> = new Map();
6507ac75b1Sopenharmony_ci  eventDecoratorSet: Set<string> = new Set();
6607ac75b1Sopenharmony_ci  localDecoratorSet: Set<string> = new Set();
6707ac75b1Sopenharmony_ci  providerDecoratorSet: Set<string> = new Set();
6807ac75b1Sopenharmony_ci  consumerDecoratorSet: Set<string> = new Set();
6907ac75b1Sopenharmony_ci  builderParamDecoratorSet: Set<string> = new Set();
7007ac75b1Sopenharmony_ci  regularSet: Set<string> = new Set();
7107ac75b1Sopenharmony_ci  propertiesMap: Map<string, ts.Expression> = new Map();
7207ac75b1Sopenharmony_ci  staticPropertySet: Set<string> = new Set();
7307ac75b1Sopenharmony_ci}
7407ac75b1Sopenharmony_ci
7507ac75b1Sopenharmony_ciconst structMapInEts: Map<string, StructInfo> = new Map();
7607ac75b1Sopenharmony_ci
7707ac75b1Sopenharmony_cifunction getOrCreateStructInfo(key: string): StructInfo {
7807ac75b1Sopenharmony_ci  let structInfo: StructInfo = structMapInEts.get(key);
7907ac75b1Sopenharmony_ci  if (!structInfo) {
8007ac75b1Sopenharmony_ci    structInfo = new StructInfo();
8107ac75b1Sopenharmony_ci    structInfo.structName = key;
8207ac75b1Sopenharmony_ci    structMapInEts.set(key, structInfo);
8307ac75b1Sopenharmony_ci  }
8407ac75b1Sopenharmony_ci  return structInfo;
8507ac75b1Sopenharmony_ci}
8607ac75b1Sopenharmony_ci
8707ac75b1Sopenharmony_ci/**
8807ac75b1Sopenharmony_ci * import * as a from './common'
8907ac75b1Sopenharmony_ci * a.struct()
9007ac75b1Sopenharmony_ci */
9107ac75b1Sopenharmony_cifunction getAliasStructInfo(node: ts.CallExpression): StructInfo {
9207ac75b1Sopenharmony_ci  let aliasStructInfo: StructInfo;
9307ac75b1Sopenharmony_ci  if (node.expression && structMapInEts.has(node.expression.getText())) {
9407ac75b1Sopenharmony_ci    aliasStructInfo = structMapInEts.get(node.expression.getText());
9507ac75b1Sopenharmony_ci  }
9607ac75b1Sopenharmony_ci  return aliasStructInfo;
9707ac75b1Sopenharmony_ci}
9807ac75b1Sopenharmony_ci
9907ac75b1Sopenharmony_cifunction processStructComponentV2(node: ts.StructDeclaration, log: LogInfo[],
10007ac75b1Sopenharmony_ci  context: ts.TransformationContext): ts.ClassDeclaration {
10107ac75b1Sopenharmony_ci  return ts.factory.createClassDeclaration(ts.getModifiers(node), node.name,
10207ac75b1Sopenharmony_ci    node.typeParameters, updateHeritageClauses(node, log, true),
10307ac75b1Sopenharmony_ci    processStructMembersV2(node, context, log));
10407ac75b1Sopenharmony_ci}
10507ac75b1Sopenharmony_ci
10607ac75b1Sopenharmony_cifunction processStructMembersV2(node: ts.StructDeclaration, context: ts.TransformationContext,
10707ac75b1Sopenharmony_ci  log: LogInfo[]): ts.ClassElement[] {
10807ac75b1Sopenharmony_ci  const structName: string = node.name.getText();
10907ac75b1Sopenharmony_ci  const newMembers: ts.ClassElement[] = [];
11007ac75b1Sopenharmony_ci  const buildCount: BuildCount = { count: 0 };
11107ac75b1Sopenharmony_ci  const structInfo: StructInfo = getOrCreateStructInfo(structName);
11207ac75b1Sopenharmony_ci  const addStatementsInConstructor: ts.Statement[] = [];
11307ac75b1Sopenharmony_ci  const paramStatementsInStateVarsMethod: ts.Statement[] = [];
11407ac75b1Sopenharmony_ci  const structDecorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
11507ac75b1Sopenharmony_ci  const freezeParam: FreezeParamType = { componentFreezeParam: undefined };
11607ac75b1Sopenharmony_ci  decoratorAssignParams(structDecorators, context, freezeParam);
11707ac75b1Sopenharmony_ci  traverseStructInfo(structInfo, addStatementsInConstructor, paramStatementsInStateVarsMethod);
11807ac75b1Sopenharmony_ci  node.members.forEach((member: ts.ClassElement) => {
11907ac75b1Sopenharmony_ci    if (ts.isConstructorDeclaration(member)) {
12007ac75b1Sopenharmony_ci      processStructConstructorV2(node.members, newMembers, addStatementsInConstructor, freezeParam);
12107ac75b1Sopenharmony_ci      return;
12207ac75b1Sopenharmony_ci    } else if (ts.isPropertyDeclaration(member)) {
12307ac75b1Sopenharmony_ci      newMembers.push(processComponentProperty(member, structInfo, log));
12407ac75b1Sopenharmony_ci      return;
12507ac75b1Sopenharmony_ci    } else if (ts.isMethodDeclaration(member) && member.name) {
12607ac75b1Sopenharmony_ci      const newMethodNode: ts.MethodDeclaration = processComponentMethod(member, context, log, buildCount);
12707ac75b1Sopenharmony_ci      if (newMethodNode) {
12807ac75b1Sopenharmony_ci        newMembers.push(newMethodNode);
12907ac75b1Sopenharmony_ci      }
13007ac75b1Sopenharmony_ci      return;
13107ac75b1Sopenharmony_ci    }
13207ac75b1Sopenharmony_ci    newMembers.push(member);
13307ac75b1Sopenharmony_ci  });
13407ac75b1Sopenharmony_ci  validateBuildMethodCount(buildCount, node.name, log);
13507ac75b1Sopenharmony_ci  updateStateVarsMethodNode(paramStatementsInStateVarsMethod, newMembers);
13607ac75b1Sopenharmony_ci  newMembers.push(addRerenderFunc([]));
13707ac75b1Sopenharmony_ci  if (componentCollection.entryComponent === structName) {
13807ac75b1Sopenharmony_ci    newMembers.push(getEntryNameFunction(componentCollection.entryComponent));
13907ac75b1Sopenharmony_ci  }
14007ac75b1Sopenharmony_ci  return newMembers;
14107ac75b1Sopenharmony_ci}
14207ac75b1Sopenharmony_ci
14307ac75b1Sopenharmony_cifunction traverseStructInfo(structInfo: StructInfo,
14407ac75b1Sopenharmony_ci  addStatementsInConstructor: ts.Statement[], paramStatementsInStateVarsMethod: ts.Statement[]): void {
14507ac75b1Sopenharmony_ci  const needInitFromParams: string[] = [...structInfo.builderParamDecoratorSet,
14607ac75b1Sopenharmony_ci    ...structInfo.eventDecoratorSet];
14707ac75b1Sopenharmony_ci  for (const property of structInfo.propertiesMap) {
14807ac75b1Sopenharmony_ci    if (!structInfo.staticPropertySet.has(property[0])) {
14907ac75b1Sopenharmony_ci      setPropertyStatement(structInfo, addStatementsInConstructor, property[0], property[1],
15007ac75b1Sopenharmony_ci        needInitFromParams);
15107ac75b1Sopenharmony_ci    }
15207ac75b1Sopenharmony_ci  }
15307ac75b1Sopenharmony_ci  for (const param of structInfo.paramDecoratorMap) {
15407ac75b1Sopenharmony_ci    if (!structInfo.staticPropertySet.has(param[0])) {
15507ac75b1Sopenharmony_ci      paramStatementsInStateVarsMethod.push(updateParamNode(param[0]));
15607ac75b1Sopenharmony_ci    }
15707ac75b1Sopenharmony_ci  }
15807ac75b1Sopenharmony_ci}
15907ac75b1Sopenharmony_ci
16007ac75b1Sopenharmony_cifunction setPropertyStatement(structInfo: StructInfo, addStatementsInConstructor: ts.Statement[],
16107ac75b1Sopenharmony_ci  propName: string, initializer: ts.Expression, needInitFromParams: string[]): void {
16207ac75b1Sopenharmony_ci  if (needInitFromParams.includes(propName)) {
16307ac75b1Sopenharmony_ci    if (structInfo.eventDecoratorSet.has(propName)) {
16407ac75b1Sopenharmony_ci      addStatementsInConstructor.push(
16507ac75b1Sopenharmony_ci        createPropertyAssignNode(propName, initializer || getDefaultValueForEvent(), true));
16607ac75b1Sopenharmony_ci    } else {
16707ac75b1Sopenharmony_ci      addStatementsInConstructor.push(createPropertyAssignNode(propName, initializer, true));
16807ac75b1Sopenharmony_ci    }
16907ac75b1Sopenharmony_ci  } else if (structInfo.paramDecoratorMap.has(propName)) {
17007ac75b1Sopenharmony_ci    const paramProperty: ParamDecoratorInfo = structInfo.paramDecoratorMap.get(propName);
17107ac75b1Sopenharmony_ci    addStatementsInConstructor.push(createInitParam(propName, paramProperty.initializer));
17207ac75b1Sopenharmony_ci  } else {
17307ac75b1Sopenharmony_ci    addStatementsInConstructor.push(createPropertyAssignNode(propName, initializer, false));
17407ac75b1Sopenharmony_ci  }
17507ac75b1Sopenharmony_ci}
17607ac75b1Sopenharmony_ci
17707ac75b1Sopenharmony_cifunction getDefaultValueForEvent(): ts.Expression {
17807ac75b1Sopenharmony_ci  return ts.factory.createArrowFunction(undefined, undefined, [], undefined,
17907ac75b1Sopenharmony_ci    ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
18007ac75b1Sopenharmony_ci    ts.factory.createBlock([], false));
18107ac75b1Sopenharmony_ci}
18207ac75b1Sopenharmony_ci
18307ac75b1Sopenharmony_cifunction createPropertyAssignNode(propName: string, initializer: ts.Expression,
18407ac75b1Sopenharmony_ci  initFromParams: boolean): ts.ExpressionStatement {
18507ac75b1Sopenharmony_ci  return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(
18607ac75b1Sopenharmony_ci    ts.factory.createPropertyAccessExpression(
18707ac75b1Sopenharmony_ci      ts.factory.createThis(),
18807ac75b1Sopenharmony_ci      ts.factory.createIdentifier(propName)
18907ac75b1Sopenharmony_ci    ),
19007ac75b1Sopenharmony_ci    ts.factory.createToken(ts.SyntaxKind.EqualsToken),
19107ac75b1Sopenharmony_ci    setInitValue(propName, initializer, initFromParams)
19207ac75b1Sopenharmony_ci  ));
19307ac75b1Sopenharmony_ci}
19407ac75b1Sopenharmony_ci
19507ac75b1Sopenharmony_cifunction processComponentProperty(member: ts.PropertyDeclaration, structInfo: StructInfo,
19607ac75b1Sopenharmony_ci  log: LogInfo[]): ts.PropertyDeclaration {
19707ac75b1Sopenharmony_ci  const propName: string = member.name.getText();
19807ac75b1Sopenharmony_ci  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(member);
19907ac75b1Sopenharmony_ci  let initializer: ts.Expression;
20007ac75b1Sopenharmony_ci  if (!structInfo.regularSet.has(propName) && !member.type) {
20107ac75b1Sopenharmony_ci    checkV2ComponentMemberType(member.name, propName, log);
20207ac75b1Sopenharmony_ci  }
20307ac75b1Sopenharmony_ci  if (structInfo.staticPropertySet.has(propName)) {
20407ac75b1Sopenharmony_ci    initializer = member.initializer;
20507ac75b1Sopenharmony_ci  }
20607ac75b1Sopenharmony_ci  if (structInfo.paramDecoratorMap.has(propName)) {
20707ac75b1Sopenharmony_ci    return processParamProperty(member, decorators, initializer);
20807ac75b1Sopenharmony_ci  }
20907ac75b1Sopenharmony_ci  if (structInfo.builderParamDecoratorSet.has(propName)) {
21007ac75b1Sopenharmony_ci    return processBuilderParamProperty(member, log, decorators, initializer);
21107ac75b1Sopenharmony_ci  }
21207ac75b1Sopenharmony_ci  return ts.factory.updatePropertyDeclaration(member,
21307ac75b1Sopenharmony_ci    ts.concatenateDecoratorsAndModifiers(decorators, ts.getModifiers(member)),
21407ac75b1Sopenharmony_ci    member.name, member.questionToken, member.type, initializer);
21507ac75b1Sopenharmony_ci}
21607ac75b1Sopenharmony_ci
21707ac75b1Sopenharmony_cifunction checkV2ComponentMemberType(node: ts.Node, propName: string, log: LogInfo[]): void {
21807ac75b1Sopenharmony_ci  log.push({
21907ac75b1Sopenharmony_ci    type: LogType.ERROR,
22007ac75b1Sopenharmony_ci    message: `The property '${propName}' must specify a type.`,
22107ac75b1Sopenharmony_ci    pos: node.getStart()
22207ac75b1Sopenharmony_ci  });
22307ac75b1Sopenharmony_ci}
22407ac75b1Sopenharmony_ci
22507ac75b1Sopenharmony_cifunction processParamProperty(member: ts.PropertyDeclaration,
22607ac75b1Sopenharmony_ci  decorators: readonly ts.Decorator[], initializer: ts.Expression): ts.PropertyDeclaration {
22707ac75b1Sopenharmony_ci  const newDecorators: readonly ts.Decorator[] = removeDecorator(decorators, constantDefine.REQUIRE);
22807ac75b1Sopenharmony_ci  return ts.factory.updatePropertyDeclaration(member,
22907ac75b1Sopenharmony_ci    ts.concatenateDecoratorsAndModifiers(newDecorators, ts.getModifiers(member)),
23007ac75b1Sopenharmony_ci    member.name, member.questionToken, member.type, initializer);
23107ac75b1Sopenharmony_ci}
23207ac75b1Sopenharmony_ci
23307ac75b1Sopenharmony_cifunction processBuilderParamProperty(member: ts.PropertyDeclaration, log: LogInfo[],
23407ac75b1Sopenharmony_ci  decorators: readonly ts.Decorator[], initializer: ts.Expression): ts.PropertyDeclaration {
23507ac75b1Sopenharmony_ci  if (judgeBuilderParamAssignedByBuilder(member)) {
23607ac75b1Sopenharmony_ci    log.push({
23707ac75b1Sopenharmony_ci      type: LogType.ERROR,
23807ac75b1Sopenharmony_ci      message: 'BuilderParam property can only initialized by Builder function.',
23907ac75b1Sopenharmony_ci      pos: member.getStart()
24007ac75b1Sopenharmony_ci    });
24107ac75b1Sopenharmony_ci  }
24207ac75b1Sopenharmony_ci  const newDecorators: readonly ts.Decorator[] = removeDecorator(decorators, constantDefine.BUILDER_PARAM);
24307ac75b1Sopenharmony_ci  return ts.factory.updatePropertyDeclaration(member,
24407ac75b1Sopenharmony_ci    ts.concatenateDecoratorsAndModifiers(newDecorators, ts.getModifiers(member)),
24507ac75b1Sopenharmony_ci    member.name, member.questionToken, member.type, initializer);
24607ac75b1Sopenharmony_ci}
24707ac75b1Sopenharmony_ci
24807ac75b1Sopenharmony_cifunction setInitValue(propName: string, initializer: ts.Expression,
24907ac75b1Sopenharmony_ci  initFromParams: boolean): ts.Expression {
25007ac75b1Sopenharmony_ci  let initNode: ts.Expression = initializer ||
25107ac75b1Sopenharmony_ci    ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_UNDEFINED);
25207ac75b1Sopenharmony_ci  if (initFromParams) {
25307ac75b1Sopenharmony_ci    initNode = createInitNode(propName, initNode);
25407ac75b1Sopenharmony_ci  }
25507ac75b1Sopenharmony_ci  return initNode;
25607ac75b1Sopenharmony_ci}
25707ac75b1Sopenharmony_ci
25807ac75b1Sopenharmony_cifunction createInitNode(propName: string, defaultValue: ts.Expression): ts.Expression {
25907ac75b1Sopenharmony_ci  return ts.factory.createConditionalExpression(
26007ac75b1Sopenharmony_ci    ts.factory.createBinaryExpression(
26107ac75b1Sopenharmony_ci      ts.factory.createStringLiteral(propName),
26207ac75b1Sopenharmony_ci      ts.factory.createToken(ts.SyntaxKind.InKeyword),
26307ac75b1Sopenharmony_ci      ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS)
26407ac75b1Sopenharmony_ci    ),
26507ac75b1Sopenharmony_ci    ts.factory.createToken(ts.SyntaxKind.QuestionToken),
26607ac75b1Sopenharmony_ci    ts.factory.createPropertyAccessExpression(
26707ac75b1Sopenharmony_ci      ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS),
26807ac75b1Sopenharmony_ci      ts.factory.createIdentifier(propName)
26907ac75b1Sopenharmony_ci    ),
27007ac75b1Sopenharmony_ci    ts.factory.createToken(ts.SyntaxKind.ColonToken),
27107ac75b1Sopenharmony_ci    defaultValue
27207ac75b1Sopenharmony_ci  );
27307ac75b1Sopenharmony_ci}
27407ac75b1Sopenharmony_ci
27507ac75b1Sopenharmony_cifunction parseComponentProperty(node: ts.StructDeclaration, structInfo: StructInfo, log: LogInfo[],
27607ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile): void {
27707ac75b1Sopenharmony_ci  node.members.forEach((member: ts.ClassElement) => {
27807ac75b1Sopenharmony_ci    if (ts.isPropertyDeclaration(member)) {
27907ac75b1Sopenharmony_ci      const decorators: readonly ts.Decorator[] = ts.getAllDecorators(member);
28007ac75b1Sopenharmony_ci      const modifiers: readonly ts.Modifier[] = ts.getModifiers(member);
28107ac75b1Sopenharmony_ci      structInfo.propertiesMap.set(member.name.getText(), member.initializer);
28207ac75b1Sopenharmony_ci      parsePropertyDecorator(member, decorators, structInfo, log, sourceFileNode);
28307ac75b1Sopenharmony_ci      parsePropertyModifiers(member.name.getText(), structInfo, modifiers);
28407ac75b1Sopenharmony_ci    }
28507ac75b1Sopenharmony_ci  });
28607ac75b1Sopenharmony_ci}
28707ac75b1Sopenharmony_ci
28807ac75b1Sopenharmony_cifunction parsePropertyModifiers(propName: string, structInfo: StructInfo,
28907ac75b1Sopenharmony_ci  modifiers: readonly ts.Modifier[]): void {
29007ac75b1Sopenharmony_ci  if (modifiers && modifiers.length) {
29107ac75b1Sopenharmony_ci    const isStatic: boolean = modifiers.some((item: ts.Modifier) => {
29207ac75b1Sopenharmony_ci      return item.kind === ts.SyntaxKind.StaticKeyword;
29307ac75b1Sopenharmony_ci    });
29407ac75b1Sopenharmony_ci    if (isStatic) {
29507ac75b1Sopenharmony_ci      structInfo.staticPropertySet.add(propName);
29607ac75b1Sopenharmony_ci    }
29707ac75b1Sopenharmony_ci  }
29807ac75b1Sopenharmony_ci}
29907ac75b1Sopenharmony_ci
30007ac75b1Sopenharmony_ciclass PropertyDecorator {
30107ac75b1Sopenharmony_ci  hasParam: boolean = false;
30207ac75b1Sopenharmony_ci  hasRequire: boolean = false;
30307ac75b1Sopenharmony_ci  hasOnce: boolean = false;
30407ac75b1Sopenharmony_ci  hasEvent: boolean = false;
30507ac75b1Sopenharmony_ci}
30607ac75b1Sopenharmony_ci
30707ac75b1Sopenharmony_ciconst decoratorsFunc: Record<string, Function> = {
30807ac75b1Sopenharmony_ci  'Param': parseParamDecorator,
30907ac75b1Sopenharmony_ci  'Event': parseEventDecorator,
31007ac75b1Sopenharmony_ci  'Require': parseRequireDecorator,
31107ac75b1Sopenharmony_ci  'Once': parseOnceDecorator,
31207ac75b1Sopenharmony_ci  'Local': parseLocalDecorator,
31307ac75b1Sopenharmony_ci  'BuilderParam': parseBuilderParamDecorator,
31407ac75b1Sopenharmony_ci  'Provider': parseProviderDecorator,
31507ac75b1Sopenharmony_ci  'Consumer': parseConsumerDecorator
31607ac75b1Sopenharmony_ci};
31707ac75b1Sopenharmony_ci
31807ac75b1Sopenharmony_cifunction parsePropertyDecorator(member: ts.PropertyDeclaration, decorators: readonly ts.Decorator[],
31907ac75b1Sopenharmony_ci  structInfo: StructInfo, log: LogInfo[], sourceFileNode: ts.SourceFile): void {
32007ac75b1Sopenharmony_ci  const propertyDecorator: PropertyDecorator = new PropertyDecorator();
32107ac75b1Sopenharmony_ci  let isRegular: boolean = true;
32207ac75b1Sopenharmony_ci  for (let i = 0; i < decorators.length; i++) {
32307ac75b1Sopenharmony_ci    const originalName: string = decorators[i].getText().replace(/\([^\(\)]*\)/, '').trim();
32407ac75b1Sopenharmony_ci    const name: string = originalName.replace('@', '').trim();
32507ac75b1Sopenharmony_ci    if (decoratorsFunc[name]) {
32607ac75b1Sopenharmony_ci      decoratorsFunc[name](propertyDecorator, member, structInfo);
32707ac75b1Sopenharmony_ci    }
32807ac75b1Sopenharmony_ci    if (constantDefine.COMPONENT_MEMBER_DECORATOR_V2.includes(originalName) ||
32907ac75b1Sopenharmony_ci      originalName === constantDefine.DECORATOR_BUILDER_PARAM) {
33007ac75b1Sopenharmony_ci      isRegular = false;
33107ac75b1Sopenharmony_ci    }
33207ac75b1Sopenharmony_ci  }
33307ac75b1Sopenharmony_ci  if (isRegular) {
33407ac75b1Sopenharmony_ci    structInfo.regularSet.add(member.name.getText());
33507ac75b1Sopenharmony_ci  }
33607ac75b1Sopenharmony_ci  checkPropertyDecorator(propertyDecorator, member, log, sourceFileNode);
33707ac75b1Sopenharmony_ci}
33807ac75b1Sopenharmony_ci
33907ac75b1Sopenharmony_cifunction checkPropertyDecorator(propertyDecorator: PropertyDecorator,
34007ac75b1Sopenharmony_ci  member: ts.PropertyDeclaration, log: LogInfo[], sourceFileNode: ts.SourceFile): void {
34107ac75b1Sopenharmony_ci  if (log && sourceFileNode) {
34207ac75b1Sopenharmony_ci    checkParamDecorator(propertyDecorator, member, log, sourceFileNode);
34307ac75b1Sopenharmony_ci  }
34407ac75b1Sopenharmony_ci}
34507ac75b1Sopenharmony_ci
34607ac75b1Sopenharmony_cifunction parseParamDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration,
34707ac75b1Sopenharmony_ci  structInfo: StructInfo): void {
34807ac75b1Sopenharmony_ci  propertyDecorator.hasParam = true;
34907ac75b1Sopenharmony_ci  let paramDecoratorInfo: ParamDecoratorInfo = structInfo.paramDecoratorMap.get(member.name.getText());
35007ac75b1Sopenharmony_ci  if (!paramDecoratorInfo) {
35107ac75b1Sopenharmony_ci    paramDecoratorInfo = new ParamDecoratorInfo();
35207ac75b1Sopenharmony_ci  }
35307ac75b1Sopenharmony_ci  paramDecoratorInfo.initializer = member.initializer;
35407ac75b1Sopenharmony_ci  structInfo.paramDecoratorMap.set(member.name.getText(), paramDecoratorInfo);
35507ac75b1Sopenharmony_ci}
35607ac75b1Sopenharmony_ci
35707ac75b1Sopenharmony_cifunction parseEventDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration,
35807ac75b1Sopenharmony_ci  structInfo: StructInfo): void {
35907ac75b1Sopenharmony_ci  propertyDecorator.hasEvent = true;
36007ac75b1Sopenharmony_ci  structInfo.eventDecoratorSet.add(member.name.getText());
36107ac75b1Sopenharmony_ci}
36207ac75b1Sopenharmony_ci
36307ac75b1Sopenharmony_cifunction parseRequireDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration,
36407ac75b1Sopenharmony_ci  structInfo: StructInfo): void {
36507ac75b1Sopenharmony_ci  propertyDecorator.hasRequire = true;
36607ac75b1Sopenharmony_ci  let paramDecoratorInfo: ParamDecoratorInfo = structInfo.paramDecoratorMap.get(member.name.getText());
36707ac75b1Sopenharmony_ci  if (!paramDecoratorInfo) {
36807ac75b1Sopenharmony_ci    paramDecoratorInfo = new ParamDecoratorInfo();
36907ac75b1Sopenharmony_ci  }
37007ac75b1Sopenharmony_ci  paramDecoratorInfo.hasRequire = true;
37107ac75b1Sopenharmony_ci  structInfo.paramDecoratorMap.set(member.name.getText(), paramDecoratorInfo);
37207ac75b1Sopenharmony_ci}
37307ac75b1Sopenharmony_ci
37407ac75b1Sopenharmony_cifunction parseOnceDecorator(propertyDecorator: PropertyDecorator): void {
37507ac75b1Sopenharmony_ci  propertyDecorator.hasOnce = true;
37607ac75b1Sopenharmony_ci}
37707ac75b1Sopenharmony_ci
37807ac75b1Sopenharmony_cifunction parseLocalDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration,
37907ac75b1Sopenharmony_ci  structInfo: StructInfo): void {
38007ac75b1Sopenharmony_ci  structInfo.localDecoratorSet.add(member.name.getText());
38107ac75b1Sopenharmony_ci}
38207ac75b1Sopenharmony_ci
38307ac75b1Sopenharmony_cifunction parseProviderDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration,
38407ac75b1Sopenharmony_ci  structInfo: StructInfo): void {
38507ac75b1Sopenharmony_ci  structInfo.providerDecoratorSet.add(member.name.getText());
38607ac75b1Sopenharmony_ci}
38707ac75b1Sopenharmony_ci
38807ac75b1Sopenharmony_cifunction parseConsumerDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration,
38907ac75b1Sopenharmony_ci  structInfo: StructInfo): void {
39007ac75b1Sopenharmony_ci  structInfo.consumerDecoratorSet.add(member.name.getText());
39107ac75b1Sopenharmony_ci}
39207ac75b1Sopenharmony_ci
39307ac75b1Sopenharmony_cifunction parseBuilderParamDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration,
39407ac75b1Sopenharmony_ci  structInfo: StructInfo): void {
39507ac75b1Sopenharmony_ci  let builderParamSet: Set<string> = builderParamObjectCollection.get(structInfo.structName);
39607ac75b1Sopenharmony_ci  if (!builderParamSet) {
39707ac75b1Sopenharmony_ci    builderParamSet = new Set();
39807ac75b1Sopenharmony_ci  }
39907ac75b1Sopenharmony_ci  builderParamSet.add(member.name.getText());
40007ac75b1Sopenharmony_ci  builderParamObjectCollection.set(structInfo.structName, builderParamSet);
40107ac75b1Sopenharmony_ci  structInfo.builderParamDecoratorSet.add(member.name.getText());
40207ac75b1Sopenharmony_ci}
40307ac75b1Sopenharmony_ci
40407ac75b1Sopenharmony_cifunction checkParamDecorator(propertyDecorator: PropertyDecorator, member: ts.PropertyDeclaration, log: LogInfo[],
40507ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile): void {
40607ac75b1Sopenharmony_ci  if (propertyDecorator.hasParam && !member.initializer && !propertyDecorator.hasRequire) {
40707ac75b1Sopenharmony_ci    const message: string = 'When a variable decorated with @Param is not assigned a default value, ' +
40807ac75b1Sopenharmony_ci      'it must also be decorated with @Require.';
40907ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, member.getStart(), log, sourceFileNode);
41007ac75b1Sopenharmony_ci  }
41107ac75b1Sopenharmony_ci  if (propertyDecorator.hasOnce && !propertyDecorator.hasParam) {
41207ac75b1Sopenharmony_ci    const message: string = 'When a variable decorated with @Once, it must also be decorated with @Param.';
41307ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, member.getStart(), log, sourceFileNode);
41407ac75b1Sopenharmony_ci  }
41507ac75b1Sopenharmony_ci  if (propertyDecorator.hasRequire && !propertyDecorator.hasParam) {
41607ac75b1Sopenharmony_ci    const message: string = 'In a struct decorated with @ComponentV2, @Require can only be used with @Param.';
41707ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, member.getStart(), log, sourceFileNode);
41807ac75b1Sopenharmony_ci  }
41907ac75b1Sopenharmony_ci}
42007ac75b1Sopenharmony_ci
42107ac75b1Sopenharmony_cifunction processStructConstructorV2(members: ts.NodeArray<ts.ClassElement>, newMembers: ts.ClassElement[],
42207ac75b1Sopenharmony_ci  paramStatements: ts.Statement[], freezeParam: FreezeParamType): void {
42307ac75b1Sopenharmony_ci  const freezeParamNode: ts.Expression = freezeParam.componentFreezeParam ?
42407ac75b1Sopenharmony_ci    freezeParam.componentFreezeParam : undefined;
42507ac75b1Sopenharmony_ci  const constructorIndex: number = members.findIndex((item: ts.ClassElement) => {
42607ac75b1Sopenharmony_ci    return ts.isConstructorDeclaration(item);
42707ac75b1Sopenharmony_ci  });
42807ac75b1Sopenharmony_ci  if (constructorIndex !== -1) {
42907ac75b1Sopenharmony_ci    const constructorNode: ts.ConstructorDeclaration = members[constructorIndex] as ts.ConstructorDeclaration;
43007ac75b1Sopenharmony_ci    newMembers.splice(constructorIndex, 0, ts.factory.updateConstructorDeclaration(constructorNode, ts.getModifiers(constructorNode),
43107ac75b1Sopenharmony_ci      createConstructorParams(), updateConstructorBody(constructorNode.body, paramStatements, freezeParamNode)));
43207ac75b1Sopenharmony_ci  }
43307ac75b1Sopenharmony_ci}
43407ac75b1Sopenharmony_ci
43507ac75b1Sopenharmony_cifunction createConstructorParams(): ts.ParameterDeclaration[] {
43607ac75b1Sopenharmony_ci  const paramNames: string[] = [COMPONENT_CONSTRUCTOR_PARENT, COMPONENT_CONSTRUCTOR_PARAMS,
43707ac75b1Sopenharmony_ci    COMPONENT_CONSTRUCTOR_LOCALSTORAGE_PU, ELMTID, COMPONENT_PARAMS_LAMBDA_FUNCTION,
43807ac75b1Sopenharmony_ci    CUSTOM_COMPONENT_EXTRAINFO];
43907ac75b1Sopenharmony_ci  return paramNames.map((name: string) => {
44007ac75b1Sopenharmony_ci    return createAstNodeUtils.createParameterDeclaration(name);
44107ac75b1Sopenharmony_ci  });
44207ac75b1Sopenharmony_ci}
44307ac75b1Sopenharmony_ci
44407ac75b1Sopenharmony_cifunction updateConstructorBody(node: ts.Block, paramStatements: ts.Statement[],
44507ac75b1Sopenharmony_ci  freezeParamNode: ts.Expression): ts.Block {
44607ac75b1Sopenharmony_ci  const body: ts.Statement[] = [createSuperV2()];
44707ac75b1Sopenharmony_ci  if (node.statements) {
44807ac75b1Sopenharmony_ci    body.push(...node.statements);
44907ac75b1Sopenharmony_ci  }
45007ac75b1Sopenharmony_ci  body.push(...paramStatements, createAstNodeUtils.createFinalizeConstruction(freezeParamNode));
45107ac75b1Sopenharmony_ci  return ts.factory.createBlock(body, true);
45207ac75b1Sopenharmony_ci}
45307ac75b1Sopenharmony_ci
45407ac75b1Sopenharmony_cifunction createSuperV2(): ts.Statement {
45507ac75b1Sopenharmony_ci  const paramNames: string[] = [COMPONENT_CONSTRUCTOR_PARENT, ELMTID, CUSTOM_COMPONENT_EXTRAINFO];
45607ac75b1Sopenharmony_ci  return ts.factory.createExpressionStatement(ts.factory.createCallExpression(
45707ac75b1Sopenharmony_ci    ts.factory.createSuper(), undefined, paramNames.map((name: string) => {
45807ac75b1Sopenharmony_ci      return ts.factory.createIdentifier(name);
45907ac75b1Sopenharmony_ci    })));
46007ac75b1Sopenharmony_ci}
46107ac75b1Sopenharmony_ci
46207ac75b1Sopenharmony_cifunction createInitParam(propName: string, initializer: ts.Expression): ts.ExpressionStatement {
46307ac75b1Sopenharmony_ci  return ts.factory.createExpressionStatement(ts.factory.createCallExpression(
46407ac75b1Sopenharmony_ci    ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
46507ac75b1Sopenharmony_ci      ts.factory.createIdentifier(constantDefine.INIT_PARAM)),
46607ac75b1Sopenharmony_ci    undefined,
46707ac75b1Sopenharmony_ci    [
46807ac75b1Sopenharmony_ci      ts.factory.createStringLiteral(propName),
46907ac75b1Sopenharmony_ci      ts.factory.createConditionalExpression(ts.factory.createParenthesizedExpression(
47007ac75b1Sopenharmony_ci        ts.factory.createBinaryExpression(ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS),
47107ac75b1Sopenharmony_ci          ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken),
47207ac75b1Sopenharmony_ci          createParamBinaryNode(propName)
47307ac75b1Sopenharmony_ci        )),
47407ac75b1Sopenharmony_ci      ts.factory.createToken(ts.SyntaxKind.QuestionToken),
47507ac75b1Sopenharmony_ci      ts.factory.createPropertyAccessExpression(
47607ac75b1Sopenharmony_ci        ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS), ts.factory.createIdentifier(propName)
47707ac75b1Sopenharmony_ci      ),
47807ac75b1Sopenharmony_ci      ts.factory.createToken(ts.SyntaxKind.ColonToken),
47907ac75b1Sopenharmony_ci      initializer || ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_UNDEFINED)
48007ac75b1Sopenharmony_ci      )
48107ac75b1Sopenharmony_ci    ]));
48207ac75b1Sopenharmony_ci}
48307ac75b1Sopenharmony_ci
48407ac75b1Sopenharmony_cifunction updateParamNode(propName: string): ts.IfStatement {
48507ac75b1Sopenharmony_ci  return ts.factory.createIfStatement(createParamBinaryNode(propName),
48607ac75b1Sopenharmony_ci    ts.factory.createBlock([
48707ac75b1Sopenharmony_ci      ts.factory.createExpressionStatement(ts.factory.createCallExpression(
48807ac75b1Sopenharmony_ci        ts.factory.createPropertyAccessExpression(ts.factory.createThis(),
48907ac75b1Sopenharmony_ci          ts.factory.createIdentifier(constantDefine.UPDATE_PARAM)),
49007ac75b1Sopenharmony_ci        undefined,
49107ac75b1Sopenharmony_ci        [
49207ac75b1Sopenharmony_ci          ts.factory.createStringLiteral(propName),
49307ac75b1Sopenharmony_ci          ts.factory.createPropertyAccessExpression(
49407ac75b1Sopenharmony_ci            ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS), ts.factory.createIdentifier(propName)
49507ac75b1Sopenharmony_ci          )
49607ac75b1Sopenharmony_ci        ]))], true));
49707ac75b1Sopenharmony_ci}
49807ac75b1Sopenharmony_ci
49907ac75b1Sopenharmony_cifunction createParamBinaryNode(propName: string): ts.BinaryExpression {
50007ac75b1Sopenharmony_ci  return ts.factory.createBinaryExpression(
50107ac75b1Sopenharmony_ci    ts.factory.createStringLiteral(propName),
50207ac75b1Sopenharmony_ci    ts.factory.createToken(ts.SyntaxKind.InKeyword),
50307ac75b1Sopenharmony_ci    ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS)
50407ac75b1Sopenharmony_ci  );
50507ac75b1Sopenharmony_ci}
50607ac75b1Sopenharmony_ci
50707ac75b1Sopenharmony_cifunction updateStateVarsMethodNode(paramStatements: ts.Statement[], newMembers: ts.ClassElement[]): void {
50807ac75b1Sopenharmony_ci  if (paramStatements.length) {
50907ac75b1Sopenharmony_ci    newMembers.push(ts.factory.createMethodDeclaration([ts.factory.createToken(ts.SyntaxKind.PublicKeyword)],
51007ac75b1Sopenharmony_ci      undefined, ts.factory.createIdentifier(constantDefine.UPDATE_STATE_VARS), undefined, undefined,
51107ac75b1Sopenharmony_ci      [createAstNodeUtils.createParameterDeclaration(COMPONENT_CONSTRUCTOR_PARAMS)], undefined,
51207ac75b1Sopenharmony_ci      ts.factory.createBlock([emptyJudgeForParamsNode(), ...paramStatements], true)));
51307ac75b1Sopenharmony_ci  }
51407ac75b1Sopenharmony_ci}
51507ac75b1Sopenharmony_ci
51607ac75b1Sopenharmony_cifunction emptyJudgeForParamsNode(): ts.IfStatement {
51707ac75b1Sopenharmony_ci  return ts.factory.createIfStatement(ts.factory.createBinaryExpression(
51807ac75b1Sopenharmony_ci    ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARAMS),
51907ac75b1Sopenharmony_ci    ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
52007ac75b1Sopenharmony_ci    ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_UNDEFINED)
52107ac75b1Sopenharmony_ci  ), ts.factory.createBlock([ts.factory.createReturnStatement(undefined)], true), undefined);
52207ac75b1Sopenharmony_ci}
52307ac75b1Sopenharmony_ci
52407ac75b1Sopenharmony_cifunction resetStructMapInEts(): void {
52507ac75b1Sopenharmony_ci  structMapInEts.clear();
52607ac75b1Sopenharmony_ci}
52707ac75b1Sopenharmony_ci
52807ac75b1Sopenharmony_ciexport default {
52907ac75b1Sopenharmony_ci  getOrCreateStructInfo: getOrCreateStructInfo,
53007ac75b1Sopenharmony_ci  processStructComponentV2: processStructComponentV2,
53107ac75b1Sopenharmony_ci  parseComponentProperty: parseComponentProperty,
53207ac75b1Sopenharmony_ci  resetStructMapInEts: resetStructMapInEts,
53307ac75b1Sopenharmony_ci  getAliasStructInfo: getAliasStructInfo
53407ac75b1Sopenharmony_ci};
535