107ac75b1Sopenharmony_ci/*
207ac75b1Sopenharmony_ci * Copyright (c) 2021 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_ciimport path from 'path';
1807ac75b1Sopenharmony_ci
1907ac75b1Sopenharmony_ciimport {
2007ac75b1Sopenharmony_ci  INNER_COMPONENT_DECORATORS,
2107ac75b1Sopenharmony_ci  COMPONENT_DECORATOR_ENTRY,
2207ac75b1Sopenharmony_ci  COMPONENT_DECORATOR_PREVIEW,
2307ac75b1Sopenharmony_ci  COMPONENT_DECORATOR_COMPONENT,
2407ac75b1Sopenharmony_ci  COMPONENT_DECORATOR_CUSTOM_DIALOG,
2507ac75b1Sopenharmony_ci  NATIVE_MODULE,
2607ac75b1Sopenharmony_ci  SYSTEM_PLUGIN,
2707ac75b1Sopenharmony_ci  OHOS_PLUGIN,
2807ac75b1Sopenharmony_ci  INNER_COMPONENT_MEMBER_DECORATORS,
2907ac75b1Sopenharmony_ci  COMPONENT_FOREACH,
3007ac75b1Sopenharmony_ci  COMPONENT_LAZYFOREACH,
3107ac75b1Sopenharmony_ci  COMPONENT_STATE_DECORATOR,
3207ac75b1Sopenharmony_ci  COMPONENT_LINK_DECORATOR,
3307ac75b1Sopenharmony_ci  COMPONENT_PROP_DECORATOR,
3407ac75b1Sopenharmony_ci  COMPONENT_STORAGE_PROP_DECORATOR,
3507ac75b1Sopenharmony_ci  COMPONENT_STORAGE_LINK_DECORATOR,
3607ac75b1Sopenharmony_ci  COMPONENT_PROVIDE_DECORATOR,
3707ac75b1Sopenharmony_ci  COMPONENT_CONSUME_DECORATOR,
3807ac75b1Sopenharmony_ci  COMPONENT_OBJECT_LINK_DECORATOR,
3907ac75b1Sopenharmony_ci  COMPONENT_OBSERVED_DECORATOR,
4007ac75b1Sopenharmony_ci  COMPONENT_LOCAL_STORAGE_LINK_DECORATOR,
4107ac75b1Sopenharmony_ci  COMPONENT_LOCAL_STORAGE_PROP_DECORATOR,
4207ac75b1Sopenharmony_ci  COMPONENT_CONCURRENT_DECORATOR,
4307ac75b1Sopenharmony_ci  CHECK_EXTEND_DECORATORS,
4407ac75b1Sopenharmony_ci  COMPONENT_STYLES_DECORATOR,
4507ac75b1Sopenharmony_ci  RESOURCE_NAME_TYPE,
4607ac75b1Sopenharmony_ci  COMPONENT_BUTTON,
4707ac75b1Sopenharmony_ci  COMPONENT_TOGGLE,
4807ac75b1Sopenharmony_ci  COMPONENT_BUILDERPARAM_DECORATOR,
4907ac75b1Sopenharmony_ci  ESMODULE,
5007ac75b1Sopenharmony_ci  CARD_ENABLE_DECORATORS,
5107ac75b1Sopenharmony_ci  CARD_LOG_TYPE_DECORATORS,
5207ac75b1Sopenharmony_ci  JSBUNDLE,
5307ac75b1Sopenharmony_ci  COMPONENT_DECORATOR_REUSEABLE,
5407ac75b1Sopenharmony_ci  STRUCT_DECORATORS,
5507ac75b1Sopenharmony_ci  STRUCT_CONTEXT_METHOD_DECORATORS,
5607ac75b1Sopenharmony_ci  CHECK_COMPONENT_EXTEND_DECORATOR,
5707ac75b1Sopenharmony_ci  CHECK_COMPONENT_ANIMATABLE_EXTEND_DECORATOR,
5807ac75b1Sopenharmony_ci  CLASS_TRACK_DECORATOR,
5907ac75b1Sopenharmony_ci  COMPONENT_REQUIRE_DECORATOR,
6007ac75b1Sopenharmony_ci  COMPONENT_SENDABLE_DECORATOR,
6107ac75b1Sopenharmony_ci  CLASS_MIN_TRACK_DECORATOR,
6207ac75b1Sopenharmony_ci  MIN_OBSERVED,
6307ac75b1Sopenharmony_ci  COMPONENT_NON_DECORATOR,
6407ac75b1Sopenharmony_ci  COMPONENT_DECORATOR_COMPONENT_V2,
6507ac75b1Sopenharmony_ci  OBSERVED,
6607ac75b1Sopenharmony_ci  SENDABLE,
6707ac75b1Sopenharmony_ci  TYPE,
6807ac75b1Sopenharmony_ci  COMPONENT_LOCAL_BUILDER_DECORATOR
6907ac75b1Sopenharmony_ci} from './pre_define';
7007ac75b1Sopenharmony_ciimport {
7107ac75b1Sopenharmony_ci  INNER_COMPONENT_NAMES,
7207ac75b1Sopenharmony_ci  AUTOMIC_COMPONENT,
7307ac75b1Sopenharmony_ci  SINGLE_CHILD_COMPONENT,
7407ac75b1Sopenharmony_ci  SPECIFIC_CHILD_COMPONENT,
7507ac75b1Sopenharmony_ci  BUILDIN_STYLE_NAMES,
7607ac75b1Sopenharmony_ci  EXTEND_ATTRIBUTE,
7707ac75b1Sopenharmony_ci  GLOBAL_STYLE_FUNCTION,
7807ac75b1Sopenharmony_ci  STYLES_ATTRIBUTE,
7907ac75b1Sopenharmony_ci  CUSTOM_BUILDER_METHOD,
8007ac75b1Sopenharmony_ci  GLOBAL_CUSTOM_BUILDER_METHOD,
8107ac75b1Sopenharmony_ci  INNER_CUSTOM_BUILDER_METHOD,
8207ac75b1Sopenharmony_ci  INNER_STYLE_FUNCTION,
8307ac75b1Sopenharmony_ci  INNER_CUSTOM_LOCALBUILDER_METHOD
8407ac75b1Sopenharmony_ci} from './component_map';
8507ac75b1Sopenharmony_ciimport {
8607ac75b1Sopenharmony_ci  LogType,
8707ac75b1Sopenharmony_ci  LogInfo,
8807ac75b1Sopenharmony_ci  componentInfo,
8907ac75b1Sopenharmony_ci  addLog,
9007ac75b1Sopenharmony_ci  hasDecorator,
9107ac75b1Sopenharmony_ci  storedFileInfo,
9207ac75b1Sopenharmony_ci  ExtendResult
9307ac75b1Sopenharmony_ci} from './utils';
9407ac75b1Sopenharmony_ciimport { globalProgram, projectConfig, abilityPagesFullPath } from '../main';
9507ac75b1Sopenharmony_ciimport {
9607ac75b1Sopenharmony_ci  collectExtend,
9707ac75b1Sopenharmony_ci  isExtendFunction,
9807ac75b1Sopenharmony_ci  transformLog,
9907ac75b1Sopenharmony_ci  validatorCard
10007ac75b1Sopenharmony_ci} from './process_ui_syntax';
10107ac75b1Sopenharmony_ciimport {
10207ac75b1Sopenharmony_ci  isBuilderOrLocalBuilder,
10307ac75b1Sopenharmony_ci  builderConditionType
10407ac75b1Sopenharmony_ci} from './process_component_class';
10507ac75b1Sopenharmony_ciimport { stateObjectCollection } from './process_component_member';
10607ac75b1Sopenharmony_ciimport { collectSharedModule } from './fast_build/ark_compiler/check_shared_module';
10707ac75b1Sopenharmony_ciimport constantDefine from './constant_define';
10807ac75b1Sopenharmony_ciimport processStructComponentV2, { StructInfo } from './process_struct_componentV2';
10907ac75b1Sopenharmony_ciimport { getMessageCollection } from './log_message_collection';
11007ac75b1Sopenharmony_ci
11107ac75b1Sopenharmony_ciexport class ComponentCollection {
11207ac75b1Sopenharmony_ci  localStorageName: string = null;
11307ac75b1Sopenharmony_ci  localStorageNode: ts.Identifier | ts.ObjectLiteralExpression = null;
11407ac75b1Sopenharmony_ci  localSharedStorage: ts.Node = null;
11507ac75b1Sopenharmony_ci  entryComponentPos: number = null;
11607ac75b1Sopenharmony_ci  entryComponent: string = null;
11707ac75b1Sopenharmony_ci  previewComponent: Array<string> = [];
11807ac75b1Sopenharmony_ci  customDialogs: Set<string> = new Set([]);
11907ac75b1Sopenharmony_ci  customComponents: Set<string> = new Set([]);
12007ac75b1Sopenharmony_ci  currentClassName: string = null;
12107ac75b1Sopenharmony_ci}
12207ac75b1Sopenharmony_ci
12307ac75b1Sopenharmony_ciexport class IComponentSet {
12407ac75b1Sopenharmony_ci  properties: Set<string> = new Set();
12507ac75b1Sopenharmony_ci  regulars: Set<string> = new Set();
12607ac75b1Sopenharmony_ci  states: Set<string> = new Set();
12707ac75b1Sopenharmony_ci  links: Set<string> = new Set();
12807ac75b1Sopenharmony_ci  props: Set<string> = new Set();
12907ac75b1Sopenharmony_ci  storageProps: Set<string> = new Set();
13007ac75b1Sopenharmony_ci  storageLinks: Set<string> = new Set();
13107ac75b1Sopenharmony_ci  provides: Set<string> = new Set();
13207ac75b1Sopenharmony_ci  consumes: Set<string> = new Set();
13307ac75b1Sopenharmony_ci  objectLinks: Set<string> = new Set();
13407ac75b1Sopenharmony_ci  localStorageLink: Map<string, Set<string>> = new Map();
13507ac75b1Sopenharmony_ci  localStorageProp: Map<string, Set<string>> = new Map();
13607ac75b1Sopenharmony_ci  builderParams: Set<string> = new Set();
13707ac75b1Sopenharmony_ci  builderParamData: Set<string> = new Set();
13807ac75b1Sopenharmony_ci  propData: Set<string> = new Set();
13907ac75b1Sopenharmony_ci  regularInit: Set<string> = new Set();
14007ac75b1Sopenharmony_ci  stateInit: Set<string> = new Set();
14107ac75b1Sopenharmony_ci  provideInit: Set<string> = new Set();
14207ac75b1Sopenharmony_ci  privateCollection: Set<string> = new Set();
14307ac75b1Sopenharmony_ci}
14407ac75b1Sopenharmony_ci
14507ac75b1Sopenharmony_ciexport let componentCollection: ComponentCollection = new ComponentCollection();
14607ac75b1Sopenharmony_ci
14707ac75b1Sopenharmony_ciexport const observedClassCollection: Set<string> = new Set();
14807ac75b1Sopenharmony_ciexport const enumCollection: Set<string> = new Set();
14907ac75b1Sopenharmony_ciexport const classMethodCollection: Map<string, Map<string, Set<string>>> = new Map();
15007ac75b1Sopenharmony_ciexport const dollarCollection: Set<string> = new Set();
15107ac75b1Sopenharmony_ci
15207ac75b1Sopenharmony_ciexport const propertyCollection: Map<string, Set<string>> = new Map();
15307ac75b1Sopenharmony_ciexport const stateCollection: Map<string, Set<string>> = new Map();
15407ac75b1Sopenharmony_ciexport const linkCollection: Map<string, Set<string>> = new Map();
15507ac75b1Sopenharmony_ciexport const propCollection: Map<string, Set<string>> = new Map();
15607ac75b1Sopenharmony_ciexport const regularCollection: Map<string, Set<string>> = new Map();
15707ac75b1Sopenharmony_ciexport const storagePropCollection: Map<string, Set<string>> = new Map();
15807ac75b1Sopenharmony_ciexport const storageLinkCollection: Map<string, Set<string>> = new Map();
15907ac75b1Sopenharmony_ciexport const provideCollection: Map<string, Set<string>> = new Map();
16007ac75b1Sopenharmony_ciexport const consumeCollection: Map<string, Set<string>> = new Map();
16107ac75b1Sopenharmony_ciexport const objectLinkCollection: Map<string, Set<string>> = new Map();
16207ac75b1Sopenharmony_ciexport const builderParamObjectCollection: Map<string, Set<string>> = new Map();
16307ac75b1Sopenharmony_ciexport const localStorageLinkCollection: Map<string, Map<string, Set<string>>> = new Map();
16407ac75b1Sopenharmony_ciexport const localStoragePropCollection: Map<string, Map<string, Set<string>>> = new Map();
16507ac75b1Sopenharmony_ciexport const builderParamInitialization: Map<string, Set<string>> = new Map();
16607ac75b1Sopenharmony_ciexport const propInitialization: Map<string, Set<string>> = new Map();
16707ac75b1Sopenharmony_ciexport const regularInitialization: Map<string, Set<string>> = new Map();
16807ac75b1Sopenharmony_ciexport const stateInitialization: Map<string, Set<string>> = new Map();
16907ac75b1Sopenharmony_ciexport const provideInitialization: Map<string, Set<string>> = new Map();
17007ac75b1Sopenharmony_ciexport const privateCollection: Map<string, Set<string>> = new Map();
17107ac75b1Sopenharmony_ci
17207ac75b1Sopenharmony_ciexport const isStaticViewCollection: Map<string, boolean> = new Map();
17307ac75b1Sopenharmony_ci
17407ac75b1Sopenharmony_ciexport const useOSFiles: Set<string> = new Set();
17507ac75b1Sopenharmony_ciexport const sourcemapNamesCollection: Map<string, Map<string, string>> = new Map();
17607ac75b1Sopenharmony_ciexport const originalImportNamesMap: Map<string, string> = new Map();
17707ac75b1Sopenharmony_ci
17807ac75b1Sopenharmony_ciexport function validateUISyntax(source: string, content: string, filePath: string,
17907ac75b1Sopenharmony_ci  fileQuery: string, sourceFile: ts.SourceFile = null): LogInfo[] {
18007ac75b1Sopenharmony_ci  let log: LogInfo[] = [];
18107ac75b1Sopenharmony_ci  if (process.env.compileMode === 'moduleJson' ||
18207ac75b1Sopenharmony_ci    path.resolve(filePath) !== path.resolve(projectConfig.projectPath || '', 'app.ets')) {
18307ac75b1Sopenharmony_ci    componentCollection = new ComponentCollection();
18407ac75b1Sopenharmony_ci    const res: LogInfo[] = checkComponentDecorator(source, filePath, fileQuery, sourceFile);
18507ac75b1Sopenharmony_ci    if (res) {
18607ac75b1Sopenharmony_ci      log = log.concat(res);
18707ac75b1Sopenharmony_ci    }
18807ac75b1Sopenharmony_ci    const allComponentNames: Set<string> =
18907ac75b1Sopenharmony_ci      new Set([...INNER_COMPONENT_NAMES, ...componentCollection.customComponents]);
19007ac75b1Sopenharmony_ci    checkUISyntax(filePath, allComponentNames, content, log, sourceFile, fileQuery);
19107ac75b1Sopenharmony_ci    componentCollection.customComponents.forEach(item => componentInfo.componentNames.add(item));
19207ac75b1Sopenharmony_ci  }
19307ac75b1Sopenharmony_ci
19407ac75b1Sopenharmony_ci  if (projectConfig.compileMode === ESMODULE) {
19507ac75b1Sopenharmony_ci    collectSharedModule(source, filePath, sourceFile);
19607ac75b1Sopenharmony_ci  }
19707ac75b1Sopenharmony_ci
19807ac75b1Sopenharmony_ci  return log;
19907ac75b1Sopenharmony_ci}
20007ac75b1Sopenharmony_ci
20107ac75b1Sopenharmony_cifunction checkComponentDecorator(source: string, filePath: string,
20207ac75b1Sopenharmony_ci  fileQuery: string, sourceFile: ts.SourceFile | null): LogInfo[] | null {
20307ac75b1Sopenharmony_ci  const log: LogInfo[] = [];
20407ac75b1Sopenharmony_ci  if (!sourceFile) {
20507ac75b1Sopenharmony_ci    sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
20607ac75b1Sopenharmony_ci  }
20707ac75b1Sopenharmony_ci  if (sourceFile && sourceFile.statements && sourceFile.statements.length) {
20807ac75b1Sopenharmony_ci    const result: DecoratorResult = {
20907ac75b1Sopenharmony_ci      entryCount: 0,
21007ac75b1Sopenharmony_ci      previewCount: 0
21107ac75b1Sopenharmony_ci    };
21207ac75b1Sopenharmony_ci    sourceFile.statements.forEach((item, index, arr) => {
21307ac75b1Sopenharmony_ci      if (isObservedClass(item)) {
21407ac75b1Sopenharmony_ci        // @ts-ignore
21507ac75b1Sopenharmony_ci        observedClassCollection.add(item.name.getText());
21607ac75b1Sopenharmony_ci      }
21707ac75b1Sopenharmony_ci      if (ts.isEnumDeclaration(item) && item.name) {
21807ac75b1Sopenharmony_ci        enumCollection.add(item.name.getText());
21907ac75b1Sopenharmony_ci      }
22007ac75b1Sopenharmony_ci      if (ts.isStructDeclaration(item)) {
22107ac75b1Sopenharmony_ci        validateStructSpec(item, result, log, sourceFile);
22207ac75b1Sopenharmony_ci      }
22307ac75b1Sopenharmony_ci      if (ts.isMissingDeclaration(item)) {
22407ac75b1Sopenharmony_ci        const decorators = ts.getAllDecorators(item);
22507ac75b1Sopenharmony_ci        for (let i = 0; i < decorators.length; i++) {
22607ac75b1Sopenharmony_ci          if (decorators[i] && /struct/.test(decorators[i].getText())) {
22707ac75b1Sopenharmony_ci            const message: string = `Please use a valid decorator.`;
22807ac75b1Sopenharmony_ci            addLog(LogType.ERROR, message, item.getStart(), log, sourceFile);
22907ac75b1Sopenharmony_ci            break;
23007ac75b1Sopenharmony_ci          }
23107ac75b1Sopenharmony_ci        }
23207ac75b1Sopenharmony_ci      }
23307ac75b1Sopenharmony_ci    });
23407ac75b1Sopenharmony_ci    if (process.env.compileTool === 'rollup') {
23507ac75b1Sopenharmony_ci      if (result.entryCount > 0) {
23607ac75b1Sopenharmony_ci        storedFileInfo.wholeFileInfo[filePath].hasEntry = true;
23707ac75b1Sopenharmony_ci      } else {
23807ac75b1Sopenharmony_ci        storedFileInfo.wholeFileInfo[filePath].hasEntry = false;
23907ac75b1Sopenharmony_ci      }
24007ac75b1Sopenharmony_ci    }
24107ac75b1Sopenharmony_ci    validateEntryAndPreviewCount(result, fileQuery, sourceFile.fileName, projectConfig.isPreview,
24207ac75b1Sopenharmony_ci      !!projectConfig.checkEntry, log);
24307ac75b1Sopenharmony_ci  }
24407ac75b1Sopenharmony_ci
24507ac75b1Sopenharmony_ci  return log.length ? log : null;
24607ac75b1Sopenharmony_ci}
24707ac75b1Sopenharmony_ci
24807ac75b1Sopenharmony_cifunction validateStructSpec(item: ts.StructDeclaration, result: DecoratorResult, log: LogInfo[],
24907ac75b1Sopenharmony_ci  sourceFile: ts.SourceFile | null): void {
25007ac75b1Sopenharmony_ci  if (item.name && ts.isIdentifier(item.name)) {
25107ac75b1Sopenharmony_ci    const componentName: string = item.name.getText();
25207ac75b1Sopenharmony_ci    componentCollection.customComponents.add(componentName);
25307ac75b1Sopenharmony_ci    const decorators: readonly ts.Decorator[] = ts.getAllDecorators(item);
25407ac75b1Sopenharmony_ci    if (decorators && decorators.length) {
25507ac75b1Sopenharmony_ci      checkDecorators(decorators, result, item.name, log, sourceFile, item);
25607ac75b1Sopenharmony_ci    } else {
25707ac75b1Sopenharmony_ci      const message: string = `Decorator '@Component', '@ComponentV2', or '@CustomDialog' is missing for struct '${componentName}'.`;
25807ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, item.getStart(), log, sourceFile);
25907ac75b1Sopenharmony_ci    }
26007ac75b1Sopenharmony_ci  } else {
26107ac75b1Sopenharmony_ci    const message: string = `A struct must have a name.`;
26207ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, item.getStart(), log, sourceFile);
26307ac75b1Sopenharmony_ci  }
26407ac75b1Sopenharmony_ci}
26507ac75b1Sopenharmony_ci
26607ac75b1Sopenharmony_cifunction validateEntryAndPreviewCount(result: DecoratorResult, fileQuery: string,
26707ac75b1Sopenharmony_ci  fileName: string, isPreview: boolean, checkEntry: boolean, log: LogInfo[]): void {
26807ac75b1Sopenharmony_ci  if (result.previewCount > 10 && (fileQuery === '?entry' || process.env.watchMode === 'true')) {
26907ac75b1Sopenharmony_ci    log.push({
27007ac75b1Sopenharmony_ci      type: LogType.ERROR,
27107ac75b1Sopenharmony_ci      message: `A page can contain at most 10 '@Preview' decorators.`,
27207ac75b1Sopenharmony_ci      fileName: fileName
27307ac75b1Sopenharmony_ci    });
27407ac75b1Sopenharmony_ci  }
27507ac75b1Sopenharmony_ci  if (result.entryCount > 1 && fileQuery === '?entry') {
27607ac75b1Sopenharmony_ci    log.push({
27707ac75b1Sopenharmony_ci      type: LogType.ERROR,
27807ac75b1Sopenharmony_ci      message: `A page can't contain more than one '@Entry' decorator`,
27907ac75b1Sopenharmony_ci      fileName: fileName
28007ac75b1Sopenharmony_ci    });
28107ac75b1Sopenharmony_ci  }
28207ac75b1Sopenharmony_ci  if (isPreview && !checkEntry && result.previewCount < 1 && result.entryCount !== 1 &&
28307ac75b1Sopenharmony_ci    fileQuery === '?entry') {
28407ac75b1Sopenharmony_ci    log.push({
28507ac75b1Sopenharmony_ci      type: LogType.ERROR,
28607ac75b1Sopenharmony_ci      message: `A page which is being previewed must have one and only one '@Entry' ` +
28707ac75b1Sopenharmony_ci        `decorator, or at least one '@Preview' decorator.`,
28807ac75b1Sopenharmony_ci      fileName: fileName
28907ac75b1Sopenharmony_ci    });
29007ac75b1Sopenharmony_ci  } else if ((!isPreview || isPreview && checkEntry) && result.entryCount !== 1 && fileQuery === '?entry' &&
29107ac75b1Sopenharmony_ci    !abilityPagesFullPath.has(path.resolve(fileName).toLowerCase())) {
29207ac75b1Sopenharmony_ci    log.push({
29307ac75b1Sopenharmony_ci      type: LogType.ERROR,
29407ac75b1Sopenharmony_ci      message: `A page configured in '${projectConfig.pagesJsonFileName} or build-profile.json5' must have one and only one '@Entry' decorator.` +
29507ac75b1Sopenharmony_ci        `Solutions:>Please make sure that the splash page has one and only one '@Entry' decorator.`,
29607ac75b1Sopenharmony_ci      fileName: fileName
29707ac75b1Sopenharmony_ci    });
29807ac75b1Sopenharmony_ci  }
29907ac75b1Sopenharmony_ci}
30007ac75b1Sopenharmony_ci
30107ac75b1Sopenharmony_ciexport function isObservedClass(node: ts.Node): boolean {
30207ac75b1Sopenharmony_ci  if (ts.isClassDeclaration(node) && hasDecorator(node, COMPONENT_OBSERVED_DECORATOR)) {
30307ac75b1Sopenharmony_ci    return true;
30407ac75b1Sopenharmony_ci  }
30507ac75b1Sopenharmony_ci  return false;
30607ac75b1Sopenharmony_ci}
30707ac75b1Sopenharmony_ci
30807ac75b1Sopenharmony_ciexport function isCustomDialogClass(node: ts.Node): boolean {
30907ac75b1Sopenharmony_ci  if (ts.isStructDeclaration(node) && hasDecorator(node, COMPONENT_DECORATOR_CUSTOM_DIALOG)) {
31007ac75b1Sopenharmony_ci    return true;
31107ac75b1Sopenharmony_ci  }
31207ac75b1Sopenharmony_ci  return false;
31307ac75b1Sopenharmony_ci}
31407ac75b1Sopenharmony_ci
31507ac75b1Sopenharmony_ciinterface DecoratorResult {
31607ac75b1Sopenharmony_ci  entryCount: number;
31707ac75b1Sopenharmony_ci  previewCount: number;
31807ac75b1Sopenharmony_ci}
31907ac75b1Sopenharmony_ci
32007ac75b1Sopenharmony_cifunction checkDecorators(decorators: readonly ts.Decorator[], result: DecoratorResult,
32107ac75b1Sopenharmony_ci  component: ts.Identifier, log: LogInfo[], sourceFile: ts.SourceFile, node: ts.StructDeclaration): void {
32207ac75b1Sopenharmony_ci  const componentName: string = component.getText();
32307ac75b1Sopenharmony_ci  const structInfo: StructInfo = processStructComponentV2.getOrCreateStructInfo(componentName);
32407ac75b1Sopenharmony_ci  let hasInnerComponentDecorator: boolean = false;
32507ac75b1Sopenharmony_ci  decorators.forEach((element) => {
32607ac75b1Sopenharmony_ci    let name: string = element.getText().replace(/\([^\(\)]*\)/, '').trim();
32707ac75b1Sopenharmony_ci    if (element.expression && element.expression.expression && ts.isIdentifier(element.expression.expression)) {
32807ac75b1Sopenharmony_ci      name = '@' + element.expression.expression.getText();
32907ac75b1Sopenharmony_ci    }
33007ac75b1Sopenharmony_ci    if (INNER_COMPONENT_DECORATORS.has(name)) {
33107ac75b1Sopenharmony_ci      hasInnerComponentDecorator = true;
33207ac75b1Sopenharmony_ci      switch (name) {
33307ac75b1Sopenharmony_ci        case COMPONENT_DECORATOR_ENTRY:
33407ac75b1Sopenharmony_ci          checkEntryComponent(node, log, sourceFile);
33507ac75b1Sopenharmony_ci          result.entryCount++;
33607ac75b1Sopenharmony_ci          componentCollection.entryComponent = componentName;
33707ac75b1Sopenharmony_ci          componentCollection.entryComponentPos = node.getStart();
33807ac75b1Sopenharmony_ci          collectLocalStorageName(element);
33907ac75b1Sopenharmony_ci          break;
34007ac75b1Sopenharmony_ci        case COMPONENT_DECORATOR_PREVIEW:
34107ac75b1Sopenharmony_ci          result.previewCount++;
34207ac75b1Sopenharmony_ci          componentCollection.previewComponent.push(componentName);
34307ac75b1Sopenharmony_ci          break;
34407ac75b1Sopenharmony_ci        case COMPONENT_DECORATOR_COMPONENT_V2:
34507ac75b1Sopenharmony_ci          structInfo.isComponentV2 = true;
34607ac75b1Sopenharmony_ci          break;
34707ac75b1Sopenharmony_ci        case COMPONENT_DECORATOR_COMPONENT:
34807ac75b1Sopenharmony_ci          structInfo.isComponentV1 = true;
34907ac75b1Sopenharmony_ci          break;
35007ac75b1Sopenharmony_ci        case COMPONENT_DECORATOR_CUSTOM_DIALOG:
35107ac75b1Sopenharmony_ci          componentCollection.customDialogs.add(componentName);
35207ac75b1Sopenharmony_ci          structInfo.isCustomDialog = true;
35307ac75b1Sopenharmony_ci          break;
35407ac75b1Sopenharmony_ci        case COMPONENT_DECORATOR_REUSEABLE:
35507ac75b1Sopenharmony_ci          storedFileInfo.getCurrentArkTsFile().recycleComponents.add(componentName);
35607ac75b1Sopenharmony_ci          structInfo.isReusable = true;
35707ac75b1Sopenharmony_ci          break;
35807ac75b1Sopenharmony_ci      }
35907ac75b1Sopenharmony_ci    } else {
36007ac75b1Sopenharmony_ci      validateInvalidStructDecorator(element, componentName, log, sourceFile);
36107ac75b1Sopenharmony_ci    }
36207ac75b1Sopenharmony_ci  });
36307ac75b1Sopenharmony_ci  validateStruct(hasInnerComponentDecorator, componentName, component, log, sourceFile, structInfo);
36407ac75b1Sopenharmony_ci}
36507ac75b1Sopenharmony_ci
36607ac75b1Sopenharmony_cifunction validateInvalidStructDecorator(element: ts.Decorator, componentName: string, log: LogInfo[],
36707ac75b1Sopenharmony_ci  sourceFile: ts.SourceFile): void {
36807ac75b1Sopenharmony_ci  const pos: number = element.expression ? element.expression.pos : element.pos;
36907ac75b1Sopenharmony_ci  const message: string = `The struct '${componentName}' use invalid decorator.`;
37007ac75b1Sopenharmony_ci  addLog(LogType.WARN, message, pos, log, sourceFile);
37107ac75b1Sopenharmony_ci}
37207ac75b1Sopenharmony_ci
37307ac75b1Sopenharmony_cifunction validateStruct(hasInnerComponentDecorator: boolean, componentName: string, component: ts.Identifier,
37407ac75b1Sopenharmony_ci  log: LogInfo[], sourceFile: ts.SourceFile, structInfo: StructInfo): void {
37507ac75b1Sopenharmony_ci  if (!hasInnerComponentDecorator) {
37607ac75b1Sopenharmony_ci    const message: string = `Decorator '@Component', '@ComponentV2', or '@CustomDialog' is missing for struct '${componentName}'.`;
37707ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, component.pos, log, sourceFile);
37807ac75b1Sopenharmony_ci  } else if (structInfo.isComponentV2 && (structInfo.isComponentV1 || structInfo.isReusable || structInfo.isCustomDialog) ) {
37907ac75b1Sopenharmony_ci    const message: string = `The struct '${componentName}' can not be decorated with '@ComponentV2' ` +
38007ac75b1Sopenharmony_ci      `and '@Component', '@Reusable', '@CustomDialog' at the same time.`;
38107ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, component.pos, log, sourceFile);
38207ac75b1Sopenharmony_ci  }
38307ac75b1Sopenharmony_ci  if (BUILDIN_STYLE_NAMES.has(componentName)) {
38407ac75b1Sopenharmony_ci    const message: string = `The struct '${componentName}' cannot have the same name ` +
38507ac75b1Sopenharmony_ci      `as the built-in attribute '${componentName}'.`;
38607ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, component.pos, log, sourceFile);
38707ac75b1Sopenharmony_ci  }
38807ac75b1Sopenharmony_ci  if (INNER_COMPONENT_NAMES.has(componentName)) {
38907ac75b1Sopenharmony_ci    const message: string = `The struct '${componentName}' cannot have the same name ` +
39007ac75b1Sopenharmony_ci      `as the built-in component '${componentName}'.`;
39107ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, component.pos, log, sourceFile);
39207ac75b1Sopenharmony_ci  }
39307ac75b1Sopenharmony_ci}
39407ac75b1Sopenharmony_ci
39507ac75b1Sopenharmony_cifunction checkConcurrentDecorator(node: ts.FunctionDeclaration | ts.MethodDeclaration, log: LogInfo[],
39607ac75b1Sopenharmony_ci  sourceFile: ts.SourceFile): void {
39707ac75b1Sopenharmony_ci  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
39807ac75b1Sopenharmony_ci  if (projectConfig.compileMode === JSBUNDLE) {
39907ac75b1Sopenharmony_ci    const message: string = `@Concurrent can only be used in ESMODULE compile mode.`;
40007ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, decorators![0].pos, log, sourceFile);
40107ac75b1Sopenharmony_ci  }
40207ac75b1Sopenharmony_ci  if (ts.isMethodDeclaration(node)) {
40307ac75b1Sopenharmony_ci    const message: string = `@Concurrent can not be used on method. please use it on function declaration.`;
40407ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, decorators![0].pos, log, sourceFile);
40507ac75b1Sopenharmony_ci  }
40607ac75b1Sopenharmony_ci  if (node.asteriskToken) {
40707ac75b1Sopenharmony_ci    let hasAsync: boolean = false;
40807ac75b1Sopenharmony_ci    const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
40907ac75b1Sopenharmony_ci    const checkAsyncModifier = (modifier: ts.Modifier) : boolean => modifier.kind === ts.SyntaxKind.AsyncKeyword;
41007ac75b1Sopenharmony_ci    modifiers && (hasAsync = modifiers.some(checkAsyncModifier));
41107ac75b1Sopenharmony_ci    const funcKind: string = hasAsync ? 'Async generator' : 'Generator';
41207ac75b1Sopenharmony_ci    const message: string = `@Concurrent can not be used on ${funcKind} function declaration.`;
41307ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, decorators![0].pos, log, sourceFile);
41407ac75b1Sopenharmony_ci  }
41507ac75b1Sopenharmony_ci}
41607ac75b1Sopenharmony_ci
41707ac75b1Sopenharmony_cifunction collectLocalStorageName(node: ts.Decorator): void {
41807ac75b1Sopenharmony_ci  if (node && node.expression && ts.isCallExpression(node.expression)) {
41907ac75b1Sopenharmony_ci    if (node.expression.arguments && node.expression.arguments.length) {
42007ac75b1Sopenharmony_ci      node.expression.arguments.forEach((item: ts.Node, index: number) => {
42107ac75b1Sopenharmony_ci        if (ts.isIdentifier(item) && index === 0) {
42207ac75b1Sopenharmony_ci          componentCollection.localStorageName = item.getText();
42307ac75b1Sopenharmony_ci          componentCollection.localStorageNode = item;
42407ac75b1Sopenharmony_ci        } else if (ts.isObjectLiteralExpression(item) && index === 0) {
42507ac75b1Sopenharmony_ci          componentCollection.localStorageName = null;
42607ac75b1Sopenharmony_ci          componentCollection.localStorageNode = item;
42707ac75b1Sopenharmony_ci        } else {
42807ac75b1Sopenharmony_ci          componentCollection.localSharedStorage = item;
42907ac75b1Sopenharmony_ci        }
43007ac75b1Sopenharmony_ci      });
43107ac75b1Sopenharmony_ci    }
43207ac75b1Sopenharmony_ci  } else {
43307ac75b1Sopenharmony_ci    componentCollection.localStorageName = null;
43407ac75b1Sopenharmony_ci    componentCollection.localStorageNode = null;
43507ac75b1Sopenharmony_ci  }
43607ac75b1Sopenharmony_ci}
43707ac75b1Sopenharmony_ci
43807ac75b1Sopenharmony_cifunction checkUISyntax(filePath: string, allComponentNames: Set<string>, content: string,
43907ac75b1Sopenharmony_ci  log: LogInfo[], sourceFile: ts.SourceFile | null, fileQuery: string): void {
44007ac75b1Sopenharmony_ci  if (!sourceFile) {
44107ac75b1Sopenharmony_ci    sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
44207ac75b1Sopenharmony_ci  }
44307ac75b1Sopenharmony_ci  visitAllNode(sourceFile, sourceFile, allComponentNames, log, false, false, false, false, fileQuery, false, false);
44407ac75b1Sopenharmony_ci}
44507ac75b1Sopenharmony_ci
44607ac75b1Sopenharmony_cifunction visitAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, allComponentNames: Set<string>,
44707ac75b1Sopenharmony_ci  log: LogInfo[], structContext: boolean, classContext: boolean, isObservedClass: boolean,
44807ac75b1Sopenharmony_ci  isComponentV2: boolean, fileQuery: string, isObservedV1Class: boolean, isSendableClass: boolean): void {
44907ac75b1Sopenharmony_ci  if (ts.isStructDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
45007ac75b1Sopenharmony_ci    structContext = true;
45107ac75b1Sopenharmony_ci    const structName: string = node.name.escapedText.toString();
45207ac75b1Sopenharmony_ci    const structInfo: StructInfo = processStructComponentV2.getOrCreateStructInfo(structName);
45307ac75b1Sopenharmony_ci    if (structInfo.isComponentV2) {
45407ac75b1Sopenharmony_ci      processStructComponentV2.parseComponentProperty(node, structInfo, log, sourceFileNode);
45507ac75b1Sopenharmony_ci      isComponentV2 = true;
45607ac75b1Sopenharmony_ci    } else {
45707ac75b1Sopenharmony_ci      collectComponentProps(node, structInfo);
45807ac75b1Sopenharmony_ci    }
45907ac75b1Sopenharmony_ci  }
46007ac75b1Sopenharmony_ci  if (ts.isClassDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
46107ac75b1Sopenharmony_ci    classContext = true;
46207ac75b1Sopenharmony_ci    [isObservedV1Class, isObservedClass, isSendableClass] = parseClassDecorator(node, sourceFileNode, log);
46307ac75b1Sopenharmony_ci  }
46407ac75b1Sopenharmony_ci  if (ts.isMethodDeclaration(node) || ts.isFunctionDeclaration(node)) {
46507ac75b1Sopenharmony_ci    methodDecoratorCollect(node);
46607ac75b1Sopenharmony_ci    if (hasDecorator(node, COMPONENT_CONCURRENT_DECORATOR)) {
46707ac75b1Sopenharmony_ci      // ark compiler's feature
46807ac75b1Sopenharmony_ci      checkConcurrentDecorator(node, log, sourceFileNode);
46907ac75b1Sopenharmony_ci    }
47007ac75b1Sopenharmony_ci    validateFunction(node, sourceFileNode, log);
47107ac75b1Sopenharmony_ci  }
47207ac75b1Sopenharmony_ci  checkDecoratorCount(node, sourceFileNode, log);
47307ac75b1Sopenharmony_ci  checkDecorator(sourceFileNode, node, log, structContext, classContext, isObservedClass, isComponentV2,
47407ac75b1Sopenharmony_ci    isObservedV1Class, isSendableClass);
47507ac75b1Sopenharmony_ci  node.getChildren().forEach((item: ts.Node) => visitAllNode(item, sourceFileNode, allComponentNames, log,
47607ac75b1Sopenharmony_ci    structContext, classContext, isObservedClass, isComponentV2, fileQuery, isObservedV1Class, isSendableClass));
47707ac75b1Sopenharmony_ci  structContext = false;
47807ac75b1Sopenharmony_ci  classContext = false;
47907ac75b1Sopenharmony_ci  isObservedClass = false;
48007ac75b1Sopenharmony_ci  isObservedV1Class = false;
48107ac75b1Sopenharmony_ci  isSendableClass = false;
48207ac75b1Sopenharmony_ci}
48307ac75b1Sopenharmony_ci
48407ac75b1Sopenharmony_ciconst v1ComponentDecorators: string[] = [
48507ac75b1Sopenharmony_ci  'State', 'Prop', 'Link', 'Provide', 'Consume',
48607ac75b1Sopenharmony_ci  'StorageLink', 'StorageProp', 'LocalStorageLink', 'LocalStorageProp'
48707ac75b1Sopenharmony_ci];
48807ac75b1Sopenharmony_ciconst v2ComponentDecorators: string[] = [
48907ac75b1Sopenharmony_ci  'Local', 'Param', 'Event', 'Provider', 'Consumer'
49007ac75b1Sopenharmony_ci];
49107ac75b1Sopenharmony_cifunction validatePropertyInStruct(structContext: boolean, decoratorNode: ts.Identifier,
49207ac75b1Sopenharmony_ci  decoratorName: string, sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
49307ac75b1Sopenharmony_ci  if (structContext) {
49407ac75b1Sopenharmony_ci    const isV1Decorator: boolean = v1ComponentDecorators.includes(decoratorName);
49507ac75b1Sopenharmony_ci    const isV2Decorator: boolean = v2ComponentDecorators.includes(decoratorName);
49607ac75b1Sopenharmony_ci    if (!isV1Decorator && !isV2Decorator) {
49707ac75b1Sopenharmony_ci      return;
49807ac75b1Sopenharmony_ci    }
49907ac75b1Sopenharmony_ci    const classResult: ClassDecoratorResult = new ClassDecoratorResult();
50007ac75b1Sopenharmony_ci    const propertyNode: ts.PropertyDeclaration = getPropertyNodeByDecorator(decoratorNode);
50107ac75b1Sopenharmony_ci    if (propertyNode && propertyNode.type && globalProgram.checker) {
50207ac75b1Sopenharmony_ci      validatePropertyType(propertyNode.type, classResult);
50307ac75b1Sopenharmony_ci    }
50407ac75b1Sopenharmony_ci    let message: string;
50507ac75b1Sopenharmony_ci    if (isV1Decorator && classResult.hasObservedV2) {
50607ac75b1Sopenharmony_ci      message = `The type of the @${decoratorName} property can not be a class decorated with @ObservedV2.`;
50707ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, decoratorNode.getStart(), log, sourceFileNode);
50807ac75b1Sopenharmony_ci      return;
50907ac75b1Sopenharmony_ci    }
51007ac75b1Sopenharmony_ci    if (isV2Decorator && classResult.hasObserved) {
51107ac75b1Sopenharmony_ci      message = `The type of the @${decoratorName} property can not be a class decorated with @Observed.`;
51207ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, decoratorNode.getStart(), log, sourceFileNode);
51307ac75b1Sopenharmony_ci      return;
51407ac75b1Sopenharmony_ci    }
51507ac75b1Sopenharmony_ci  }
51607ac75b1Sopenharmony_ci}
51707ac75b1Sopenharmony_ci
51807ac75b1Sopenharmony_cifunction getPropertyNodeByDecorator(decoratorNode: ts.Identifier): ts.PropertyDeclaration {
51907ac75b1Sopenharmony_ci  if (ts.isDecorator(decoratorNode.parent) && ts.isPropertyDeclaration(decoratorNode.parent.parent)) {
52007ac75b1Sopenharmony_ci    return decoratorNode.parent.parent;
52107ac75b1Sopenharmony_ci  }
52207ac75b1Sopenharmony_ci  if (ts.isCallExpression(decoratorNode.parent) && ts.isDecorator(decoratorNode.parent.parent) &&
52307ac75b1Sopenharmony_ci    ts.isPropertyDeclaration(decoratorNode.parent.parent.parent)) {
52407ac75b1Sopenharmony_ci    return decoratorNode.parent.parent.parent;
52507ac75b1Sopenharmony_ci  }
52607ac75b1Sopenharmony_ci  return undefined;
52707ac75b1Sopenharmony_ci}
52807ac75b1Sopenharmony_ci
52907ac75b1Sopenharmony_cifunction validatePropertyType(node: ts.TypeNode, classResult: ClassDecoratorResult): void {
53007ac75b1Sopenharmony_ci  if (ts.isUnionTypeNode(node) && node.types && node.types.length) {
53107ac75b1Sopenharmony_ci    node.types.forEach((item: ts.TypeNode) => {
53207ac75b1Sopenharmony_ci      validatePropertyType(item, classResult);
53307ac75b1Sopenharmony_ci    });
53407ac75b1Sopenharmony_ci  }
53507ac75b1Sopenharmony_ci  if (ts.isTypeReferenceNode(node) && node.typeName) {
53607ac75b1Sopenharmony_ci    const typeNode: ts.Type = globalProgram.checker.getTypeAtLocation(node.typeName);
53707ac75b1Sopenharmony_ci    parsePropertyType(typeNode, classResult);
53807ac75b1Sopenharmony_ci  }
53907ac75b1Sopenharmony_ci}
54007ac75b1Sopenharmony_ci
54107ac75b1Sopenharmony_cifunction parsePropertyType(type: ts.Type, classResult: ClassDecoratorResult): void {
54207ac75b1Sopenharmony_ci  // @ts-ignore
54307ac75b1Sopenharmony_ci  if (type && type.types && type.types.length) {
54407ac75b1Sopenharmony_ci    // @ts-ignore
54507ac75b1Sopenharmony_ci    type.types.forEach((item: ts.Type) => {
54607ac75b1Sopenharmony_ci      parsePropertyType(item, classResult);
54707ac75b1Sopenharmony_ci    });
54807ac75b1Sopenharmony_ci  }
54907ac75b1Sopenharmony_ci  if (type && type.symbol && type.symbol.valueDeclaration &&
55007ac75b1Sopenharmony_ci    ts.isClassDeclaration(type.symbol.valueDeclaration)) {
55107ac75b1Sopenharmony_ci    const result: ClassDecoratorResult = getClassDecoratorResult(type.symbol.valueDeclaration);
55207ac75b1Sopenharmony_ci    if (result.hasObserved) {
55307ac75b1Sopenharmony_ci      classResult.hasObserved = result.hasObserved;
55407ac75b1Sopenharmony_ci    }
55507ac75b1Sopenharmony_ci    if (result.hasObservedV2) {
55607ac75b1Sopenharmony_ci      classResult.hasObservedV2 = result.hasObservedV2;
55707ac75b1Sopenharmony_ci    }
55807ac75b1Sopenharmony_ci  }
55907ac75b1Sopenharmony_ci}
56007ac75b1Sopenharmony_ci
56107ac75b1Sopenharmony_cifunction checkDecoratorCount(node: ts.Node, sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
56207ac75b1Sopenharmony_ci  if (ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isMethodDeclaration(node)) {
56307ac75b1Sopenharmony_ci    const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
56407ac75b1Sopenharmony_ci    let innerDecoratorCount: number = 0;
56507ac75b1Sopenharmony_ci    const exludeDecorators: string[] = ['@Require', '@Once'];
56607ac75b1Sopenharmony_ci    const v1MethodDecorators: string[] = ['@Builder', '@Styles'];
56707ac75b1Sopenharmony_ci    const v1DecoratorMap: Map<string, number> = new Map<string, number>();
56807ac75b1Sopenharmony_ci    const v2DecoratorMap: Map<string, number> = new Map<string, number>();
56907ac75b1Sopenharmony_ci    let checkDecoratorCount: number = 0;
57007ac75b1Sopenharmony_ci    decorators.forEach((item: ts.Decorator) => {
57107ac75b1Sopenharmony_ci      const decoratorName: string = item.getText().replace(/\([^\(\)]*\)/, '');
57207ac75b1Sopenharmony_ci      if (!exludeDecorators.includes(decoratorName) && (constantDefine.DECORATOR_V2.includes(decoratorName) ||
57307ac75b1Sopenharmony_ci        decoratorName === '@BuilderParam')) {
57407ac75b1Sopenharmony_ci        const count: number = v2DecoratorMap.get(decoratorName) || 0;
57507ac75b1Sopenharmony_ci        v2DecoratorMap.set(decoratorName, count + 1);
57607ac75b1Sopenharmony_ci        return;
57707ac75b1Sopenharmony_ci      }
57807ac75b1Sopenharmony_ci      if (v1MethodDecorators.includes(decoratorName)) {
57907ac75b1Sopenharmony_ci        const count: number = v1DecoratorMap.get(decoratorName) || 0;
58007ac75b1Sopenharmony_ci        v1DecoratorMap.set(decoratorName, count + 1);
58107ac75b1Sopenharmony_ci        return;
58207ac75b1Sopenharmony_ci      }
58307ac75b1Sopenharmony_ci      if (decoratorName === COMPONENT_LOCAL_BUILDER_DECORATOR && decorators.length > 1) {
58407ac75b1Sopenharmony_ci        checkDecoratorCount = checkDecoratorCount + 1;
58507ac75b1Sopenharmony_ci        return;
58607ac75b1Sopenharmony_ci      }
58707ac75b1Sopenharmony_ci    });
58807ac75b1Sopenharmony_ci    const v2DecoratorMapKeys: string[] = Array.from(v2DecoratorMap.keys());
58907ac75b1Sopenharmony_ci    const v2DecoratorMapValues: number[] = Array.from(v2DecoratorMap.values());
59007ac75b1Sopenharmony_ci    const v1DecoratorMapKeys: string[] = Array.from(v1DecoratorMap.keys());
59107ac75b1Sopenharmony_ci    const v1DecoratorMapValues: number[] = Array.from(v1DecoratorMap.values());
59207ac75b1Sopenharmony_ci    innerDecoratorCount = v2DecoratorMapKeys.length + v1DecoratorMapKeys.length;
59307ac75b1Sopenharmony_ci    getMessageCollection().checkLocalBuilderDecoratorCount(node, sourceFileNode, checkDecoratorCount, log);
59407ac75b1Sopenharmony_ci    if (innerDecoratorCount > 1) {
59507ac75b1Sopenharmony_ci      const message: string = 'The member property or method can not be decorated by multiple built-in decorators.';
59607ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, node.getStart(), log, sourceFileNode);
59707ac75b1Sopenharmony_ci    }
59807ac75b1Sopenharmony_ci    const v2Duplicate: boolean = v2DecoratorMapValues.length &&
59907ac75b1Sopenharmony_ci      v2DecoratorMapValues.some((count: number) => count > 1);
60007ac75b1Sopenharmony_ci    const v1Duplicate: boolean = v1DecoratorMapValues.length &&
60107ac75b1Sopenharmony_ci      v1DecoratorMapValues.some((count: number) => count > 1);
60207ac75b1Sopenharmony_ci    const duplicateMessage: string = 'Duplicate decorators for method are not allowed.';
60307ac75b1Sopenharmony_ci    if (v2Duplicate || v1Duplicate) {
60407ac75b1Sopenharmony_ci      addLog(v1Duplicate ? LogType.WARN : LogType.ERROR, duplicateMessage, node.getStart(), log, sourceFileNode);
60507ac75b1Sopenharmony_ci    }
60607ac75b1Sopenharmony_ci  }
60707ac75b1Sopenharmony_ci}
60807ac75b1Sopenharmony_ci
60907ac75b1Sopenharmony_cifunction methodDecoratorCollect(node: ts.MethodDeclaration | ts.FunctionDeclaration): void {
61007ac75b1Sopenharmony_ci  const extendResult: ExtendResult = { decoratorName: '', componentName: '' };
61107ac75b1Sopenharmony_ci  const builderCondition: builderConditionType = {
61207ac75b1Sopenharmony_ci    isBuilder: false,
61307ac75b1Sopenharmony_ci    isLocalBuilder: false
61407ac75b1Sopenharmony_ci  };
61507ac75b1Sopenharmony_ci  if (isBuilderOrLocalBuilder(node, builderCondition)) {
61607ac75b1Sopenharmony_ci    if (builderCondition.isBuilder) {
61707ac75b1Sopenharmony_ci      CUSTOM_BUILDER_METHOD.add(node.name.getText());
61807ac75b1Sopenharmony_ci      if (ts.isFunctionDeclaration(node)) {
61907ac75b1Sopenharmony_ci        GLOBAL_CUSTOM_BUILDER_METHOD.add(node.name.getText());
62007ac75b1Sopenharmony_ci      } else {
62107ac75b1Sopenharmony_ci        INNER_CUSTOM_BUILDER_METHOD.add(node.name.getText());
62207ac75b1Sopenharmony_ci      }
62307ac75b1Sopenharmony_ci    } else if (builderCondition.isLocalBuilder) {
62407ac75b1Sopenharmony_ci      INNER_CUSTOM_LOCALBUILDER_METHOD.add(node.name.getText());
62507ac75b1Sopenharmony_ci    }
62607ac75b1Sopenharmony_ci  } else if (ts.isFunctionDeclaration(node) && isExtendFunction(node, extendResult)) {
62707ac75b1Sopenharmony_ci    if (extendResult.decoratorName === CHECK_COMPONENT_EXTEND_DECORATOR) {
62807ac75b1Sopenharmony_ci      collectExtend(EXTEND_ATTRIBUTE, extendResult.componentName, node.name.getText());
62907ac75b1Sopenharmony_ci    }
63007ac75b1Sopenharmony_ci    if (extendResult.decoratorName === CHECK_COMPONENT_ANIMATABLE_EXTEND_DECORATOR) {
63107ac75b1Sopenharmony_ci      collectExtend(storedFileInfo.getCurrentArkTsFile().animatableExtendAttribute,
63207ac75b1Sopenharmony_ci        extendResult.componentName, node.name.getText());
63307ac75b1Sopenharmony_ci    }
63407ac75b1Sopenharmony_ci  } else if (hasDecorator(node, COMPONENT_STYLES_DECORATOR)) {
63507ac75b1Sopenharmony_ci    collectStyles(node);
63607ac75b1Sopenharmony_ci  }
63707ac75b1Sopenharmony_ci}
63807ac75b1Sopenharmony_ci
63907ac75b1Sopenharmony_cifunction collectStyles(node: ts.FunctionLikeDeclarationBase): void {
64007ac75b1Sopenharmony_ci  if (ts.isBlock(node.body) && node.body.statements) {
64107ac75b1Sopenharmony_ci    if (ts.isFunctionDeclaration(node)) {
64207ac75b1Sopenharmony_ci      GLOBAL_STYLE_FUNCTION.set(node.name.getText(), node.body);
64307ac75b1Sopenharmony_ci    } else {
64407ac75b1Sopenharmony_ci      INNER_STYLE_FUNCTION.set(node.name.getText(), node.body);
64507ac75b1Sopenharmony_ci    }
64607ac75b1Sopenharmony_ci    STYLES_ATTRIBUTE.add(node.name.getText());
64707ac75b1Sopenharmony_ci    BUILDIN_STYLE_NAMES.add(node.name.getText());
64807ac75b1Sopenharmony_ci  }
64907ac75b1Sopenharmony_ci}
65007ac75b1Sopenharmony_ci
65107ac75b1Sopenharmony_cifunction validateFunction(node: ts.MethodDeclaration | ts.FunctionDeclaration,
65207ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
65307ac75b1Sopenharmony_ci  if (ts.isFunctionDeclaration(node)) {
65407ac75b1Sopenharmony_ci    const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
65507ac75b1Sopenharmony_ci    const decoratorMap: Map<string, number> = new Map<string, number>();
65607ac75b1Sopenharmony_ci    decorators.forEach((item: ts.Decorator) => {
65707ac75b1Sopenharmony_ci      const decoratorName: string = item.getText().replace(/\([^\(\)]*\)/, '')
65807ac75b1Sopenharmony_ci        .replace(/^@/, '').trim();
65907ac75b1Sopenharmony_ci      const count: number = decoratorMap.get(decoratorName) || 0;
66007ac75b1Sopenharmony_ci      decoratorMap.set(decoratorName, count + 1);
66107ac75b1Sopenharmony_ci    });
66207ac75b1Sopenharmony_ci    const decoratorValues: number[] = Array.from(decoratorMap.values());
66307ac75b1Sopenharmony_ci    const hasDuplicate: boolean = decoratorValues.length &&
66407ac75b1Sopenharmony_ci      decoratorValues.some((count: number) => count > 1);
66507ac75b1Sopenharmony_ci    if (hasDuplicate) {
66607ac75b1Sopenharmony_ci      const message: string = 'Duplicate decorators for function are not allowed.';
66707ac75b1Sopenharmony_ci      addLog(LogType.WARN, message, node.getStart(), log, sourceFileNode);
66807ac75b1Sopenharmony_ci    }
66907ac75b1Sopenharmony_ci    const decoratorKeys: string[] = Array.from(decoratorMap.keys());
67007ac75b1Sopenharmony_ci    if (decoratorKeys.length > 1 || decoratorKeys.includes('LocalBuilder')) {
67107ac75b1Sopenharmony_ci      const message: string = 'A function can only be decorated by one of the ' +
67207ac75b1Sopenharmony_ci        `'AnimatableExtend, Builder, Extend, Styles, Concurrent and Sendable'.`;
67307ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, node.getStart(), log, sourceFileNode);
67407ac75b1Sopenharmony_ci    }
67507ac75b1Sopenharmony_ci  }
67607ac75b1Sopenharmony_ci}
67707ac75b1Sopenharmony_ci
67807ac75b1Sopenharmony_cifunction checkDecorator(sourceFileNode: ts.SourceFile, node: ts.Node,
67907ac75b1Sopenharmony_ci  log: LogInfo[], structContext: boolean, classContext: boolean, isObservedClass: boolean,
68007ac75b1Sopenharmony_ci  isComponentV2: boolean, isObservedV1Class: boolean, isSendableClass: boolean): void {
68107ac75b1Sopenharmony_ci  if (ts.isIdentifier(node) && (ts.isDecorator(node.parent) ||
68207ac75b1Sopenharmony_ci    (ts.isCallExpression(node.parent) && ts.isDecorator(node.parent.parent)))) {
68307ac75b1Sopenharmony_ci    const decoratorName: string = node.escapedText.toString();
68407ac75b1Sopenharmony_ci    setLocalBuilderInFile(decoratorName);
68507ac75b1Sopenharmony_ci    validateStructDecorator(sourceFileNode, node, log, structContext, decoratorName, isComponentV2);
68607ac75b1Sopenharmony_ci    validateMethodDecorator(sourceFileNode, node, log, structContext, decoratorName);
68707ac75b1Sopenharmony_ci    validateClassDecorator(sourceFileNode, node, log, classContext, decoratorName, isObservedClass,
68807ac75b1Sopenharmony_ci      isObservedV1Class, isSendableClass);
68907ac75b1Sopenharmony_ci    validatePropertyInStruct(structContext, node, decoratorName, sourceFileNode, log);
69007ac75b1Sopenharmony_ci    return;
69107ac75b1Sopenharmony_ci  }
69207ac75b1Sopenharmony_ci  if (ts.isDecorator(node)) {
69307ac75b1Sopenharmony_ci    validateSingleDecorator(node, sourceFileNode, log, isComponentV2);
69407ac75b1Sopenharmony_ci  }
69507ac75b1Sopenharmony_ci}
69607ac75b1Sopenharmony_ci
69707ac75b1Sopenharmony_cifunction setLocalBuilderInFile(decoratorName: string): void {
69807ac75b1Sopenharmony_ci  if (decoratorName === 'LocalBuilder') {
69907ac75b1Sopenharmony_ci    storedFileInfo.hasLocalBuilderInFile = true;
70007ac75b1Sopenharmony_ci  }
70107ac75b1Sopenharmony_ci}
70207ac75b1Sopenharmony_ci
70307ac75b1Sopenharmony_cifunction validateSingleDecorator(node: ts.Decorator, sourceFileNode: ts.SourceFile,
70407ac75b1Sopenharmony_ci  log: LogInfo[], isComponentV2: boolean): void {
70507ac75b1Sopenharmony_ci  const decoratorName: string = node.getText().replace(/\([^\(\)]*\)/, '');
70607ac75b1Sopenharmony_ci  if (decoratorName === constantDefine.COMPUTED_DECORATOR && node.parent && !ts.isGetAccessor(node.parent)) {
70707ac75b1Sopenharmony_ci    const message: string = `@Computed can only decorate 'GetAccessor'.`;
70807ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.getStart(), log, sourceFileNode);
70907ac75b1Sopenharmony_ci    return;
71007ac75b1Sopenharmony_ci  }
71107ac75b1Sopenharmony_ci  const partialDecoratorCollection: string[] = [constantDefine.MONITOR_DECORATOR, COMPONENT_LOCAL_BUILDER_DECORATOR];
71207ac75b1Sopenharmony_ci  if (partialDecoratorCollection.includes(decoratorName) && node.parent &&
71307ac75b1Sopenharmony_ci    !ts.isMethodDeclaration(node.parent)) {
71407ac75b1Sopenharmony_ci    const message: string = `'${decoratorName}' can only decorate method.`;
71507ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.getStart(), log, sourceFileNode);
71607ac75b1Sopenharmony_ci    return;
71707ac75b1Sopenharmony_ci  }
71807ac75b1Sopenharmony_ci  if (isMemberForComponentV2(decoratorName, isComponentV2) && node.parent &&
71907ac75b1Sopenharmony_ci    !ts.isPropertyDeclaration(node.parent)) {
72007ac75b1Sopenharmony_ci    const message: string = `'${decoratorName}' can only decorate member property.`;
72107ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.getStart(), log, sourceFileNode);
72207ac75b1Sopenharmony_ci    return;
72307ac75b1Sopenharmony_ci  }
72407ac75b1Sopenharmony_ci}
72507ac75b1Sopenharmony_ci
72607ac75b1Sopenharmony_cifunction isMemberForComponentV2(decoratorName: string, isComponentV2: boolean): boolean {
72707ac75b1Sopenharmony_ci  return constantDefine.COMPONENT_MEMBER_DECORATOR_V2.includes(decoratorName) ||
72807ac75b1Sopenharmony_ci    (isComponentV2 && decoratorName === '@BuilderParam');
72907ac75b1Sopenharmony_ci}
73007ac75b1Sopenharmony_ci
73107ac75b1Sopenharmony_ciconst classDecorators: string[] = [CLASS_TRACK_DECORATOR, CLASS_MIN_TRACK_DECORATOR, MIN_OBSERVED];
73207ac75b1Sopenharmony_ciconst classMemberDecorators: string[] = [CLASS_TRACK_DECORATOR, CLASS_MIN_TRACK_DECORATOR, TYPE,
73307ac75b1Sopenharmony_ci  constantDefine.MONITOR, constantDefine.COMPUTED];
73407ac75b1Sopenharmony_ci
73507ac75b1Sopenharmony_cifunction validTypeCallback(node: ts.Identifier): boolean {
73607ac75b1Sopenharmony_ci  let isSdkPath: boolean = true;
73707ac75b1Sopenharmony_ci  if (globalProgram.checker && process.env.compileTool === 'rollup') {
73807ac75b1Sopenharmony_ci    const symbolObj: ts.Symbol = getSymbolIfAliased(node);
73907ac75b1Sopenharmony_ci    const fileName: string = symbolObj?.valueDeclaration?.getSourceFile()?.fileName;
74007ac75b1Sopenharmony_ci    isSdkPath = /@ohos.arkui.*/.test(fileName);
74107ac75b1Sopenharmony_ci  }
74207ac75b1Sopenharmony_ci  return isSdkPath;
74307ac75b1Sopenharmony_ci}
74407ac75b1Sopenharmony_ci
74507ac75b1Sopenharmony_cifunction isTypeFromSdkCallback(classContext: boolean, decoratorName: string, isTypeFromSdk: boolean): boolean {
74607ac75b1Sopenharmony_ci  if (!classContext && decoratorName === TYPE && isTypeFromSdk) {
74707ac75b1Sopenharmony_ci    return true;
74807ac75b1Sopenharmony_ci  }
74907ac75b1Sopenharmony_ci  return false;
75007ac75b1Sopenharmony_ci}
75107ac75b1Sopenharmony_ci
75207ac75b1Sopenharmony_cifunction validateClassDecorator(sourceFileNode: ts.SourceFile, node: ts.Identifier, log: LogInfo[],
75307ac75b1Sopenharmony_ci  classContext: boolean, decoratorName: string, isObservedClass: boolean, isObservedV1Class: boolean,
75407ac75b1Sopenharmony_ci  isSendableClass: boolean): void {
75507ac75b1Sopenharmony_ci  const isTypeFromSdk: boolean = validTypeCallback(node);
75607ac75b1Sopenharmony_ci  if (!classContext && (classDecorators.includes(decoratorName) || isTypeFromSdkCallback(classContext, decoratorName, isTypeFromSdk))) {
75707ac75b1Sopenharmony_ci    const message: string = `The '@${decoratorName}' decorator can only be used in 'class'.`;
75807ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
75907ac75b1Sopenharmony_ci  } else if (classContext && classMemberDecorators.includes(decoratorName)) {
76007ac75b1Sopenharmony_ci    validateMemberInClass(isObservedClass, decoratorName, node, log, sourceFileNode, isObservedV1Class, isSendableClass, isTypeFromSdk);
76107ac75b1Sopenharmony_ci  }
76207ac75b1Sopenharmony_ci}
76307ac75b1Sopenharmony_ci
76407ac75b1Sopenharmony_cifunction validateMemberInClass(isObservedClass: boolean, decoratorName: string, node: ts.Identifier,
76507ac75b1Sopenharmony_ci  log: LogInfo[], sourceFileNode: ts.SourceFile, isObservedV1Class: boolean, isSendableClass: boolean, isTypeFromSdk: boolean): void {
76607ac75b1Sopenharmony_ci  if (decoratorName === CLASS_TRACK_DECORATOR) {
76707ac75b1Sopenharmony_ci    if (isObservedClass) {
76807ac75b1Sopenharmony_ci      const message: string = `The '@${decoratorName}' decorator can not be used in a 'class' decorated with ObservedV2.`;
76907ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
77007ac75b1Sopenharmony_ci    }
77107ac75b1Sopenharmony_ci    return;
77207ac75b1Sopenharmony_ci  }
77307ac75b1Sopenharmony_ci  if (decoratorName === TYPE) {
77407ac75b1Sopenharmony_ci    if (isTypeFromSdk) {
77507ac75b1Sopenharmony_ci      validType(sourceFileNode, node, log, decoratorName, isObservedV1Class, isSendableClass);
77607ac75b1Sopenharmony_ci    }
77707ac75b1Sopenharmony_ci    return;
77807ac75b1Sopenharmony_ci  }
77907ac75b1Sopenharmony_ci  if (!isObservedClass || !isPropertyForTrace(node, decoratorName)) {
78007ac75b1Sopenharmony_ci    const info: string = decoratorName === CLASS_MIN_TRACK_DECORATOR ? 'variables' : 'method';
78107ac75b1Sopenharmony_ci    const message: string = `The '@${decoratorName}' can decorate only member ${info} within a 'class' decorated with ObservedV2.`;
78207ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
78307ac75b1Sopenharmony_ci    return;
78407ac75b1Sopenharmony_ci  }
78507ac75b1Sopenharmony_ci}
78607ac75b1Sopenharmony_ci
78707ac75b1Sopenharmony_cifunction validType(sourceFileNode: ts.SourceFile, node: ts.Identifier, log: LogInfo[], decoratorName: string,
78807ac75b1Sopenharmony_ci  isObservedV1Class: boolean, isSendableClass: boolean): void {
78907ac75b1Sopenharmony_ci  if (isSendableClass) {
79007ac75b1Sopenharmony_ci    const message: string = `The '@${decoratorName}' decorator can not be used in a 'class' decorated with Sendable.`;
79107ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
79207ac75b1Sopenharmony_ci  }
79307ac75b1Sopenharmony_ci  if (isObservedV1Class) {
79407ac75b1Sopenharmony_ci    const message: string = `The '@${decoratorName}' decorator can not be used in a 'class' decorated with Observed.`;
79507ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
79607ac75b1Sopenharmony_ci  }
79707ac75b1Sopenharmony_ci  if (ts.isDecorator(node.parent?.parent) && !ts.isPropertyDeclaration(node.parent?.parent?.parent)) {
79807ac75b1Sopenharmony_ci    const message: string = `The '@${decoratorName}' can decorate only member variables in a 'class'.`;
79907ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
80007ac75b1Sopenharmony_ci  }
80107ac75b1Sopenharmony_ci}
80207ac75b1Sopenharmony_ci
80307ac75b1Sopenharmony_cifunction isPropertyForTrace(node: ts.Identifier, decoratorName: string): boolean {
80407ac75b1Sopenharmony_ci  if (decoratorName === CLASS_MIN_TRACK_DECORATOR && ts.isDecorator(node.parent) &&
80507ac75b1Sopenharmony_ci    !ts.isPropertyDeclaration(node.parent.parent)) {
80607ac75b1Sopenharmony_ci    return false;
80707ac75b1Sopenharmony_ci  }
80807ac75b1Sopenharmony_ci  return true;
80907ac75b1Sopenharmony_ci}
81007ac75b1Sopenharmony_ci
81107ac75b1Sopenharmony_ciclass ClassDecoratorResult {
81207ac75b1Sopenharmony_ci  hasObserved: boolean = false;
81307ac75b1Sopenharmony_ci  hasObservedV2: boolean = false;
81407ac75b1Sopenharmony_ci  hasSendable: boolean = false;
81507ac75b1Sopenharmony_ci}
81607ac75b1Sopenharmony_ci
81707ac75b1Sopenharmony_cifunction parseClassDecorator(node: ts.ClassDeclaration, sourceFileNode: ts.SourceFile,
81807ac75b1Sopenharmony_ci  log: LogInfo[]): [boolean, boolean, boolean] {
81907ac75b1Sopenharmony_ci  const classResult: ClassDecoratorResult = getClassDecoratorResult(node);
82007ac75b1Sopenharmony_ci  validateMutilObserved(node, classResult, sourceFileNode, log);
82107ac75b1Sopenharmony_ci  if (classResult.hasObserved || classResult.hasObservedV2) {
82207ac75b1Sopenharmony_ci    parseInheritClass(node, classResult, sourceFileNode, log);
82307ac75b1Sopenharmony_ci  }
82407ac75b1Sopenharmony_ci  return [classResult.hasObserved, classResult.hasObservedV2, classResult.hasSendable];
82507ac75b1Sopenharmony_ci}
82607ac75b1Sopenharmony_ci
82707ac75b1Sopenharmony_cifunction getClassDecoratorResult(node: ts.ClassDeclaration): ClassDecoratorResult {
82807ac75b1Sopenharmony_ci  const classResult: ClassDecoratorResult = new ClassDecoratorResult();
82907ac75b1Sopenharmony_ci  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
83007ac75b1Sopenharmony_ci  decorators.forEach((item: ts.Decorator) => {
83107ac75b1Sopenharmony_ci    if (ts.isIdentifier(item.expression)) {
83207ac75b1Sopenharmony_ci      const decoratorName: string = item.expression.escapedText.toString();
83307ac75b1Sopenharmony_ci      switch (decoratorName) {
83407ac75b1Sopenharmony_ci        case MIN_OBSERVED:
83507ac75b1Sopenharmony_ci          classResult.hasObservedV2 = true;
83607ac75b1Sopenharmony_ci          break;
83707ac75b1Sopenharmony_ci        case OBSERVED:
83807ac75b1Sopenharmony_ci          classResult.hasObserved = true;
83907ac75b1Sopenharmony_ci          break;
84007ac75b1Sopenharmony_ci        case SENDABLE:
84107ac75b1Sopenharmony_ci          classResult.hasSendable = true;
84207ac75b1Sopenharmony_ci      }
84307ac75b1Sopenharmony_ci    }
84407ac75b1Sopenharmony_ci  });
84507ac75b1Sopenharmony_ci  return classResult;
84607ac75b1Sopenharmony_ci}
84707ac75b1Sopenharmony_ci
84807ac75b1Sopenharmony_cifunction validateMutilObserved(node: ts.ClassDeclaration, classResult: ClassDecoratorResult,
84907ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
85007ac75b1Sopenharmony_ci  if (classResult.hasObserved && classResult.hasObservedV2) {
85107ac75b1Sopenharmony_ci    const message: string = `A class can not be decorated by '@Observed' and '@ObservedV2' at the same time.`;
85207ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.getStart(), log, sourceFileNode);
85307ac75b1Sopenharmony_ci  }
85407ac75b1Sopenharmony_ci}
85507ac75b1Sopenharmony_ci
85607ac75b1Sopenharmony_cifunction parseInheritClass(node: ts.ClassDeclaration, childClassResult: ClassDecoratorResult,
85707ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
85807ac75b1Sopenharmony_ci  if (globalProgram.checker && process.env.compileTool === 'rollup' && node.heritageClauses) {
85907ac75b1Sopenharmony_ci    for (const heritageClause of node.heritageClauses) {
86007ac75b1Sopenharmony_ci      if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword && heritageClause.types &&
86107ac75b1Sopenharmony_ci        heritageClause.types.length) {
86207ac75b1Sopenharmony_ci        getClassNode(heritageClause.types[0].expression, childClassResult, node, sourceFileNode, log);
86307ac75b1Sopenharmony_ci      }
86407ac75b1Sopenharmony_ci    }
86507ac75b1Sopenharmony_ci  }
86607ac75b1Sopenharmony_ci}
86707ac75b1Sopenharmony_ci
86807ac75b1Sopenharmony_cifunction getClassNode(parentType: ts.Node, childClassResult: ClassDecoratorResult,
86907ac75b1Sopenharmony_ci  childClass: ts.ClassDeclaration, sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
87007ac75b1Sopenharmony_ci  const symbol: ts.Symbol = parentType && getSymbolIfAliased(parentType);
87107ac75b1Sopenharmony_ci  if (symbol && symbol.valueDeclaration) {
87207ac75b1Sopenharmony_ci    if (ts.isClassDeclaration(symbol.valueDeclaration)) {
87307ac75b1Sopenharmony_ci      validateInheritClassDecorator(symbol.valueDeclaration, childClassResult, childClass, sourceFileNode, log);
87407ac75b1Sopenharmony_ci      return;
87507ac75b1Sopenharmony_ci    }
87607ac75b1Sopenharmony_ci    if (ts.isPropertyAssignment(symbol.valueDeclaration)) {
87707ac75b1Sopenharmony_ci      getClassNode(symbol.valueDeclaration.initializer, childClassResult, childClass, sourceFileNode, log);
87807ac75b1Sopenharmony_ci      return;
87907ac75b1Sopenharmony_ci    }
88007ac75b1Sopenharmony_ci    if (ts.isShorthandPropertyAssignment(symbol.valueDeclaration)) {
88107ac75b1Sopenharmony_ci      parseShorthandPropertyForClass(symbol.valueDeclaration, childClassResult, childClass, sourceFileNode, log);
88207ac75b1Sopenharmony_ci      return;
88307ac75b1Sopenharmony_ci    }
88407ac75b1Sopenharmony_ci  }
88507ac75b1Sopenharmony_ci}
88607ac75b1Sopenharmony_ci
88707ac75b1Sopenharmony_cifunction parseShorthandPropertyForClass(node: ts.ShorthandPropertyAssignment, childClassResult: ClassDecoratorResult,
88807ac75b1Sopenharmony_ci  childClass: ts.ClassDeclaration, sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
88907ac75b1Sopenharmony_ci  const shortSymbol: ts.Symbol = globalProgram.checker.getShorthandAssignmentValueSymbol(node);
89007ac75b1Sopenharmony_ci  if (shortSymbol && shortSymbol.valueDeclaration && ts.isClassDeclaration(shortSymbol.valueDeclaration)) {
89107ac75b1Sopenharmony_ci    validateInheritClassDecorator(shortSymbol.valueDeclaration, childClassResult, childClass, sourceFileNode, log);
89207ac75b1Sopenharmony_ci  }
89307ac75b1Sopenharmony_ci}
89407ac75b1Sopenharmony_ci
89507ac75b1Sopenharmony_cifunction getSymbolIfAliased(node: ts.Node): ts.Symbol {
89607ac75b1Sopenharmony_ci  const symbol: ts.Symbol = globalProgram.checker.getSymbolAtLocation(node);
89707ac75b1Sopenharmony_ci  if (symbol && (symbol.getFlags() & ts.SymbolFlags.Alias) !== 0) {
89807ac75b1Sopenharmony_ci    return globalProgram.checker.getAliasedSymbol(symbol);
89907ac75b1Sopenharmony_ci  }
90007ac75b1Sopenharmony_ci  return symbol;
90107ac75b1Sopenharmony_ci}
90207ac75b1Sopenharmony_ci
90307ac75b1Sopenharmony_cifunction validateInheritClassDecorator(parentNode: ts.ClassDeclaration, childClassResult: ClassDecoratorResult,
90407ac75b1Sopenharmony_ci  childClass: ts.ClassDeclaration, sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
90507ac75b1Sopenharmony_ci  const parentClassResult: ClassDecoratorResult = getClassDecoratorResult(parentNode);
90607ac75b1Sopenharmony_ci  if (childClassResult.hasObservedV2 && parentClassResult.hasObserved) {
90707ac75b1Sopenharmony_ci    const message: string = `Because the current class is decorated by '@ObservedV2', ` +
90807ac75b1Sopenharmony_ci      `it can not inherit a class decorated by '@Observed'.`;
90907ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, childClass.getStart(), log, sourceFileNode);
91007ac75b1Sopenharmony_ci    return;
91107ac75b1Sopenharmony_ci  }
91207ac75b1Sopenharmony_ci  if (childClassResult.hasObserved && parentClassResult.hasObservedV2) {
91307ac75b1Sopenharmony_ci    const message: string = `Because the current class is decorated by '@Observed', ` +
91407ac75b1Sopenharmony_ci      `it can not inherit a class decorated by '@ObservedV2'.`;
91507ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, childClass.getStart(), log, sourceFileNode);
91607ac75b1Sopenharmony_ci    return;
91707ac75b1Sopenharmony_ci  }
91807ac75b1Sopenharmony_ci}
91907ac75b1Sopenharmony_ci
92007ac75b1Sopenharmony_cifunction validateStructDecorator(sourceFileNode: ts.SourceFile, node: ts.Identifier, log: LogInfo[],
92107ac75b1Sopenharmony_ci  structContext: boolean, decoratorName: string, isComponentV2: boolean): void {
92207ac75b1Sopenharmony_ci  const name: string = `@${decoratorName}`;
92307ac75b1Sopenharmony_ci  if (structContext) {
92407ac75b1Sopenharmony_ci    if (isComponentV2) {
92507ac75b1Sopenharmony_ci      if (constantDefine.COMPONENT_MEMBER_DECORATOR_V1.includes(name)) {
92607ac75b1Sopenharmony_ci        const message: string = `The '@${decoratorName}' decorator can only be used in a 'struct' decorated with '@Component'.`;
92707ac75b1Sopenharmony_ci        addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
92807ac75b1Sopenharmony_ci      }
92907ac75b1Sopenharmony_ci    } else if (constantDefine.DECORATOR_V2.includes(name)) {
93007ac75b1Sopenharmony_ci      const message: string = `The '@${decoratorName}' decorator can only be used in a 'struct' decorated with '@ComponentV2'.`;
93107ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
93207ac75b1Sopenharmony_ci    }
93307ac75b1Sopenharmony_ci  } else if (STRUCT_DECORATORS.has(name) || constantDefine.COMPONENT_MEMBER_DECORATOR_V2.includes(name)) {
93407ac75b1Sopenharmony_ci    const message: string = `The '@${decoratorName}' decorator can only be used with 'struct'.`;
93507ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
93607ac75b1Sopenharmony_ci  }
93707ac75b1Sopenharmony_ci}
93807ac75b1Sopenharmony_ci
93907ac75b1Sopenharmony_cifunction validateMethodDecorator(sourceFileNode: ts.SourceFile, node: ts.Identifier, log: LogInfo[],
94007ac75b1Sopenharmony_ci  structContext: boolean, decoratorName: string): void {
94107ac75b1Sopenharmony_ci  let message: string;
94207ac75b1Sopenharmony_ci  if (ts.isMethodDeclaration(node.parent.parent) ||
94307ac75b1Sopenharmony_ci    (ts.isDecorator(node.parent.parent) && ts.isMethodDeclaration(node.parent.parent.parent))) {
94407ac75b1Sopenharmony_ci    if (!structContext && STRUCT_CONTEXT_METHOD_DECORATORS.has(`@${decoratorName}`)) {
94507ac75b1Sopenharmony_ci      message = `The '@${decoratorName}' decorator can only be used in 'struct'.`;
94607ac75b1Sopenharmony_ci    }
94707ac75b1Sopenharmony_ci    if (CHECK_EXTEND_DECORATORS.includes(decoratorName)) {
94807ac75b1Sopenharmony_ci      message = `The '@${decoratorName}' decorator can not be a member property method of a 'class' or 'struct'.`;
94907ac75b1Sopenharmony_ci    }
95007ac75b1Sopenharmony_ci    if (message) {
95107ac75b1Sopenharmony_ci      addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
95207ac75b1Sopenharmony_ci    }
95307ac75b1Sopenharmony_ci  }
95407ac75b1Sopenharmony_ci}
95507ac75b1Sopenharmony_ci
95607ac75b1Sopenharmony_ciexport function isSendableClassDeclaration(classDeclarationNode: ts.ClassDeclaration): boolean {
95707ac75b1Sopenharmony_ci  return hasDecorator(classDeclarationNode, COMPONENT_SENDABLE_DECORATOR) ||
95807ac75b1Sopenharmony_ci      (classDeclarationNode.members && classDeclarationNode.members.some((member: ts.Node) => {
95907ac75b1Sopenharmony_ci        // Check if the constructor has "use sendable" as the first statement
96007ac75b1Sopenharmony_ci        // (Sendable classes already transformed by process_ui_syntax.ts)
96107ac75b1Sopenharmony_ci        if (ts.isConstructorDeclaration(member)) {
96207ac75b1Sopenharmony_ci          if (!(member as ts.ConstructorDeclaration).body ||
96307ac75b1Sopenharmony_ci              !(member as ts.ConstructorDeclaration).body.statements) {
96407ac75b1Sopenharmony_ci            return false;
96507ac75b1Sopenharmony_ci          }
96607ac75b1Sopenharmony_ci          const constructorStatements: ts.Statement[] = (member as ts.ConstructorDeclaration).body.statements;
96707ac75b1Sopenharmony_ci          if (constructorStatements && constructorStatements[0] &&
96807ac75b1Sopenharmony_ci              ts.isExpressionStatement(constructorStatements[0])) {
96907ac75b1Sopenharmony_ci            const expression: ts.Node = (constructorStatements[0] as ts.ExpressionStatement).expression;
97007ac75b1Sopenharmony_ci            return expression && ts.isStringLiteral(expression) &&
97107ac75b1Sopenharmony_ci                (expression as ts.StringLiteral).text === 'use sendable';
97207ac75b1Sopenharmony_ci          }
97307ac75b1Sopenharmony_ci        }
97407ac75b1Sopenharmony_ci        return false;
97507ac75b1Sopenharmony_ci      }));
97607ac75b1Sopenharmony_ci}
97707ac75b1Sopenharmony_ci
97807ac75b1Sopenharmony_ciexport function checkAllNode(
97907ac75b1Sopenharmony_ci  node: ts.EtsComponentExpression,
98007ac75b1Sopenharmony_ci  allComponentNames: Set<string>,
98107ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile,
98207ac75b1Sopenharmony_ci  log: LogInfo[]
98307ac75b1Sopenharmony_ci): void {
98407ac75b1Sopenharmony_ci  if (ts.isIdentifier(node.expression)) {
98507ac75b1Sopenharmony_ci    checkNoChildComponent(node, sourceFileNode, log);
98607ac75b1Sopenharmony_ci    checkOneChildComponent(node, allComponentNames, sourceFileNode, log);
98707ac75b1Sopenharmony_ci    checkSpecificChildComponent(node, allComponentNames, sourceFileNode, log);
98807ac75b1Sopenharmony_ci  }
98907ac75b1Sopenharmony_ci}
99007ac75b1Sopenharmony_ci
99107ac75b1Sopenharmony_ciinterface ParamType {
99207ac75b1Sopenharmony_ci  name: string,
99307ac75b1Sopenharmony_ci  value: string,
99407ac75b1Sopenharmony_ci}
99507ac75b1Sopenharmony_ci
99607ac75b1Sopenharmony_cifunction checkNoChildComponent(node: ts.EtsComponentExpression, sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
99707ac75b1Sopenharmony_ci  const isCheckType: ParamType = { name: null, value: null};
99807ac75b1Sopenharmony_ci  if (hasChild(node, isCheckType)) {
99907ac75b1Sopenharmony_ci    const componentName: string = (node.expression as ts.Identifier).escapedText.toString();
100007ac75b1Sopenharmony_ci    const pos: number = node.expression.getStart();
100107ac75b1Sopenharmony_ci    const message: string = isCheckType.name === null ?
100207ac75b1Sopenharmony_ci      `The component '${componentName}' can't have any child.` :
100307ac75b1Sopenharmony_ci      `When the component '${componentName}' set '${isCheckType.name}' is '${isCheckType.value}'` +
100407ac75b1Sopenharmony_ci        `, can't have any child.`;
100507ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, pos, log, sourceFileNode);
100607ac75b1Sopenharmony_ci  }
100707ac75b1Sopenharmony_ci}
100807ac75b1Sopenharmony_ci
100907ac75b1Sopenharmony_cifunction hasChild(node: ts.EtsComponentExpression, isCheckType: ParamType): boolean {
101007ac75b1Sopenharmony_ci  const nodeName: ts.Identifier = node.expression as ts.Identifier;
101107ac75b1Sopenharmony_ci  if ((AUTOMIC_COMPONENT.has(nodeName.escapedText.toString()) || judgeComponentType(nodeName, node, isCheckType)) &&
101207ac75b1Sopenharmony_ci    getNextNode(node)) {
101307ac75b1Sopenharmony_ci    return true;
101407ac75b1Sopenharmony_ci  }
101507ac75b1Sopenharmony_ci  return false;
101607ac75b1Sopenharmony_ci}
101707ac75b1Sopenharmony_ci
101807ac75b1Sopenharmony_cifunction judgeComponentType(nodeName: ts.Identifier, etsComponentExpression: ts.EtsComponentExpression,
101907ac75b1Sopenharmony_ci  isCheckType: ParamType): boolean {
102007ac75b1Sopenharmony_ci  return COMPONENT_TOGGLE === nodeName.escapedText.toString() &&
102107ac75b1Sopenharmony_ci    etsComponentExpression.arguments && etsComponentExpression.arguments[0] &&
102207ac75b1Sopenharmony_ci    ts.isObjectLiteralExpression(etsComponentExpression.arguments[0]) &&
102307ac75b1Sopenharmony_ci    etsComponentExpression.arguments[0].getText() &&
102407ac75b1Sopenharmony_ci    judgeToggleComponentParamType(etsComponentExpression.arguments[0].getText(), isCheckType);
102507ac75b1Sopenharmony_ci}
102607ac75b1Sopenharmony_ci
102707ac75b1Sopenharmony_cifunction judgeToggleComponentParamType(param: string, isCheckType: ParamType): boolean {
102807ac75b1Sopenharmony_ci  if (param.indexOf(RESOURCE_NAME_TYPE) > -1) {
102907ac75b1Sopenharmony_ci    isCheckType.name = RESOURCE_NAME_TYPE;
103007ac75b1Sopenharmony_ci    const match: string[] = param.match(/\b(Checkbox|Switch|Button)\b/);
103107ac75b1Sopenharmony_ci    if (match && match.length) {
103207ac75b1Sopenharmony_ci      isCheckType.value = match[0];
103307ac75b1Sopenharmony_ci      if (isCheckType.value === COMPONENT_BUTTON) {
103407ac75b1Sopenharmony_ci        return false;
103507ac75b1Sopenharmony_ci      }
103607ac75b1Sopenharmony_ci      return true;
103707ac75b1Sopenharmony_ci    }
103807ac75b1Sopenharmony_ci  }
103907ac75b1Sopenharmony_ci  return false;
104007ac75b1Sopenharmony_ci}
104107ac75b1Sopenharmony_ci
104207ac75b1Sopenharmony_cifunction getNextNode(node: ts.EtsComponentExpression): ts.Block {
104307ac75b1Sopenharmony_ci  if (node.body && ts.isBlock(node.body)) {
104407ac75b1Sopenharmony_ci    const statementsArray: ts.Block = node.body;
104507ac75b1Sopenharmony_ci    return statementsArray;
104607ac75b1Sopenharmony_ci  }
104707ac75b1Sopenharmony_ci  return undefined;
104807ac75b1Sopenharmony_ci}
104907ac75b1Sopenharmony_ci
105007ac75b1Sopenharmony_cifunction checkOneChildComponent(node: ts.EtsComponentExpression, allComponentNames: Set<string>,
105107ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
105207ac75b1Sopenharmony_ci  const isCheckType: ParamType = { name: null, value: null};
105307ac75b1Sopenharmony_ci  if (hasNonSingleChild(node, allComponentNames, isCheckType)) {
105407ac75b1Sopenharmony_ci    const componentName: string = (node.expression as ts.Identifier).escapedText.toString();
105507ac75b1Sopenharmony_ci    const pos: number = node.expression.getStart();
105607ac75b1Sopenharmony_ci    const message: string = isCheckType.name === null ?
105707ac75b1Sopenharmony_ci      `The component '${componentName}' can only have a single child component.` :
105807ac75b1Sopenharmony_ci      `When the component '${componentName}' set '${isCheckType.name}' is ` +
105907ac75b1Sopenharmony_ci        `'${isCheckType.value}', can only have a single child component.`;
106007ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, pos, log, sourceFileNode);
106107ac75b1Sopenharmony_ci  }
106207ac75b1Sopenharmony_ci}
106307ac75b1Sopenharmony_ci
106407ac75b1Sopenharmony_cifunction hasNonSingleChild(node: ts.EtsComponentExpression, allComponentNames: Set<string>,
106507ac75b1Sopenharmony_ci  isCheckType: ParamType): boolean {
106607ac75b1Sopenharmony_ci  const nodeName: ts.Identifier = node.expression as ts.Identifier;
106707ac75b1Sopenharmony_ci  const blockNode: ts.Block = getNextNode(node);
106807ac75b1Sopenharmony_ci  if (SINGLE_CHILD_COMPONENT.has(nodeName.escapedText.toString()) || !judgeComponentType(nodeName, node, isCheckType) &&
106907ac75b1Sopenharmony_ci    isCheckType.value === COMPONENT_BUTTON) {
107007ac75b1Sopenharmony_ci    if (!blockNode) {
107107ac75b1Sopenharmony_ci      return false;
107207ac75b1Sopenharmony_ci    }
107307ac75b1Sopenharmony_ci    if (blockNode && blockNode.statements) {
107407ac75b1Sopenharmony_ci      const length: number = blockNode.statements.length;
107507ac75b1Sopenharmony_ci      if (!length) {
107607ac75b1Sopenharmony_ci        return false;
107707ac75b1Sopenharmony_ci      }
107807ac75b1Sopenharmony_ci      if (length > 3) {
107907ac75b1Sopenharmony_ci        return true;
108007ac75b1Sopenharmony_ci      }
108107ac75b1Sopenharmony_ci      const childCount: number = getBlockChildrenCount(blockNode, allComponentNames);
108207ac75b1Sopenharmony_ci      if (childCount > 1) {
108307ac75b1Sopenharmony_ci        return true;
108407ac75b1Sopenharmony_ci      }
108507ac75b1Sopenharmony_ci    }
108607ac75b1Sopenharmony_ci  }
108707ac75b1Sopenharmony_ci  return false;
108807ac75b1Sopenharmony_ci}
108907ac75b1Sopenharmony_ci
109007ac75b1Sopenharmony_cifunction getBlockChildrenCount(blockNode: ts.Block, allComponentNames: Set<string>): number {
109107ac75b1Sopenharmony_ci  let maxCount: number = 0;
109207ac75b1Sopenharmony_ci  const length: number = blockNode.statements.length;
109307ac75b1Sopenharmony_ci  for (let i = 0; i < length; ++i) {
109407ac75b1Sopenharmony_ci    const item: ts.Node = blockNode.statements[i];
109507ac75b1Sopenharmony_ci    if (ts.isExpressionStatement(item) && ts.isCallExpression(item.expression) &&
109607ac75b1Sopenharmony_ci      isForEachComponent(item.expression)) {
109707ac75b1Sopenharmony_ci      maxCount += 2;
109807ac75b1Sopenharmony_ci    }
109907ac75b1Sopenharmony_ci    if (ts.isIfStatement(item)) {
110007ac75b1Sopenharmony_ci      maxCount += getIfChildrenCount(item, allComponentNames);
110107ac75b1Sopenharmony_ci    }
110207ac75b1Sopenharmony_ci    if (ts.isExpressionStatement(item) && ts.isEtsComponentExpression(item.expression)) {
110307ac75b1Sopenharmony_ci      maxCount += 1;
110407ac75b1Sopenharmony_ci    }
110507ac75b1Sopenharmony_ci    if (ts.isExpressionStatement(item) && ts.isCallExpression(item.expression)) {
110607ac75b1Sopenharmony_ci      let newNode = item.expression;
110707ac75b1Sopenharmony_ci      while (newNode.expression) {
110807ac75b1Sopenharmony_ci        if (ts.isEtsComponentExpression(newNode) || ts.isCallExpression(newNode) &&
110907ac75b1Sopenharmony_ci          isComponent(newNode, allComponentNames)) {
111007ac75b1Sopenharmony_ci          maxCount += 1;
111107ac75b1Sopenharmony_ci        }
111207ac75b1Sopenharmony_ci        newNode = newNode.expression;
111307ac75b1Sopenharmony_ci      }
111407ac75b1Sopenharmony_ci    }
111507ac75b1Sopenharmony_ci    if (maxCount > 1) {
111607ac75b1Sopenharmony_ci      break;
111707ac75b1Sopenharmony_ci    }
111807ac75b1Sopenharmony_ci  }
111907ac75b1Sopenharmony_ci  return maxCount;
112007ac75b1Sopenharmony_ci}
112107ac75b1Sopenharmony_ci
112207ac75b1Sopenharmony_cifunction isComponent(node: ts.EtsComponentExpression | ts.CallExpression, allComponentNames: Set<string>): boolean {
112307ac75b1Sopenharmony_ci  if (ts.isIdentifier(node.expression) &&
112407ac75b1Sopenharmony_ci    allComponentNames.has(node.expression.escapedText.toString())) {
112507ac75b1Sopenharmony_ci    return true;
112607ac75b1Sopenharmony_ci  }
112707ac75b1Sopenharmony_ci  return false;
112807ac75b1Sopenharmony_ci}
112907ac75b1Sopenharmony_ci
113007ac75b1Sopenharmony_cifunction isForEachComponent(node: ts.EtsComponentExpression | ts.CallExpression): boolean {
113107ac75b1Sopenharmony_ci  if (ts.isIdentifier(node.expression)) {
113207ac75b1Sopenharmony_ci    const componentName: string = node.expression.escapedText.toString();
113307ac75b1Sopenharmony_ci    return componentName === COMPONENT_FOREACH || componentName === COMPONENT_LAZYFOREACH;
113407ac75b1Sopenharmony_ci  }
113507ac75b1Sopenharmony_ci  return false;
113607ac75b1Sopenharmony_ci}
113707ac75b1Sopenharmony_ci
113807ac75b1Sopenharmony_cifunction getIfChildrenCount(ifNode: ts.IfStatement, allComponentNames: Set<string>): number {
113907ac75b1Sopenharmony_ci  const maxCount: number =
114007ac75b1Sopenharmony_ci    Math.max(getStatementCount(ifNode.thenStatement, allComponentNames),
114107ac75b1Sopenharmony_ci      getStatementCount(ifNode.elseStatement, allComponentNames));
114207ac75b1Sopenharmony_ci  return maxCount;
114307ac75b1Sopenharmony_ci}
114407ac75b1Sopenharmony_ci
114507ac75b1Sopenharmony_cifunction getStatementCount(node: ts.Node, allComponentNames: Set<string>): number {
114607ac75b1Sopenharmony_ci  let maxCount: number = 0;
114707ac75b1Sopenharmony_ci  if (!node) {
114807ac75b1Sopenharmony_ci    return maxCount;
114907ac75b1Sopenharmony_ci  } else if (ts.isBlock(node)) {
115007ac75b1Sopenharmony_ci    maxCount = getBlockChildrenCount(node, allComponentNames);
115107ac75b1Sopenharmony_ci  } else if (ts.isIfStatement(node)) {
115207ac75b1Sopenharmony_ci    maxCount = getIfChildrenCount(node, allComponentNames);
115307ac75b1Sopenharmony_ci  } else if (ts.isExpressionStatement(node) && ts.isEtsComponentExpression(node.expression) &&
115407ac75b1Sopenharmony_ci    isForEachComponent(node.expression)) {
115507ac75b1Sopenharmony_ci    maxCount = 2;
115607ac75b1Sopenharmony_ci  } else if (ts.isExpressionStatement(node) && ts.isEtsComponentExpression(node.expression) &&
115707ac75b1Sopenharmony_ci    !isForEachComponent(node.expression) && isComponent(node.expression, allComponentNames)) {
115807ac75b1Sopenharmony_ci    maxCount = 1;
115907ac75b1Sopenharmony_ci  }
116007ac75b1Sopenharmony_ci  return maxCount;
116107ac75b1Sopenharmony_ci}
116207ac75b1Sopenharmony_ci
116307ac75b1Sopenharmony_cifunction checkSpecificChildComponent(node: ts.EtsComponentExpression, allComponentNames: Set<string>,
116407ac75b1Sopenharmony_ci  sourceFileNode: ts.SourceFile, log: LogInfo[]): void {
116507ac75b1Sopenharmony_ci  if (hasNonspecificChild(node, allComponentNames)) {
116607ac75b1Sopenharmony_ci    const componentName: string = (node.expression as ts.Identifier).escapedText.toString();
116707ac75b1Sopenharmony_ci    const pos: number = node.expression.getStart();
116807ac75b1Sopenharmony_ci    const specificChildArray: string =
116907ac75b1Sopenharmony_ci      Array.from(SPECIFIC_CHILD_COMPONENT.get(componentName)).join(' and ');
117007ac75b1Sopenharmony_ci    const message: string =
117107ac75b1Sopenharmony_ci      `The component '${componentName}' can only have the child component ${specificChildArray}.`;
117207ac75b1Sopenharmony_ci    addLog(LogType.ERROR, message, pos, log, sourceFileNode);
117307ac75b1Sopenharmony_ci  }
117407ac75b1Sopenharmony_ci}
117507ac75b1Sopenharmony_ci
117607ac75b1Sopenharmony_cifunction hasNonspecificChild(node: ts.EtsComponentExpression,
117707ac75b1Sopenharmony_ci  allComponentNames: Set<string>): boolean {
117807ac75b1Sopenharmony_ci  const nodeName: ts.Identifier = node.expression as ts.Identifier;
117907ac75b1Sopenharmony_ci  const nodeNameString: string = nodeName.escapedText.toString();
118007ac75b1Sopenharmony_ci  const blockNode: ts.Block = getNextNode(node);
118107ac75b1Sopenharmony_ci  let isNonspecific: boolean = false;
118207ac75b1Sopenharmony_ci  if (SPECIFIC_CHILD_COMPONENT.has(nodeNameString) && blockNode) {
118307ac75b1Sopenharmony_ci    const specificChildSet: Set<string> = SPECIFIC_CHILD_COMPONENT.get(nodeNameString);
118407ac75b1Sopenharmony_ci    isNonspecific = isNonspecificChildBlock(blockNode, specificChildSet, allComponentNames);
118507ac75b1Sopenharmony_ci    if (isNonspecific) {
118607ac75b1Sopenharmony_ci      return isNonspecific;
118707ac75b1Sopenharmony_ci    }
118807ac75b1Sopenharmony_ci  }
118907ac75b1Sopenharmony_ci  return isNonspecific;
119007ac75b1Sopenharmony_ci}
119107ac75b1Sopenharmony_ci
119207ac75b1Sopenharmony_cifunction isNonspecificChildBlock(blockNode: ts.Block, specificChildSet: Set<string>,
119307ac75b1Sopenharmony_ci  allComponentNames: Set<string>): boolean {
119407ac75b1Sopenharmony_ci  if (blockNode.statements) {
119507ac75b1Sopenharmony_ci    const length: number = blockNode.statements.length;
119607ac75b1Sopenharmony_ci    for (let i = 0; i < length; ++i) {
119707ac75b1Sopenharmony_ci      const item: ts.Node = blockNode.statements[i];
119807ac75b1Sopenharmony_ci      if (ts.isIfStatement(item) && isNonspecificChildIf(item, specificChildSet, allComponentNames)) {
119907ac75b1Sopenharmony_ci        return true;
120007ac75b1Sopenharmony_ci      }
120107ac75b1Sopenharmony_ci      if (ts.isExpressionStatement(item) && ts.isCallExpression(item.expression) &&
120207ac75b1Sopenharmony_ci        isForEachComponent(item.expression) &&
120307ac75b1Sopenharmony_ci        isNonspecificChildForEach(item.expression, specificChildSet, allComponentNames)) {
120407ac75b1Sopenharmony_ci        return true;
120507ac75b1Sopenharmony_ci      }
120607ac75b1Sopenharmony_ci      if (ts.isBlock(item) && isNonspecificChildBlock(item, specificChildSet, allComponentNames)) {
120707ac75b1Sopenharmony_ci        return true;
120807ac75b1Sopenharmony_ci      }
120907ac75b1Sopenharmony_ci      if (ts.isExpressionStatement(item)) {
121007ac75b1Sopenharmony_ci        let newNode: any = item.expression;
121107ac75b1Sopenharmony_ci        while (newNode.expression) {
121207ac75b1Sopenharmony_ci          if (ts.isEtsComponentExpression(newNode) && ts.isIdentifier(newNode.expression) &&
121307ac75b1Sopenharmony_ci          !isForEachComponent(newNode) && isComponent(newNode, allComponentNames)) {
121407ac75b1Sopenharmony_ci            const isNonspecific: boolean =
121507ac75b1Sopenharmony_ci            isNonspecificChildNonForEach(newNode, specificChildSet);
121607ac75b1Sopenharmony_ci            if (isNonspecific) {
121707ac75b1Sopenharmony_ci              return isNonspecific;
121807ac75b1Sopenharmony_ci            }
121907ac75b1Sopenharmony_ci            if (i + 1 < length && ts.isBlock(blockNode.statements[i + 1])) {
122007ac75b1Sopenharmony_ci              ++i;
122107ac75b1Sopenharmony_ci            }
122207ac75b1Sopenharmony_ci          }
122307ac75b1Sopenharmony_ci          newNode = newNode.expression;
122407ac75b1Sopenharmony_ci        }
122507ac75b1Sopenharmony_ci      }
122607ac75b1Sopenharmony_ci    }
122707ac75b1Sopenharmony_ci  }
122807ac75b1Sopenharmony_ci  return false;
122907ac75b1Sopenharmony_ci}
123007ac75b1Sopenharmony_ci
123107ac75b1Sopenharmony_cifunction isNonspecificChildIf(node: ts.IfStatement, specificChildSet: Set<string>,
123207ac75b1Sopenharmony_ci  allComponentNames: Set<string>): boolean {
123307ac75b1Sopenharmony_ci  return isNonspecificChildIfStatement(node.thenStatement, specificChildSet, allComponentNames) ||
123407ac75b1Sopenharmony_ci    isNonspecificChildIfStatement(node.elseStatement, specificChildSet, allComponentNames);
123507ac75b1Sopenharmony_ci}
123607ac75b1Sopenharmony_ci
123707ac75b1Sopenharmony_cifunction isNonspecificChildForEach(node: ts.EtsComponentExpression, specificChildSet: Set<string>,
123807ac75b1Sopenharmony_ci  allComponentNames: Set<string>): boolean {
123907ac75b1Sopenharmony_ci  if (ts.isCallExpression(node) && node.arguments &&
124007ac75b1Sopenharmony_ci    node.arguments.length > 1 && ts.isArrowFunction(node.arguments[1])) {
124107ac75b1Sopenharmony_ci    const arrowFunction: ts.ArrowFunction = node.arguments[1] as ts.ArrowFunction;
124207ac75b1Sopenharmony_ci    const body: ts.Block | ts.EtsComponentExpression | ts.IfStatement =
124307ac75b1Sopenharmony_ci      arrowFunction.body as ts.Block | ts.EtsComponentExpression | ts.IfStatement;
124407ac75b1Sopenharmony_ci    if (!body) {
124507ac75b1Sopenharmony_ci      return false;
124607ac75b1Sopenharmony_ci    }
124707ac75b1Sopenharmony_ci    if (ts.isBlock(body) && isNonspecificChildBlock(body, specificChildSet, allComponentNames)) {
124807ac75b1Sopenharmony_ci      return true;
124907ac75b1Sopenharmony_ci    }
125007ac75b1Sopenharmony_ci    if (ts.isIfStatement(body) && isNonspecificChildIf(body, specificChildSet, allComponentNames)) {
125107ac75b1Sopenharmony_ci      return true;
125207ac75b1Sopenharmony_ci    }
125307ac75b1Sopenharmony_ci    if (ts.isCallExpression(body) && isForEachComponent(body) &&
125407ac75b1Sopenharmony_ci      isNonspecificChildForEach(body, specificChildSet, allComponentNames)) {
125507ac75b1Sopenharmony_ci      return true;
125607ac75b1Sopenharmony_ci    }
125707ac75b1Sopenharmony_ci    if (ts.isEtsComponentExpression(body) && !isForEachComponent(body) &&
125807ac75b1Sopenharmony_ci      isComponent(body, allComponentNames) &&
125907ac75b1Sopenharmony_ci      isNonspecificChildNonForEach(body, specificChildSet)) {
126007ac75b1Sopenharmony_ci      return true;
126107ac75b1Sopenharmony_ci    }
126207ac75b1Sopenharmony_ci  }
126307ac75b1Sopenharmony_ci  return false;
126407ac75b1Sopenharmony_ci}
126507ac75b1Sopenharmony_ci
126607ac75b1Sopenharmony_cifunction isNonspecificChildNonForEach(node: ts.EtsComponentExpression,
126707ac75b1Sopenharmony_ci  specificChildSet: Set<string>): boolean {
126807ac75b1Sopenharmony_ci  if (ts.isIdentifier(node.expression) &&
126907ac75b1Sopenharmony_ci    !specificChildSet.has(node.expression.escapedText.toString())) {
127007ac75b1Sopenharmony_ci    return true;
127107ac75b1Sopenharmony_ci  }
127207ac75b1Sopenharmony_ci  return false;
127307ac75b1Sopenharmony_ci}
127407ac75b1Sopenharmony_ci
127507ac75b1Sopenharmony_cifunction isNonspecificChildIfStatement(node: ts.Node, specificChildSet: Set<string>,
127607ac75b1Sopenharmony_ci  allComponentNames: Set<string>): boolean {
127707ac75b1Sopenharmony_ci  if (!node) {
127807ac75b1Sopenharmony_ci    return false;
127907ac75b1Sopenharmony_ci  }
128007ac75b1Sopenharmony_ci  if (ts.isBlock(node) && isNonspecificChildBlock(node, specificChildSet, allComponentNames)) {
128107ac75b1Sopenharmony_ci    return true;
128207ac75b1Sopenharmony_ci  }
128307ac75b1Sopenharmony_ci  if (ts.isIfStatement(node) && isNonspecificChildIf(node, specificChildSet, allComponentNames)) {
128407ac75b1Sopenharmony_ci    return true;
128507ac75b1Sopenharmony_ci  }
128607ac75b1Sopenharmony_ci  if (ts.isExpressionStatement(node) && ts.isEtsComponentExpression(node.expression) &&
128707ac75b1Sopenharmony_ci    isForEachComponent(node.expression) &&
128807ac75b1Sopenharmony_ci    isNonspecificChildForEach(node.expression, specificChildSet, allComponentNames)) {
128907ac75b1Sopenharmony_ci    return true;
129007ac75b1Sopenharmony_ci  }
129107ac75b1Sopenharmony_ci  if (ts.isExpressionStatement(node) && ts.isEtsComponentExpression(node.expression) &&
129207ac75b1Sopenharmony_ci    !isForEachComponent(node.expression) && isComponent(node.expression, allComponentNames) &&
129307ac75b1Sopenharmony_ci    isNonspecificChildNonForEach(node.expression, specificChildSet)) {
129407ac75b1Sopenharmony_ci    return true;
129507ac75b1Sopenharmony_ci  }
129607ac75b1Sopenharmony_ci  return false;
129707ac75b1Sopenharmony_ci}
129807ac75b1Sopenharmony_ci
129907ac75b1Sopenharmony_cifunction collectComponentProps(node: ts.StructDeclaration, structInfo: StructInfo): void {
130007ac75b1Sopenharmony_ci  const componentName: string = node.name.getText();
130107ac75b1Sopenharmony_ci  const componentSet: IComponentSet = getComponentSet(node, true);
130207ac75b1Sopenharmony_ci  propertyCollection.set(componentName, componentSet.properties);
130307ac75b1Sopenharmony_ci  stateCollection.set(componentName, componentSet.states);
130407ac75b1Sopenharmony_ci  linkCollection.set(componentName, componentSet.links);
130507ac75b1Sopenharmony_ci  storedFileInfo.overallLinkCollection.set(componentName, componentSet.links);
130607ac75b1Sopenharmony_ci  propCollection.set(componentName, componentSet.props);
130707ac75b1Sopenharmony_ci  regularCollection.set(componentName, componentSet.regulars);
130807ac75b1Sopenharmony_ci  storagePropCollection.set(componentName, componentSet.storageProps);
130907ac75b1Sopenharmony_ci  storageLinkCollection.set(componentName, componentSet.storageLinks);
131007ac75b1Sopenharmony_ci  provideCollection.set(componentName, componentSet.provides);
131107ac75b1Sopenharmony_ci  consumeCollection.set(componentName, componentSet.consumes);
131207ac75b1Sopenharmony_ci  objectLinkCollection.set(componentName, componentSet.objectLinks);
131307ac75b1Sopenharmony_ci  storedFileInfo.overallObjectLinkCollection.set(componentName, componentSet.objectLinks);
131407ac75b1Sopenharmony_ci  localStorageLinkCollection.set(componentName, componentSet.localStorageLink);
131507ac75b1Sopenharmony_ci  localStoragePropCollection.set(componentName, componentSet.localStorageProp);
131607ac75b1Sopenharmony_ci  builderParamObjectCollection.set(componentName, componentSet.builderParams);
131707ac75b1Sopenharmony_ci  builderParamInitialization.set(componentName, componentSet.builderParamData);
131807ac75b1Sopenharmony_ci  propInitialization.set(componentName, componentSet.propData);
131907ac75b1Sopenharmony_ci  regularInitialization.set(componentName, componentSet.regularInit);
132007ac75b1Sopenharmony_ci  stateInitialization.set(componentName, componentSet.stateInit);
132107ac75b1Sopenharmony_ci  provideInitialization.set(componentName, componentSet.provideInit);
132207ac75b1Sopenharmony_ci  privateCollection.set(componentName, componentSet.privateCollection);
132307ac75b1Sopenharmony_ci  structInfo.updatePropsDecoratorsV1.push(
132407ac75b1Sopenharmony_ci    ...componentSet.states, ...componentSet.props,
132507ac75b1Sopenharmony_ci    ...componentSet.provides, ...componentSet.objectLinks
132607ac75b1Sopenharmony_ci  );
132707ac75b1Sopenharmony_ci  structInfo.linkDecoratorsV1.push(...componentSet.links);
132807ac75b1Sopenharmony_ci}
132907ac75b1Sopenharmony_ci
133007ac75b1Sopenharmony_ciexport function getComponentSet(node: ts.StructDeclaration, uiCheck: boolean = false): IComponentSet {
133107ac75b1Sopenharmony_ci  const componentSet: IComponentSet = new IComponentSet();
133207ac75b1Sopenharmony_ci  traversalComponentProps(node, componentSet, uiCheck);
133307ac75b1Sopenharmony_ci  return componentSet;
133407ac75b1Sopenharmony_ci}
133507ac75b1Sopenharmony_ci
133607ac75b1Sopenharmony_ciclass RecordRequire {
133707ac75b1Sopenharmony_ci  hasRequire: boolean = false;
133807ac75b1Sopenharmony_ci  hasProp: boolean = false;
133907ac75b1Sopenharmony_ci  hasBuilderParam: boolean = false;
134007ac75b1Sopenharmony_ci  hasRegular: boolean = false;
134107ac75b1Sopenharmony_ci  hasState: boolean = false;
134207ac75b1Sopenharmony_ci  hasProvide: boolean = false;
134307ac75b1Sopenharmony_ci}
134407ac75b1Sopenharmony_ci
134507ac75b1Sopenharmony_cifunction traversalComponentProps(node: ts.StructDeclaration, componentSet: IComponentSet,
134607ac75b1Sopenharmony_ci  uiCheck: boolean = false): void {
134707ac75b1Sopenharmony_ci  let isStatic: boolean = true;
134807ac75b1Sopenharmony_ci  if (node.members) {
134907ac75b1Sopenharmony_ci    const currentMethodCollection: Set<string> = new Set();
135007ac75b1Sopenharmony_ci    node.members.forEach(item => {
135107ac75b1Sopenharmony_ci      if (ts.isPropertyDeclaration(item) && ts.isIdentifier(item.name)) {
135207ac75b1Sopenharmony_ci        const propertyName: string = item.name.getText();
135307ac75b1Sopenharmony_ci        componentSet.properties.add(propertyName);
135407ac75b1Sopenharmony_ci        const decorators: readonly ts.Decorator[] = ts.getAllDecorators(item);
135507ac75b1Sopenharmony_ci        const accessQualifierResult: AccessQualifierResult = getAccessQualifier(item, uiCheck);
135607ac75b1Sopenharmony_ci        if (!decorators || !decorators.length) {
135707ac75b1Sopenharmony_ci          componentSet.regulars.add(propertyName);
135807ac75b1Sopenharmony_ci          setPrivateCollection(componentSet, accessQualifierResult, propertyName, COMPONENT_NON_DECORATOR);
135907ac75b1Sopenharmony_ci        } else {
136007ac75b1Sopenharmony_ci          isStatic = false;
136107ac75b1Sopenharmony_ci          let hasValidatePrivate: boolean = false;
136207ac75b1Sopenharmony_ci          const recordRequire: RecordRequire = new RecordRequire();
136307ac75b1Sopenharmony_ci          for (let i = 0; i < decorators.length; i++) {
136407ac75b1Sopenharmony_ci            const decoratorName: string = decorators[i].getText().replace(/\(.*\)$/, '').trim();
136507ac75b1Sopenharmony_ci            if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName)) {
136607ac75b1Sopenharmony_ci              dollarCollection.add('$' + propertyName);
136707ac75b1Sopenharmony_ci              collectionStates(decorators[i], decoratorName, propertyName,
136807ac75b1Sopenharmony_ci                componentSet, recordRequire);
136907ac75b1Sopenharmony_ci              setPrivateCollection(componentSet, accessQualifierResult, propertyName, decoratorName);
137007ac75b1Sopenharmony_ci              validateAccessQualifier(item, propertyName, decoratorName, accessQualifierResult,
137107ac75b1Sopenharmony_ci                recordRequire, uiCheck, hasValidatePrivate);
137207ac75b1Sopenharmony_ci              hasValidatePrivate = true;
137307ac75b1Sopenharmony_ci            }
137407ac75b1Sopenharmony_ci          }
137507ac75b1Sopenharmony_ci          regularAndRequire(decorators, componentSet, recordRequire, propertyName, accessQualifierResult);
137607ac75b1Sopenharmony_ci          checkRequire(propertyName, componentSet, recordRequire);
137707ac75b1Sopenharmony_ci        }
137807ac75b1Sopenharmony_ci      }
137907ac75b1Sopenharmony_ci      if (ts.isMethodDeclaration(item) && item.name && ts.isIdentifier(item.name)) {
138007ac75b1Sopenharmony_ci        validateStateVariable(item);
138107ac75b1Sopenharmony_ci        currentMethodCollection.add(item.name.getText());
138207ac75b1Sopenharmony_ci      }
138307ac75b1Sopenharmony_ci    });
138407ac75b1Sopenharmony_ci    collectCurrentClassMethod(node, currentMethodCollection);
138507ac75b1Sopenharmony_ci  }
138607ac75b1Sopenharmony_ci  isStaticViewCollection.set(node.name.getText(), isStatic);
138707ac75b1Sopenharmony_ci}
138807ac75b1Sopenharmony_ci
138907ac75b1Sopenharmony_cifunction collectCurrentClassMethod(node: ts.StructDeclaration, currentMethodCollection: Set<string>): void {
139007ac75b1Sopenharmony_ci  const componentMethodCollection: Map<string, Set<string>> = new Map();
139107ac75b1Sopenharmony_ci  componentMethodCollection.set(node.name.getText(), currentMethodCollection);
139207ac75b1Sopenharmony_ci  const sourceFile: ts.SourceFile = node.getSourceFile();
139307ac75b1Sopenharmony_ci  const filePath: string = sourceFile ? sourceFile.fileName : undefined;
139407ac75b1Sopenharmony_ci  if (filePath) {
139507ac75b1Sopenharmony_ci    const pageMethodCollection: Map<string, Set<string>> = classMethodCollection.get(filePath);
139607ac75b1Sopenharmony_ci    if (!pageMethodCollection) {
139707ac75b1Sopenharmony_ci      classMethodCollection.set(filePath, componentMethodCollection);
139807ac75b1Sopenharmony_ci    } else if (!pageMethodCollection.get(node.name.getText())) {
139907ac75b1Sopenharmony_ci      pageMethodCollection.set(node.name.getText(), currentMethodCollection);
140007ac75b1Sopenharmony_ci    }
140107ac75b1Sopenharmony_ci  }
140207ac75b1Sopenharmony_ci}
140307ac75b1Sopenharmony_ci
140407ac75b1Sopenharmony_ciconst FORBIDDEN_PUBLIC_ACCESS: string[] = [COMPONENT_STORAGE_PROP_DECORATOR,
140507ac75b1Sopenharmony_ci  COMPONENT_STORAGE_LINK_DECORATOR, COMPONENT_LOCAL_STORAGE_LINK_DECORATOR,
140607ac75b1Sopenharmony_ci  COMPONENT_LOCAL_STORAGE_PROP_DECORATOR, COMPONENT_CONSUME_DECORATOR
140707ac75b1Sopenharmony_ci];
140807ac75b1Sopenharmony_ciconst FORBIDDEN_PRIVATE_ACCESS: string[] = [COMPONENT_LINK_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR];
140907ac75b1Sopenharmony_ci
141007ac75b1Sopenharmony_cifunction validateAccessQualifier(node: ts.PropertyDeclaration, propertyName: string,
141107ac75b1Sopenharmony_ci  decoratorName: string, accessQualifierResult: AccessQualifierResult,
141207ac75b1Sopenharmony_ci  recordRequire: RecordRequire, uiCheck: boolean = false, hasValidatePrivate: boolean): void {
141307ac75b1Sopenharmony_ci  if (uiCheck) {
141407ac75b1Sopenharmony_ci    if (accessQualifierResult.hasPublic && FORBIDDEN_PUBLIC_ACCESS.includes(decoratorName)) {
141507ac75b1Sopenharmony_ci      transformLog.errors.push({
141607ac75b1Sopenharmony_ci        type: LogType.WARN,
141707ac75b1Sopenharmony_ci        message: `Property '${propertyName}' can not be decorated with both ${decoratorName} and public.`,
141807ac75b1Sopenharmony_ci        pos: node.getStart()
141907ac75b1Sopenharmony_ci      });
142007ac75b1Sopenharmony_ci    }
142107ac75b1Sopenharmony_ci    if (accessQualifierResult.hasPrivate) {
142207ac75b1Sopenharmony_ci      if (FORBIDDEN_PRIVATE_ACCESS.includes(decoratorName)) {
142307ac75b1Sopenharmony_ci        transformLog.errors.push({
142407ac75b1Sopenharmony_ci          type: LogType.WARN,
142507ac75b1Sopenharmony_ci          message: `Property '${propertyName}' can not be decorated with both ${decoratorName} and private.`,
142607ac75b1Sopenharmony_ci          pos: node.getStart()
142707ac75b1Sopenharmony_ci        });
142807ac75b1Sopenharmony_ci      }
142907ac75b1Sopenharmony_ci      if (recordRequire.hasRequire && !hasValidatePrivate) {
143007ac75b1Sopenharmony_ci        transformLog.errors.push({
143107ac75b1Sopenharmony_ci          type: LogType.WARN,
143207ac75b1Sopenharmony_ci          message: `Property '${propertyName}' can not be decorated with both @Require and private.`,
143307ac75b1Sopenharmony_ci          pos: node.getStart()
143407ac75b1Sopenharmony_ci        });
143507ac75b1Sopenharmony_ci      }
143607ac75b1Sopenharmony_ci    }
143707ac75b1Sopenharmony_ci  }
143807ac75b1Sopenharmony_ci}
143907ac75b1Sopenharmony_ci
144007ac75b1Sopenharmony_ciconst SUPPORT_PRIVATE_PROPS: string[] = [COMPONENT_NON_DECORATOR, COMPONENT_STATE_DECORATOR,
144107ac75b1Sopenharmony_ci  COMPONENT_PROP_DECORATOR, COMPONENT_PROVIDE_DECORATOR, COMPONENT_BUILDERPARAM_DECORATOR
144207ac75b1Sopenharmony_ci];
144307ac75b1Sopenharmony_ci
144407ac75b1Sopenharmony_cifunction setPrivateCollection(componentSet: IComponentSet, accessQualifierResult: AccessQualifierResult,
144507ac75b1Sopenharmony_ci  propertyName: string, decoratorName: string): void {
144607ac75b1Sopenharmony_ci  if (accessQualifierResult.hasPrivate && SUPPORT_PRIVATE_PROPS.includes(decoratorName)) {
144707ac75b1Sopenharmony_ci    componentSet.privateCollection.add(propertyName);
144807ac75b1Sopenharmony_ci  }
144907ac75b1Sopenharmony_ci}
145007ac75b1Sopenharmony_ci
145107ac75b1Sopenharmony_ciclass AccessQualifierResult {
145207ac75b1Sopenharmony_ci  hasPrivate: boolean = false;
145307ac75b1Sopenharmony_ci  hasPublic: boolean = false;
145407ac75b1Sopenharmony_ci}
145507ac75b1Sopenharmony_ci
145607ac75b1Sopenharmony_cifunction getAccessQualifier(node: ts.PropertyDeclaration, uiCheck: boolean = false): AccessQualifierResult {
145707ac75b1Sopenharmony_ci  const modifiers: readonly ts.Modifier[] = ts.getModifiers(node);
145807ac75b1Sopenharmony_ci  const accessQualifierResult: AccessQualifierResult = new AccessQualifierResult();
145907ac75b1Sopenharmony_ci  if (modifiers && modifiers.length) {
146007ac75b1Sopenharmony_ci    modifiers.forEach((item) => {
146107ac75b1Sopenharmony_ci      if (item.kind === ts.SyntaxKind.PrivateKeyword) {
146207ac75b1Sopenharmony_ci        accessQualifierResult.hasPrivate = true;
146307ac75b1Sopenharmony_ci      }
146407ac75b1Sopenharmony_ci      if (item.kind === ts.SyntaxKind.PublicKeyword) {
146507ac75b1Sopenharmony_ci        accessQualifierResult.hasPublic = true;
146607ac75b1Sopenharmony_ci      }
146707ac75b1Sopenharmony_ci      if (uiCheck && item.kind === ts.SyntaxKind.ProtectedKeyword) {
146807ac75b1Sopenharmony_ci        transformLog.errors.push({
146907ac75b1Sopenharmony_ci          type: LogType.WARN,
147007ac75b1Sopenharmony_ci          message: `The member attributes of a struct can not be protected.`,
147107ac75b1Sopenharmony_ci          pos: node.getStart()
147207ac75b1Sopenharmony_ci        });
147307ac75b1Sopenharmony_ci      }
147407ac75b1Sopenharmony_ci    });
147507ac75b1Sopenharmony_ci  }
147607ac75b1Sopenharmony_ci  return accessQualifierResult;
147707ac75b1Sopenharmony_ci}
147807ac75b1Sopenharmony_ci
147907ac75b1Sopenharmony_cifunction regularAndRequire(decorators: readonly ts.Decorator[], componentSet: IComponentSet,
148007ac75b1Sopenharmony_ci  recordRequire: RecordRequire, propertyName: string, accessQualifierResult: AccessQualifierResult): void {
148107ac75b1Sopenharmony_ci  if (decorators && decorators.length === 1 && decorators[0].getText() === COMPONENT_REQUIRE_DECORATOR) {
148207ac75b1Sopenharmony_ci    componentSet.regulars.add(propertyName);
148307ac75b1Sopenharmony_ci    recordRequire.hasRegular = true;
148407ac75b1Sopenharmony_ci    setPrivateCollection(componentSet, accessQualifierResult, propertyName, COMPONENT_NON_DECORATOR);
148507ac75b1Sopenharmony_ci  }
148607ac75b1Sopenharmony_ci}
148707ac75b1Sopenharmony_ci
148807ac75b1Sopenharmony_cifunction checkRequire(name: string, componentSet: IComponentSet, recordRequire: RecordRequire): void {
148907ac75b1Sopenharmony_ci  if (recordRequire.hasRequire) {
149007ac75b1Sopenharmony_ci    setInitValue('hasProp', 'propData', name, componentSet, recordRequire);
149107ac75b1Sopenharmony_ci    setInitValue('hasBuilderParam', 'builderParamData', name, componentSet, recordRequire);
149207ac75b1Sopenharmony_ci    setInitValue('hasRegular', 'regularInit', name, componentSet, recordRequire);
149307ac75b1Sopenharmony_ci    setInitValue('hasState', 'stateInit', name, componentSet, recordRequire);
149407ac75b1Sopenharmony_ci    setInitValue('hasProvide', 'provideInit', name, componentSet, recordRequire);
149507ac75b1Sopenharmony_ci  }
149607ac75b1Sopenharmony_ci}
149707ac75b1Sopenharmony_ci
149807ac75b1Sopenharmony_cifunction setInitValue(requirekey: string, initKey: string, name: string, componentSet: IComponentSet,
149907ac75b1Sopenharmony_ci  recordRequire: RecordRequire): void {
150007ac75b1Sopenharmony_ci  if (recordRequire[requirekey]) {
150107ac75b1Sopenharmony_ci    componentSet[initKey].add(name);
150207ac75b1Sopenharmony_ci  }
150307ac75b1Sopenharmony_ci}
150407ac75b1Sopenharmony_ci
150507ac75b1Sopenharmony_cifunction collectionStates(node: ts.Decorator, decorator: string, name: string,
150607ac75b1Sopenharmony_ci  componentSet: IComponentSet, recordRequire: RecordRequire): void {
150707ac75b1Sopenharmony_ci  switch (decorator) {
150807ac75b1Sopenharmony_ci    case COMPONENT_STATE_DECORATOR:
150907ac75b1Sopenharmony_ci      componentSet.states.add(name);
151007ac75b1Sopenharmony_ci      recordRequire.hasState = true;
151107ac75b1Sopenharmony_ci      break;
151207ac75b1Sopenharmony_ci    case COMPONENT_LINK_DECORATOR:
151307ac75b1Sopenharmony_ci      componentSet.links.add(name);
151407ac75b1Sopenharmony_ci      break;
151507ac75b1Sopenharmony_ci    case COMPONENT_PROP_DECORATOR:
151607ac75b1Sopenharmony_ci      recordRequire.hasProp = true;
151707ac75b1Sopenharmony_ci      componentSet.props.add(name);
151807ac75b1Sopenharmony_ci      break;
151907ac75b1Sopenharmony_ci    case COMPONENT_STORAGE_PROP_DECORATOR:
152007ac75b1Sopenharmony_ci      componentSet.storageProps.add(name);
152107ac75b1Sopenharmony_ci      break;
152207ac75b1Sopenharmony_ci    case COMPONENT_STORAGE_LINK_DECORATOR:
152307ac75b1Sopenharmony_ci      componentSet.storageLinks.add(name);
152407ac75b1Sopenharmony_ci      break;
152507ac75b1Sopenharmony_ci    case COMPONENT_PROVIDE_DECORATOR:
152607ac75b1Sopenharmony_ci      recordRequire.hasProvide = true;
152707ac75b1Sopenharmony_ci      componentSet.provides.add(name);
152807ac75b1Sopenharmony_ci      break;
152907ac75b1Sopenharmony_ci    case COMPONENT_CONSUME_DECORATOR:
153007ac75b1Sopenharmony_ci      componentSet.consumes.add(name);
153107ac75b1Sopenharmony_ci      break;
153207ac75b1Sopenharmony_ci    case COMPONENT_OBJECT_LINK_DECORATOR:
153307ac75b1Sopenharmony_ci      componentSet.objectLinks.add(name);
153407ac75b1Sopenharmony_ci      break;
153507ac75b1Sopenharmony_ci    case COMPONENT_BUILDERPARAM_DECORATOR:
153607ac75b1Sopenharmony_ci      recordRequire.hasBuilderParam = true;
153707ac75b1Sopenharmony_ci      componentSet.builderParams.add(name);
153807ac75b1Sopenharmony_ci      break;
153907ac75b1Sopenharmony_ci    case COMPONENT_LOCAL_STORAGE_LINK_DECORATOR :
154007ac75b1Sopenharmony_ci      collectionlocalStorageParam(node, name, componentSet.localStorageLink);
154107ac75b1Sopenharmony_ci      break;
154207ac75b1Sopenharmony_ci    case COMPONENT_LOCAL_STORAGE_PROP_DECORATOR:
154307ac75b1Sopenharmony_ci      collectionlocalStorageParam(node, name, componentSet.localStorageProp);
154407ac75b1Sopenharmony_ci      break;
154507ac75b1Sopenharmony_ci    case COMPONENT_REQUIRE_DECORATOR:
154607ac75b1Sopenharmony_ci      recordRequire.hasRequire = true;
154707ac75b1Sopenharmony_ci      break;
154807ac75b1Sopenharmony_ci  }
154907ac75b1Sopenharmony_ci}
155007ac75b1Sopenharmony_ci
155107ac75b1Sopenharmony_cifunction collectionlocalStorageParam(node: ts.Decorator, name: string,
155207ac75b1Sopenharmony_ci  localStorage: Map<string, Set<string>>): void {
155307ac75b1Sopenharmony_ci  const localStorageParam: Set<string> = new Set();
155407ac75b1Sopenharmony_ci  if (node && ts.isCallExpression(node.expression) && node.expression.arguments &&
155507ac75b1Sopenharmony_ci    node.expression.arguments.length) {
155607ac75b1Sopenharmony_ci    localStorage.set(name, localStorageParam.add(
155707ac75b1Sopenharmony_ci      node.expression.arguments[0].getText()));
155807ac75b1Sopenharmony_ci  }
155907ac75b1Sopenharmony_ci}
156007ac75b1Sopenharmony_ci
156107ac75b1Sopenharmony_ciexport interface ReplaceResult {
156207ac75b1Sopenharmony_ci  content: string,
156307ac75b1Sopenharmony_ci  log: LogInfo[]
156407ac75b1Sopenharmony_ci}
156507ac75b1Sopenharmony_ci
156607ac75b1Sopenharmony_ciexport function sourceReplace(source: string, sourcePath: string): ReplaceResult {
156707ac75b1Sopenharmony_ci  let content: string = source;
156807ac75b1Sopenharmony_ci  const log: LogInfo[] = [];
156907ac75b1Sopenharmony_ci  content = preprocessExtend(content);
157007ac75b1Sopenharmony_ci  content = preprocessNewExtend(content);
157107ac75b1Sopenharmony_ci  // process @system.
157207ac75b1Sopenharmony_ci  content = processSystemApi(content, false, sourcePath);
157307ac75b1Sopenharmony_ci  collectImportNames(content, sourcePath);
157407ac75b1Sopenharmony_ci
157507ac75b1Sopenharmony_ci  return {
157607ac75b1Sopenharmony_ci    content: content,
157707ac75b1Sopenharmony_ci    log: log
157807ac75b1Sopenharmony_ci  };
157907ac75b1Sopenharmony_ci}
158007ac75b1Sopenharmony_ci
158107ac75b1Sopenharmony_ciexport function preprocessExtend(content: string, extendCollection?: Set<string>): string {
158207ac75b1Sopenharmony_ci  const REG_EXTEND: RegExp = /@Extend(\s+)([^\.\s]+)\.([^\(]+)\(/gm;
158307ac75b1Sopenharmony_ci  return content.replace(REG_EXTEND, (item, item1, item2, item3) => {
158407ac75b1Sopenharmony_ci    collectExtend(EXTEND_ATTRIBUTE, item2, '__' + item2 + '__' + item3);
158507ac75b1Sopenharmony_ci    collectExtend(EXTEND_ATTRIBUTE, item2, item3);
158607ac75b1Sopenharmony_ci    if (extendCollection) {
158707ac75b1Sopenharmony_ci      extendCollection.add(item3);
158807ac75b1Sopenharmony_ci    }
158907ac75b1Sopenharmony_ci    return `@Extend(${item2})${item1}function __${item2}__${item3}(`;
159007ac75b1Sopenharmony_ci  });
159107ac75b1Sopenharmony_ci}
159207ac75b1Sopenharmony_ci
159307ac75b1Sopenharmony_ciexport function preprocessNewExtend(content: string, extendCollection?: Set<string>): string {
159407ac75b1Sopenharmony_ci  const REG_EXTEND: RegExp = /@Extend\s*\([^\)]+\)\s*function\s+([^\(\s]+)\s*\(/gm;
159507ac75b1Sopenharmony_ci  return content.replace(REG_EXTEND, (item, item1) => {
159607ac75b1Sopenharmony_ci    if (extendCollection) {
159707ac75b1Sopenharmony_ci      extendCollection.add(item1);
159807ac75b1Sopenharmony_ci    }
159907ac75b1Sopenharmony_ci    return item;
160007ac75b1Sopenharmony_ci  });
160107ac75b1Sopenharmony_ci}
160207ac75b1Sopenharmony_ci
160307ac75b1Sopenharmony_cifunction replaceSystemApi(item: string, systemValue: string, moduleType: string, systemKey: string): string {
160407ac75b1Sopenharmony_ci  // if change format, please update regexp in transformModuleSpecifier
160507ac75b1Sopenharmony_ci  if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) {
160607ac75b1Sopenharmony_ci    item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`;
160707ac75b1Sopenharmony_ci  } else if (moduleType === SYSTEM_PLUGIN || moduleType === OHOS_PLUGIN) {
160807ac75b1Sopenharmony_ci    item = `var ${systemValue} = globalThis.requireNapi('${systemKey}')`;
160907ac75b1Sopenharmony_ci  }
161007ac75b1Sopenharmony_ci  return item;
161107ac75b1Sopenharmony_ci}
161207ac75b1Sopenharmony_ci
161307ac75b1Sopenharmony_cifunction replaceLibSo(importValue: string, libSoKey: string, sourcePath: string = null): string {
161407ac75b1Sopenharmony_ci  if (sourcePath) {
161507ac75b1Sopenharmony_ci    useOSFiles.add(sourcePath);
161607ac75b1Sopenharmony_ci  }
161707ac75b1Sopenharmony_ci  // if change format, please update regexp in transformModuleSpecifier
161807ac75b1Sopenharmony_ci  return projectConfig.bundleName && projectConfig.moduleName ?
161907ac75b1Sopenharmony_ci    `var ${importValue} = globalThis.requireNapi("${libSoKey}", true, "${projectConfig.bundleName}/${projectConfig.moduleName}");` :
162007ac75b1Sopenharmony_ci    `var ${importValue} = globalThis.requireNapi("${libSoKey}", true);`;
162107ac75b1Sopenharmony_ci}
162207ac75b1Sopenharmony_ci
162307ac75b1Sopenharmony_ciexport function processSystemApi(content: string, isProcessAllowList: boolean = false,
162407ac75b1Sopenharmony_ci  sourcePath: string = null, isSystemModule: boolean = false): string {
162507ac75b1Sopenharmony_ci  if (isProcessAllowList && projectConfig.compileMode === ESMODULE) {
162607ac75b1Sopenharmony_ci    // remove the unused system api import decl like following when compile as [esmodule]
162707ac75b1Sopenharmony_ci    // in the result_process phase
162807ac75b1Sopenharmony_ci    // e.g. import "@ohos.application.xxx"
162907ac75b1Sopenharmony_ci    const REG_UNUSED_SYSTEM_IMPORT: RegExp = /import(?:\s*)['"]@(system|ohos)\.(\S+)['"]/g;
163007ac75b1Sopenharmony_ci    content = content.replace(REG_UNUSED_SYSTEM_IMPORT, '');
163107ac75b1Sopenharmony_ci  }
163207ac75b1Sopenharmony_ci
163307ac75b1Sopenharmony_ci  const REG_IMPORT_DECL: RegExp = isProcessAllowList ? projectConfig.compileMode === ESMODULE ?
163407ac75b1Sopenharmony_ci    /import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]/g :
163507ac75b1Sopenharmony_ci    /(import|const)\s+(.+)\s*=\s*(\_\_importDefault\()?require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)(\))?/g :
163607ac75b1Sopenharmony_ci    /(import|export)\s+(?:(.+)|\{([\s\S]+)\})\s+from\s+['"](\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"](\S+)['"]\s*\)/g;
163707ac75b1Sopenharmony_ci
163807ac75b1Sopenharmony_ci  const systemValueCollection: Set<string> = new Set();
163907ac75b1Sopenharmony_ci  const processedContent: string = content.replace(REG_IMPORT_DECL, (item, item1, item2, item3, item4, item5, item6) => {
164007ac75b1Sopenharmony_ci    const importValue: string = isProcessAllowList ? projectConfig.compileMode === ESMODULE ? item1 : item2 : item2 || item5;
164107ac75b1Sopenharmony_ci
164207ac75b1Sopenharmony_ci    if (isProcessAllowList) {
164307ac75b1Sopenharmony_ci      systemValueCollection.add(importValue);
164407ac75b1Sopenharmony_ci      if (projectConfig.compileMode !== ESMODULE) {
164507ac75b1Sopenharmony_ci        collectSourcemapNames(sourcePath, importValue, item5);
164607ac75b1Sopenharmony_ci        return replaceSystemApi(item, importValue, item4, item5);
164707ac75b1Sopenharmony_ci      }
164807ac75b1Sopenharmony_ci      collectSourcemapNames(sourcePath, importValue, item3);
164907ac75b1Sopenharmony_ci      return replaceSystemApi(item, importValue, item2, item3);
165007ac75b1Sopenharmony_ci    }
165107ac75b1Sopenharmony_ci
165207ac75b1Sopenharmony_ci    const moduleRequest: string = item4 || item6;
165307ac75b1Sopenharmony_ci    if (/^@(system|ohos)\./.test(moduleRequest)) { // ohos/system.api
165407ac75b1Sopenharmony_ci      // ets & ts file need compile with .d.ts, so do not replace at the phase of pre_process
165507ac75b1Sopenharmony_ci      if (!isSystemModule) {
165607ac75b1Sopenharmony_ci        return item;
165707ac75b1Sopenharmony_ci      }
165807ac75b1Sopenharmony_ci      const result: RegExpMatchArray = moduleRequest.match(/^@(system|ohos)\.(\S+)$/);
165907ac75b1Sopenharmony_ci      const moduleType: string = result[1];
166007ac75b1Sopenharmony_ci      const apiName: string = result[2];
166107ac75b1Sopenharmony_ci      return replaceSystemApi(item, importValue, moduleType, apiName);
166207ac75b1Sopenharmony_ci    } else if (/^lib(\S+)\.so$/.test(moduleRequest)) { // libxxx.so
166307ac75b1Sopenharmony_ci      const result: RegExpMatchArray = moduleRequest.match(/^lib(\S+)\.so$/);
166407ac75b1Sopenharmony_ci      const libSoKey: string = result[1];
166507ac75b1Sopenharmony_ci      return replaceLibSo(importValue, libSoKey, sourcePath);
166607ac75b1Sopenharmony_ci    }
166707ac75b1Sopenharmony_ci    return item;
166807ac75b1Sopenharmony_ci  });
166907ac75b1Sopenharmony_ci  return processInnerModule(processedContent, systemValueCollection);
167007ac75b1Sopenharmony_ci}
167107ac75b1Sopenharmony_ci
167207ac75b1Sopenharmony_cifunction collectSourcemapNames(sourcePath: string, changedName: string, originalName: string): void {
167307ac75b1Sopenharmony_ci  if (sourcePath == null) {
167407ac75b1Sopenharmony_ci    return;
167507ac75b1Sopenharmony_ci  }
167607ac75b1Sopenharmony_ci  const cleanSourcePath: string = sourcePath.replace('.ets', '.js').replace('.ts', '.js');
167707ac75b1Sopenharmony_ci  if (!sourcemapNamesCollection.has(cleanSourcePath)) {
167807ac75b1Sopenharmony_ci    return;
167907ac75b1Sopenharmony_ci  }
168007ac75b1Sopenharmony_ci
168107ac75b1Sopenharmony_ci  const map: Map<string, string> = sourcemapNamesCollection.get(cleanSourcePath);
168207ac75b1Sopenharmony_ci  if (map.has(changedName)) {
168307ac75b1Sopenharmony_ci    return;
168407ac75b1Sopenharmony_ci  }
168507ac75b1Sopenharmony_ci
168607ac75b1Sopenharmony_ci  for (const entry of originalImportNamesMap.entries()) {
168707ac75b1Sopenharmony_ci    const key: string = entry[0];
168807ac75b1Sopenharmony_ci    const value: string = entry[1];
168907ac75b1Sopenharmony_ci    if (value === '@ohos.' + originalName || value === '@system.' + originalName) {
169007ac75b1Sopenharmony_ci      map.set(changedName.trim(), key);
169107ac75b1Sopenharmony_ci      sourcemapNamesCollection.set(cleanSourcePath, map);
169207ac75b1Sopenharmony_ci      originalImportNamesMap.delete(key);
169307ac75b1Sopenharmony_ci      break;
169407ac75b1Sopenharmony_ci    }
169507ac75b1Sopenharmony_ci  }
169607ac75b1Sopenharmony_ci}
169707ac75b1Sopenharmony_ci
169807ac75b1Sopenharmony_ciexport function collectImportNames(content: string, sourcePath: string = null): void {
169907ac75b1Sopenharmony_ci  const REG_IMPORT_DECL: RegExp =
170007ac75b1Sopenharmony_ci    /(import|export)\s+(.+)\s+from\s+['"](\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"](\S+)['"]\s*\)/g;
170107ac75b1Sopenharmony_ci
170207ac75b1Sopenharmony_ci  const decls: string[] = content.match(REG_IMPORT_DECL);
170307ac75b1Sopenharmony_ci  if (decls !== null) {
170407ac75b1Sopenharmony_ci    decls.forEach(decl => {
170507ac75b1Sopenharmony_ci      const parts: string[] = decl.split(' ');
170607ac75b1Sopenharmony_ci      if (parts.length === 4 && parts[0] === 'import' && parts[2] === 'from' && !parts[3].includes('.so')) {
170707ac75b1Sopenharmony_ci        originalImportNamesMap.set(parts[1], parts[3].replace(/'/g, ''));
170807ac75b1Sopenharmony_ci      }
170907ac75b1Sopenharmony_ci    });
171007ac75b1Sopenharmony_ci  }
171107ac75b1Sopenharmony_ci
171207ac75b1Sopenharmony_ci  if (sourcePath && sourcePath !== null) {
171307ac75b1Sopenharmony_ci    const cleanSourcePath: string = sourcePath.replace('.ets', '.js').replace('.ts', '.js');
171407ac75b1Sopenharmony_ci    if (!sourcemapNamesCollection.has(cleanSourcePath)) {
171507ac75b1Sopenharmony_ci      sourcemapNamesCollection.set(cleanSourcePath, new Map());
171607ac75b1Sopenharmony_ci    }
171707ac75b1Sopenharmony_ci  }
171807ac75b1Sopenharmony_ci}
171907ac75b1Sopenharmony_ci
172007ac75b1Sopenharmony_cifunction processInnerModule(content: string, systemValueCollection: Set<string>): string {
172107ac75b1Sopenharmony_ci  systemValueCollection.forEach(element => {
172207ac75b1Sopenharmony_ci    const target: string = element.trim() + '.default';
172307ac75b1Sopenharmony_ci    while (content.includes(target)) {
172407ac75b1Sopenharmony_ci      content = content.replace(target, element.trim());
172507ac75b1Sopenharmony_ci    }
172607ac75b1Sopenharmony_ci  });
172707ac75b1Sopenharmony_ci  return content;
172807ac75b1Sopenharmony_ci}
172907ac75b1Sopenharmony_ci
173007ac75b1Sopenharmony_ciexport function resetComponentCollection(): void {
173107ac75b1Sopenharmony_ci  componentCollection.entryComponent = null;
173207ac75b1Sopenharmony_ci  componentCollection.entryComponentPos = null;
173307ac75b1Sopenharmony_ci  componentCollection.previewComponent = [];
173407ac75b1Sopenharmony_ci  stateObjectCollection.clear();
173507ac75b1Sopenharmony_ci  builderParamInitialization.clear();
173607ac75b1Sopenharmony_ci  propInitialization.clear();
173707ac75b1Sopenharmony_ci  propCollection.clear();
173807ac75b1Sopenharmony_ci  objectLinkCollection.clear();
173907ac75b1Sopenharmony_ci  linkCollection.clear();
174007ac75b1Sopenharmony_ci  storedFileInfo.overallLinkCollection.clear();
174107ac75b1Sopenharmony_ci  storedFileInfo.overallObjectLinkCollection.clear();
174207ac75b1Sopenharmony_ci  storedFileInfo.overallBuilderParamCollection.clear();
174307ac75b1Sopenharmony_ci  regularInitialization.clear();
174407ac75b1Sopenharmony_ci  stateInitialization.clear();
174507ac75b1Sopenharmony_ci  provideInitialization.clear();
174607ac75b1Sopenharmony_ci  privateCollection.clear();
174707ac75b1Sopenharmony_ci}
174807ac75b1Sopenharmony_ci
174907ac75b1Sopenharmony_cifunction checkEntryComponent(node: ts.StructDeclaration, log: LogInfo[], sourceFile: ts.SourceFile): void {
175007ac75b1Sopenharmony_ci  const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
175107ac75b1Sopenharmony_ci  if (modifiers) {
175207ac75b1Sopenharmony_ci    for (let i = 0; i < modifiers.length; i++) {
175307ac75b1Sopenharmony_ci      if (modifiers[i].kind === ts.SyntaxKind.ExportKeyword) {
175407ac75b1Sopenharmony_ci        const message: string = `It's not a recommended way to export struct with @Entry decorator, ` +
175507ac75b1Sopenharmony_ci          `which may cause ACE Engine error in component preview mode.`;
175607ac75b1Sopenharmony_ci        addLog(LogType.WARN, message, node.getStart(), log, sourceFile);
175707ac75b1Sopenharmony_ci        break;
175807ac75b1Sopenharmony_ci      }
175907ac75b1Sopenharmony_ci    }
176007ac75b1Sopenharmony_ci  }
176107ac75b1Sopenharmony_ci}
176207ac75b1Sopenharmony_ci
176307ac75b1Sopenharmony_cifunction validateStateVariable(node: ts.MethodDeclaration): void {
176407ac75b1Sopenharmony_ci  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
176507ac75b1Sopenharmony_ci  if (decorators && decorators.length) {
176607ac75b1Sopenharmony_ci    for (let i = 0; i < decorators.length; i++) {
176707ac75b1Sopenharmony_ci      const decoratorName: string = decorators[i].getText().replace(/\(.*\)$/, '').trim();
176807ac75b1Sopenharmony_ci      if (CARD_ENABLE_DECORATORS[decoratorName]) {
176907ac75b1Sopenharmony_ci        validatorCard(transformLog.errors, CARD_LOG_TYPE_DECORATORS,
177007ac75b1Sopenharmony_ci          decorators[i].getStart(), decoratorName);
177107ac75b1Sopenharmony_ci      }
177207ac75b1Sopenharmony_ci      if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName)) {
177307ac75b1Sopenharmony_ci        transformLog.errors.push({
177407ac75b1Sopenharmony_ci          type: LogType.ERROR,
177507ac75b1Sopenharmony_ci          message: `'${decorators[i].getText()}' can not decorate the method.`,
177607ac75b1Sopenharmony_ci          pos: decorators[i].getStart()
177707ac75b1Sopenharmony_ci        });
177807ac75b1Sopenharmony_ci      }
177907ac75b1Sopenharmony_ci    }
178007ac75b1Sopenharmony_ci  }
178107ac75b1Sopenharmony_ci}
178207ac75b1Sopenharmony_ci
178307ac75b1Sopenharmony_ciexport function getObservedPropertyCollection(className: string): Set<string> {
178407ac75b1Sopenharmony_ci  const observedProperthCollection: Set<string> = new Set([
178507ac75b1Sopenharmony_ci    ...stateCollection.get(className),
178607ac75b1Sopenharmony_ci    ...linkCollection.get(className),
178707ac75b1Sopenharmony_ci    ...propCollection.get(className),
178807ac75b1Sopenharmony_ci    ...storageLinkCollection.get(className),
178907ac75b1Sopenharmony_ci    ...storageLinkCollection.get(className),
179007ac75b1Sopenharmony_ci    ...provideCollection.get(className),
179107ac75b1Sopenharmony_ci    ...consumeCollection.get(className),
179207ac75b1Sopenharmony_ci    ...objectLinkCollection.get(className)
179307ac75b1Sopenharmony_ci  ]);
179407ac75b1Sopenharmony_ci  getLocalStorageCollection(className, observedProperthCollection);
179507ac75b1Sopenharmony_ci  return observedProperthCollection;
179607ac75b1Sopenharmony_ci}
179707ac75b1Sopenharmony_ci
179807ac75b1Sopenharmony_ciexport function getLocalStorageCollection(componentName: string, collection: Set<string>): void {
179907ac75b1Sopenharmony_ci  if (localStorageLinkCollection.get(componentName)) {
180007ac75b1Sopenharmony_ci    for (const key of localStorageLinkCollection.get(componentName).keys()) {
180107ac75b1Sopenharmony_ci      collection.add(key);
180207ac75b1Sopenharmony_ci    }
180307ac75b1Sopenharmony_ci  }
180407ac75b1Sopenharmony_ci  if (localStoragePropCollection.get(componentName)) {
180507ac75b1Sopenharmony_ci    for (const key of localStoragePropCollection.get(componentName).keys()) {
180607ac75b1Sopenharmony_ci      collection.add(key);
180707ac75b1Sopenharmony_ci    }
180807ac75b1Sopenharmony_ci  }
180907ac75b1Sopenharmony_ci}
181007ac75b1Sopenharmony_ci
181107ac75b1Sopenharmony_ciexport function resetValidateUiSyntax(): void {
181207ac75b1Sopenharmony_ci  observedClassCollection.clear();
181307ac75b1Sopenharmony_ci  enumCollection.clear();
181407ac75b1Sopenharmony_ci  classMethodCollection.clear();
181507ac75b1Sopenharmony_ci  dollarCollection.clear();
181607ac75b1Sopenharmony_ci  stateCollection.clear();
181707ac75b1Sopenharmony_ci  regularCollection.clear();
181807ac75b1Sopenharmony_ci  storagePropCollection.clear();
181907ac75b1Sopenharmony_ci  storageLinkCollection.clear();
182007ac75b1Sopenharmony_ci  provideCollection.clear();
182107ac75b1Sopenharmony_ci  consumeCollection.clear();
182207ac75b1Sopenharmony_ci  builderParamObjectCollection.clear();
182307ac75b1Sopenharmony_ci  localStorageLinkCollection.clear();
182407ac75b1Sopenharmony_ci  localStoragePropCollection.clear();
182507ac75b1Sopenharmony_ci  isStaticViewCollection.clear();
182607ac75b1Sopenharmony_ci  useOSFiles.clear();
182707ac75b1Sopenharmony_ci  sourcemapNamesCollection.clear();
182807ac75b1Sopenharmony_ci  originalImportNamesMap.clear();
182907ac75b1Sopenharmony_ci}
1830