diff --git a/.gitignore b/.gitignore index ace4a03ce043b5ff9fccd8f87b398ed9cc718933..8481c75bc61ff85205a049ca668b262864d833f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode/ +compiler/arkTest_build/ compiler/node_modules/ compiler/lib/ compiler/declarations/ diff --git a/compiler/src/ets_checker.ts b/compiler/src/ets_checker.ts index 889599ddb9eb715008d4f866a16bf78fad0bff22..f52aafe899a21a38a328da4243135810296a4476 100644 --- a/compiler/src/ets_checker.ts +++ b/compiler/src/ets_checker.ts @@ -657,6 +657,8 @@ export function resolveModuleNames(moduleNames: string[], containingFile: string } else { const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts'); const systemDETSModulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ets'); + const kitModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ts'); + const kitSystemDETSModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ets'); const suffix: string = /\.js$/.test(moduleName) ? '' : '.js'; const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix); const fileModulePath: string = @@ -667,6 +669,10 @@ export function resolveModuleNames(moduleNames: string[], containingFile: string resolvedModules.push(getResolveModule(modulePath, '.d.ts')); } else if (ts.sys.fileExists(systemDETSModulePath)) { resolvedModules.push(getResolveModule(systemDETSModulePath, '.d.ets')); + } else if (ts.sys.fileExists(kitModulePath)) { + resolvedModules.push(getResolveModule(kitModulePath, '.d.ts')); + } else if (ts.sys.fileExists(kitSystemDETSModulePath)) { + resolvedModules.push(getResolveModule(kitSystemDETSModulePath, '.d.ets')); } else if (ts.sys.fileExists(jsModulePath)) { resolvedModules.push(getResolveModule(jsModulePath, '.js')); } else if (ts.sys.fileExists(fileModulePath)) { diff --git a/compiler/src/fast_build/ark_compiler/module/module_source_file.ts b/compiler/src/fast_build/ark_compiler/module/module_source_file.ts index 6a35327df515678e9900a0595427f1d1eb2163e5..3b815a3b73e1e983aa24b12d6300eb36a694fcf2 100644 --- a/compiler/src/fast_build/ark_compiler/module/module_source_file.ts +++ b/compiler/src/fast_build/ark_compiler/module/module_source_file.ts @@ -360,7 +360,7 @@ export class ModuleSourceFile { if (ts.isImportDeclaration(node) || (ts.isExportDeclaration(node) && node.moduleSpecifier)) { // moduleSpecifier.getText() returns string carrying on quotation marks which the importMap's key does not, // so we need to remove the quotation marks from moduleRequest. - const moduleRequest: string = node.moduleSpecifier.getText().replace(/'|"/g, ''); + const moduleRequest: string = (node.moduleSpecifier! as ts.StringLiteral).text.replace(/'|"/g, ''); let ohmUrl: string | undefined = this.getOhmUrl(rollupObject, moduleRequest, importMap[moduleRequest]); if (ohmUrl !== undefined) { // the import module are added with ".origin" at the end of the ohm url in every mock file. diff --git a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts index 7daee56f07d5c0e53732bf12a6d2d188fb9a893d..536d2763f7016273abd8c6c6d862e08c2c139bfc 100644 --- a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts +++ b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts @@ -72,6 +72,10 @@ import { GLOBAL_CUSTOM_BUILDER_METHOD, INNER_CUSTOM_BUILDER_METHOD } from '../../component_map'; +import { + kitTransformLog, + processKitImport +} from '../../process_kit_import'; const filter:any = createFilter(/(? = process.env.watchMode === 'true' ? new Map() : SOURCE_FILES; +const IMPORT_FILE_ASTCACHE: Map = + process.env.watchMode === 'true' ? new Map() : (SOURCE_FILES ? SOURCE_FILES : new Map()); export default function processImport(node: ts.ImportDeclaration | ts.ImportEqualsDeclaration | ts.ExportDeclaration, pagesDir: string, log: LogInfo[], asName: Map = new Map(), @@ -87,7 +88,7 @@ isEntryPage: boolean = true, pathCollection: Set = new Set()): void { let filePath: string; let defaultName: string; if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) { - filePath = node.moduleSpecifier.getText().replace(/'|"/g, ''); + filePath = (node.moduleSpecifier! as ts.StringLiteral).text.replace(/'|"/g, ''); if (ts.isImportDeclaration(node) && node.importClause && node.importClause.name && ts.isIdentifier(node.importClause.name)) { defaultName = node.importClause.name.escapedText.toString(); @@ -296,7 +297,7 @@ function visitAllNode(node: ts.Node, sourceFile: ts.SourceFile, defaultNameFromP } if (ts.isImportDeclaration(node)) { if (node.importClause && node.importClause.name && ts.isIdentifier(node.importClause.name) && - asNameFromParent.has(node.importClause.name.getText())) { + asNameFromParent.has(node.importClause.name.text)) { processImport(node, pagesDir, log, asNameFromParent, false, new Set(pathCollection)); } else if (node.importClause && node.importClause.namedBindings && ts.isNamedImports(node.importClause.namedBindings) && node.importClause.namedBindings.elements) { diff --git a/compiler/src/process_kit_import.ts b/compiler/src/process_kit_import.ts new file mode 100644 index 0000000000000000000000000000000000000000..67f305e283beae1952cbcf87fba18883b2603393 --- /dev/null +++ b/compiler/src/process_kit_import.ts @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as ts from 'typescript'; +import fs from 'fs'; +import path from 'path'; + +import { + FileLog, + LogType +} from './utils'; + +/* +* basic implementation logic: +* tsc -> transformer +* | -> iterate top-level static import/export declaration +* | -> for each declaration +* | -> collect KitInfo +* | -> generate corresponding ohosImports for each ohos-source +* | -> replace each origin declaration with corresponding ohosImports +*/ + +export const kitTransformLog: FileLog = new FileLog(); + +const KIT_PREFIX = '@kit.'; + +/* +* This API is the TSC Transformer for transforming `KitImport` into `OhosImport` +* e.g. +* ``` +* import { ability, ErrorCode } from '@kit.AbilityKit' +* ---> +* import ability from '@ohos.ability.ability' +* import ErrorCode from '@ohos.ability.errorCode' +* ``` +*/ +export function processKitImport(): Function { + return (context: ts.TransformationContext) => { + const visitor: ts.Visitor = node => { + // only transform static import/export declaration + if (ts.isImportDeclaration(node) || (ts.isExportDeclaration(node) && node.moduleSpecifier)) { + const moduleRequest: string = (node.moduleSpecifier as ts.StringLiteral).text.replace(/'|"/g, ''); + if (moduleRequest.startsWith(KIT_PREFIX)) { + const kitDefs = getKitDefs(moduleRequest); + if (kitDefs && kitDefs.symbols) { + KitInfo.processKitInfo(moduleRequest, kitDefs.symbols as KitSymbols, node); + return [...KitInfo.getCurrentKitInfo().getOhosImportNodes()]; + } + } + } + return node; + } + + return (node: ts.SourceFile) => { + KitInfo.init(node); + return ts.visitEachChild(node, visitor, context); + }; + } +} + +/* +* Main implementation of Transforming +*/ +const DEFAULT_BINDINGS = 'default'; + +enum FileType { + ETS, + TS +} + +interface KitSymbol { + source: string + bindings: string +} + +declare type KitSymbols = Record; +declare type TSspecifier = ts.ImportSpecifier | ts.ExportSpecifier; +declare type TSModuleDeclaration = ts.ImportDeclaration | ts.ExportDeclaration; + +/* +* class SpecificerInfo represents the corresponding info of each imported identifier which coming from Kit +*/ +class SpecificerInfo { + private localName: string; + private importName: string; + private symbol: KitSymbol; + private renamed: boolean; + + private originElement: TSspecifier | undefined; + + constructor(localName: string, importName: string, symbol: KitSymbol, originElement: TSspecifier | undefined) { + this.localName = localName; + this.importName = importName; + this.symbol = symbol; + this.originElement = originElement; + this.renamed = (this.localName !== this.symbol.bindings); + + this.validateImportingETSDeclarationSymbol(); + } + + getSource(): string { + return this.symbol.source; + } + + getLocalName(): string { + return this.localName; + } + + isRenamed(): boolean { + return this.renamed; + } + + getBindings(): string { + return this.symbol.bindings; + } + + isDefaultBinding(): boolean { + return this.symbol.bindings === DEFAULT_BINDINGS; + } + + validateImportingETSDeclarationSymbol() { + if (KitInfo.isTSFile() && /.d.ets$/.test(this.symbol.source)) { + kitTransformLog.errors.push({ + type: LogType.ERROR, + message: `Identifier '${this.importName}' comes from '${this.symbol.source}' ` + + `which can not be imported in .ts file.`, + pos: this.getOriginElementNode().getStart() + }); + } + } + + setOriginElementNode(originElement: TSspecifier) { + this.originElement = originElement; + } + + getOriginElementNode(): TSspecifier { + return this.originElement; + } +} + +class KitInfo { + private static currentKitInfo: KitInfo = undefined; + private static currentFileType: FileType = FileType.ETS; + private static currentKitName: string = ''; + + private symbols: KitSymbols; + private kitNode: TSModuleDeclaration; + private kitNodeModifier: readonly ts.Modifier[] | undefined; + private specifiers: Map = new Map(); + + private ohosImportNodes: TSModuleDeclaration[] = []; + + constructor(kitNode: TSModuleDeclaration, symbols: Record) { + this.kitNode = kitNode; + this.symbols = symbols; + + this.kitNodeModifier = ts.canHaveDecorators(this.kitNode) ? ts.getModifiers(this.kitNode) : undefined; + } + + static init(node: ts.SourceFile): void { + if (/\.ts$/.test(node.fileName)) { + this.setFileType(FileType.TS); + } else { + this.setFileType(FileType.ETS); + } + + kitTransformLog.sourceFile = node; + } + + static getCurrentKitName(): string { + return this.currentKitName; + } + + static getCurrentKitInfo(): KitInfo { + return this.currentKitInfo; + } + + static setFileType(fileType: FileType): void { + this.currentFileType = fileType; + } + + static isTSFile(): boolean { + return this.currentFileType === FileType.TS; + } + + static processImportDecl(kitNode: ts.ImportDeclaration, symbols: Record) { + if (kitNode.importClause!.namedBindings) { + const namedBindings: ts.NamedImportBindings = kitNode.importClause.namedBindings; + if (ts.isNamespaceImport(namedBindings)) { + // e.g. import * as ns from "@kit.xxx" + this.currentKitInfo = new NameSpaceKitInfo(kitNode, symbols); + } + if (ts.isNamedImports(namedBindings) && namedBindings.elements.length !== 0) { + // e.g. import { ... } from "@kit.xxx" + this.currentKitInfo = new ImportSpecifierKitInfo(kitNode, symbols); + namedBindings.elements.forEach(element => { this.currentKitInfo.collectSpecifier(element) }); + } + } + + if (kitNode.importClause!.name) { + // e.g. import default from "@kit.xxx" + const defaultName: string = kitNode.importClause.name.text; + this.currentKitInfo.newSpecificerInfo(defaultName, DEFAULT_BINDINGS, undefined); + } + } + + static processExportDecl(kitNode: ts.ExportDeclaration, symbols: Record) { + if (kitNode.exportClause) { + const namedExportBindings: ts.NamedExportBindings = kitNode.exportClause; + if (ts.isNamespaceExport(namedExportBindings)) { + // e.g. export * as ns from "@kit.xxx" + this.currentKitInfo = new NameSpaceKitInfo(kitNode, symbols); + } else if (ts.isNamedExports(namedExportBindings) && namedExportBindings.elements.length !== 0) { + // e.g. export { ... } from "@kit.xxx" + this.currentKitInfo = new ExportSpecifierKitInfo(kitNode, symbols); + namedExportBindings.elements.forEach(element => { this.currentKitInfo.collectSpecifier(element) }); + } + } else { + this.currentKitInfo = new ExportStarKitInfo(kitNode, symbols); + } + } + + static processKitInfo(kitName: string, symbols: Record, kitNode: TSModuleDeclaration): void { + this.currentKitName = kitName; + + // do not handle an empty import + if (ts.isImportDeclaration(kitNode) && kitNode.importClause) { + // case 1: import { ... } from '@kit.xxx' + // case 2: import * as ns from '@kit.xxx' + // case 3: import defalutValue from '@kit.xxx' + this.processImportDecl(kitNode, symbols); + } + + if (ts.isExportDeclaration(kitNode) && kitNode.moduleSpecifier) { + // case 1: export { ... } from '@kit.xxx' + // case 2: export * from '@kit.xxx' + // case 3: export * as ns from '@kit.xxx' - considering forbidden + this.processExportDecl(kitNode, symbols); + } + // transform into ohos imports or exports + this.currentKitInfo && this.currentKitInfo.transform(); + } + + getSymbols(): KitSymbols { + return this.symbols; + } + + getKitNode(): TSModuleDeclaration { + return this.kitNode; + } + + getKitNodeModifier(): readonly ts.Modifier[] | undefined { + return this.kitNodeModifier; + } + + getSpecifiers(): Map { + return this.specifiers; + } + + getOhosImportNodes(): TSModuleDeclaration[] { + return this.ohosImportNodes; + } + + newSpecificerInfo(localName: string, importName: string, originElement: TSspecifier | undefined): void { + const symbol: KitSymbol | undefined = this.symbols[importName]; + if (symbol) { + const specifier: SpecificerInfo = new SpecificerInfo(localName, importName, symbol, originElement); + if (this.specifiers.has(symbol.source)) { + this.specifiers.get(symbol.source).push(specifier); + } else { + this.specifiers.set(symbol.source, [specifier]); + } + } else { + kitTransformLog.errors.push({ + type: LogType.ERROR, + message: `Kit '${KitInfo.getCurrentKitName()} has not exported the Identifier '${importName}'.`, + pos: originElement ? originElement.getStart() : this.getKitNode().getStart() + }); + } + } + + collectSpecifier(element: TSspecifier) { + const localName: string = element.name.getText(); + const importName: string = element.propertyName ? element.propertyName.getText() : localName; + this.newSpecificerInfo(localName, importName, element); + } + + // @ts-ignore + transform(): void {} //override api +} + +class NameSpaceKitInfo extends KitInfo { + private namespaceName: string; + private localNameTable: string[] = []; + + constructor(kitNode: ts.ImportDeclaration | ts.ExportDeclaration, symbols: Record) { + super(kitNode, symbols); + + kitTransformLog.errors.push({ + type: LogType.ERROR, + message: `Namespace import or export of Kit is not supported currently.`, + pos: kitNode.getStart() + }); + } + + transform(): void { + } +} + +class ImportSpecifierKitInfo extends KitInfo { + private namedBindings: ts.ImportSpecifier[] = []; + private specifierDefaultName: ts.Identifier | undefined = undefined; + + constructor(kitNode: ts.ImportDeclaration, symbols: Record) { + super(kitNode, symbols); + } + + private hasNamedBindings(): boolean { + return this.namedBindings.length !== 0; + } + + private clearSpecifierKitInfo(): void { + this.namedBindings = []; + this.specifierDefaultName = undefined; + } + + transform() { + const node: ts.ImportDeclaration = this.getKitNode() as ts.ImportDeclaration; + + this.getSpecifiers().forEach((specifiers: SpecificerInfo[], source: string) => { + specifiers.forEach((specifier: SpecificerInfo) => { + if (specifier.isDefaultBinding()) { + this.specifierDefaultName = ts.factory.createIdentifier(specifier.getLocalName()); + } else { + this.namedBindings.push( + ts.factory.createImportSpecifier( + specifier.getOriginElementNode() ? + (specifier.getOriginElementNode() as ts.ImportSpecifier).isTypeOnly : node.importClause.isTypeOnly, + specifier.isRenamed() ? ts.factory.createIdentifier(specifier.getBindings()) : undefined, + ts.factory.createIdentifier(specifier.getLocalName()) + ) + ); + } + }); + + this.getOhosImportNodes().push(ts.factory.createImportDeclaration( + this.getKitNodeModifier(), + ts.factory.createImportClause( + node.importClause!.isTypeOnly, + this.specifierDefaultName, + this.hasNamedBindings() ? ts.factory.createNamedImports(this.namedBindings) : undefined + ), + ts.factory.createStringLiteral(trimSourceSuffix(source)) + )); + + this.clearSpecifierKitInfo(); + }); + } +} + +class ExportSpecifierKitInfo extends KitInfo { + private namedBindings: ts.ExportSpecifier[] = []; + + constructor(kitNode: ts.ExportDeclaration, symbols: Record) { + super(kitNode, symbols); + } + + private hasNamedBindings(): boolean { + return this.namedBindings.length !== 0; + } + + private clearSpecifierKitInfo(): void { + this.namedBindings = []; + } + + transform(): void { + const node: ts.ExportDeclaration = this.getKitNode() as ts.ExportDeclaration; + + this.getSpecifiers().forEach((specifiers: SpecificerInfo[], source: string) => { + specifiers.forEach((specifier: SpecificerInfo) => { + this.namedBindings.push( + ts.factory.createExportSpecifier( + (specifier.getOriginElementNode() as ts.ExportSpecifier).isTypeOnly, + specifier.isRenamed() ? ts.factory.createIdentifier(specifier.getBindings()) : undefined, + ts.factory.createIdentifier(specifier.getLocalName()) + ) + ); + }); + + this.getOhosImportNodes().push(ts.factory.createExportDeclaration( + this.getKitNodeModifier(), + node.isTypeOnly, + this.hasNamedBindings() ? ts.factory.createNamedExports(this.namedBindings) : undefined, + ts.factory.createStringLiteral(trimSourceSuffix(source)), + node.assertClause + )); + + this.clearSpecifierKitInfo(); + }); + } +} + +class ExportStarKitInfo extends KitInfo { + private sourceSet: Set = new Set(); + + constructor(kitNode: ts.ExportDeclaration, symbols: Record) { + super(kitNode, symbols); + + for (const symbol in symbols) { + this.sourceSet.add(symbols[symbol].source); + } + + kitTransformLog.errors.push({ + type: LogType.WARN, + message: `Using 'export *' will load all the sub-module of Kit in runtime.`, + pos: this.getKitNode().getStart() + }); + } + + transform(): void { + const node: ts.ExportDeclaration = this.getKitNode() as ts.ExportDeclaration; + + this.sourceSet.forEach((source: string) => { + this.getOhosImportNodes().push(ts.factory.createExportDeclaration( + this.getKitNodeModifier(), + node.isTypeOnly, + undefined, + ts.factory.createStringLiteral(trimSourceSuffix(source)), + node.assertClause + )); + }); + } +} + +/* +* utils part +*/ +const JSON_SUFFIX = '.json'; +const KIT_CONFIGS = 'kit_configs'; +const KIT_CONFIG_PATH = './build-tools/ets-loader/kit_configs'; + +function getKitDefs(kitModuleRequest: string) { + const kitConfigs: string[] = [path.resolve(__dirname, `../${KIT_CONFIGS}`)]; + if (process.env.externalApiPaths) { + const externalApiPaths = process.env.externalApiPaths.split(path.delimiter); + externalApiPaths.forEach(sdkPath => { + kitConfigs.push(path.resolve(sdkPath, KIT_CONFIG_PATH)); + }); + } + + for (const kitConfig of kitConfigs) { + const kitModuleConfigJson = path.resolve(kitConfig, `./${kitModuleRequest}${JSON_SUFFIX}`); + if (fs.existsSync(kitModuleConfigJson)) { + return JSON.parse(fs.readFileSync(kitModuleConfigJson, 'utf-8')); + } + } + return undefined; +} + +function trimSourceSuffix(source: string): string { + return source.replace(/\.d.[e]?ts$/, ''); +} \ No newline at end of file diff --git a/compiler/src/process_ui_syntax.ts b/compiler/src/process_ui_syntax.ts index 55b585f99b08f53b0bc9b5f23eed394a2be23e30..0936dfa4e027bb575a3cb90d4a0593449c62db7d 100644 --- a/compiler/src/process_ui_syntax.ts +++ b/compiler/src/process_ui_syntax.ts @@ -235,17 +235,10 @@ export function processUISyntax(program: ts.Program, ut = false, parentEvent?: a } function processAllNodes(node: ts.Node): ts.Node { - if (projectConfig.compileMode === 'esmodule' && process.env.compileTool === 'rollup' && - ts.isImportDeclaration(node)) { - startTimeStatisticsLocation(compilationTime ? compilationTime.processImportTime : undefined); - processImportModule(node, pageFile); - stopTimeStatisticsLocation(compilationTime ? compilationTime.processImportTime : undefined); - } else if ((projectConfig.compileMode !== 'esmodule' || process.env.compileTool !== 'rollup') && - (ts.isImportDeclaration(node) || ts.isImportEqualsDeclaration(node) || - ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier))) { + if (ts.isImportDeclaration(node) || ts.isImportEqualsDeclaration(node) || + ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { processImport(node, pagesDir, transformLog.errors); - } - if (ts.isStructDeclaration(node)) { + } else if (ts.isStructDeclaration(node)) { componentCollection.currentClassName = node.name.getText(); componentCollection.entryComponent === componentCollection.currentClassName && entryKeyNode(node); startTimeStatisticsLocation(compilationTime ? compilationTime.processComponentClassTime : undefined); diff --git a/compiler/test/ark_compiler_ut/common/process_kit_import.test.ts b/compiler/test/ark_compiler_ut/common/process_kit_import.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..db559da054037f21da1663a5024b71359edaf0c7 --- /dev/null +++ b/compiler/test/ark_compiler_ut/common/process_kit_import.test.ts @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use rollupObject file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import mocha from 'mocha'; +import * as ts from 'typescript'; +import path from 'path'; + +import { processKitImport } from '../../../lib/process_kit_import' + +const KIT_IMPORT_CODE: string = +` +import { Ability, featureAbility, ErrorCode } from "@kit.AbilityKit"; +let localAbility = new Ability(); +let localFeature = new featureAbility(); +let noError = ErrorCode.NO_ERROR; +` + +const KIT_IMPORT_CODE_EXPECT: string = +'import Ability from "@ohos.app.ability.Ability";\n' + +'import featureAbility from "@ohos.ability.featureAbility";\n'+ +'import { ErrorCode } from "@ohos.ability.errorCode";\n'+ +'let localAbility = new Ability();\n'+ +'let localFeature = new featureAbility();\n'+ +'let noError = ErrorCode.NO_ERROR;\n'+ +'//# sourceMappingURL=kitTest.js.map' + +const KIT_EXPORT_CODE: string = +` +export { Ability, featureAbility, ErrorCode } from "@kit.AbilityKit"; +` + +const KIT_EXPORT_CODE_EXPECT: string = +'export { default as Ability } from "@ohos.app.ability.Ability";\n' + +'export { default as featureAbility } from "@ohos.ability.featureAbility";\n'+ +'export { ErrorCode } from "@ohos.ability.errorCode";\n'+ +'//# sourceMappingURL=kitTest.js.map' + +const KIT_STAR_EXPORT_CODE: string = +` +export * from "@kit.AudioKit"; +` + +const KIT_STAR_EXPORT_CODE_EXPECT: string = +'export * from "@ohos.multimedia.audio";\n' + +'export * from "@ohos.multimedia.audioHaptic";\n'+ +'export * from "@ohos.multimedia.systemSoundManager";\n'+ +'//# sourceMappingURL=kitTest.js.map' + +const compilerOptions = ts.readConfigFile( + path.resolve(__dirname, '../../../tsconfig.json'), ts.sys.readFile).config.compilerOptions; +compilerOptions['moduleResolution'] = 'nodenext'; +compilerOptions['module'] = 'es2020'; + +// !! The Kit transform result would be changed once the kit config file has updated. +mocha.describe('process Kit Imports tests', function () { + mocha.it('process specifier imports', function () { + const result: ts.TranspileOutput = ts.transpileModule(KIT_IMPORT_CODE, { + compilerOptions: compilerOptions, + fileName: "kitTest.ts", + transformers: { before: [ processKitImport() ] } + }); + expect(result.outputText == KIT_IMPORT_CODE_EXPECT).to.be.true; + }); + + mocha.it('process specifier exports', function () { + const result: ts.TranspileOutput = ts.transpileModule(KIT_EXPORT_CODE, { + compilerOptions: compilerOptions, + fileName: "kitTest.ts", + transformers: { before: [ processKitImport() ] } + }); + expect(result.outputText == KIT_EXPORT_CODE_EXPECT).to.be.true; + }); + + mocha.it('process star export', function () { + const result: ts.TranspileOutput = ts.transpileModule(KIT_STAR_EXPORT_CODE, { + compilerOptions: compilerOptions, + fileName: "kitTest.ts", + transformers: { before: [ processKitImport() ] } + }); + expect(result.outputText == KIT_STAR_EXPORT_CODE_EXPECT).to.be.true; + }); +});