mirror of
https://github.com/openharmony/tools_previewer.git
synced 2026-07-19 14:23:32 -04:00
fix problem context undefined
Signed-off-by: sambaby <1337922982@qq.com>
This commit is contained in:
@@ -53,6 +53,7 @@ export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string):
|
||||
let exportAssignment: Array<string> = [];
|
||||
const staticMethods: Array<Array<StaticMethodEntity>> = [];
|
||||
const exportDeclarations: Array<string> = [];
|
||||
const functionDeclarations: Array<FunctionEntity> = [];
|
||||
|
||||
sourceFile.forEachChild(node => {
|
||||
if (isImportDeclaration(node)) {
|
||||
@@ -85,7 +86,10 @@ export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string):
|
||||
enumDeclarations.push(getEnumDeclaration(node, sourceFile));
|
||||
} else if (isExportDeclaration(node)) {
|
||||
exportDeclarations.push(sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd());
|
||||
} else {
|
||||
} else if (isFunctionDeclaration(node)){
|
||||
functionDeclarations.push(getFunctionDeclaration(node, sourceFile));
|
||||
}
|
||||
else {
|
||||
if (node.kind !== SyntaxKind.EndOfFileToken && !isFunctionDeclaration(node) && !isVariableStatement(node)) {
|
||||
console.log('--------------------------- uncaught sourceFile type start -----------------------');
|
||||
console.log('fileName: ' + fileName);
|
||||
@@ -104,7 +108,8 @@ export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string):
|
||||
enumDeclarations: enumDeclarations,
|
||||
exportAssignment: exportAssignment,
|
||||
staticMethods: staticMethods,
|
||||
exportDeclarations: exportDeclarations
|
||||
exportDeclarations: exportDeclarations,
|
||||
functionDeclarations: functionDeclarations,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -169,5 +174,6 @@ export interface SourceFileEntity {
|
||||
enumDeclarations: Array<EnumEntity>,
|
||||
exportAssignment: Array<string>,
|
||||
staticMethods: Array<Array<StaticMethodEntity>>,
|
||||
exportDeclarations: Array<string>
|
||||
exportDeclarations: Array<string>,
|
||||
functionDeclarations: Array<FunctionEntity>
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ function getImportTypeAliasNameFromImportElements(importElementEntity: ImportEle
|
||||
if (typeName === 'Want') {
|
||||
typeName = 'mockWant().Want';
|
||||
} else if (typeName === 'InputMethodExtensionContext') {
|
||||
typeName = 'mockInputmethodextensioncontext().InputMethodExtensionContext';
|
||||
typeName = 'mockInputMethodExtensionContext().InputMethodExtensionContext';
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 type { SourceFile } from 'typescript';
|
||||
import { SyntaxKind } from 'typescript';
|
||||
import type { FunctionEntity } from '../declaration-node/functionDeclaration';
|
||||
import { getCallbackStatement, getReturnStatement } from './generateCommonUtil';
|
||||
|
||||
/**
|
||||
* generate function
|
||||
* @param rootName
|
||||
* @param functionArray
|
||||
* @param sourceFile
|
||||
* @param mockApi
|
||||
* @returns
|
||||
*/
|
||||
export function generateExportFunction(functionEntity: FunctionEntity, sourceFile: SourceFile, mockApi: string): string {
|
||||
let functionBody = '';
|
||||
functionBody = `global.${functionEntity.functionName} = function (...args) {`;
|
||||
functionBody += `console.warn('The ${functionEntity.functionName} interface in the Previewer is a mocked implementation and may behave differently than on a real device.');\n`;
|
||||
|
||||
const args = functionEntity.args;
|
||||
const len = args.length;
|
||||
if (args.length > 0 && args[len - 1].paramName.toLowerCase().includes('callback')) {
|
||||
functionBody += getCallbackStatement(mockApi);
|
||||
}
|
||||
if (functionEntity.returnType.returnKind !== SyntaxKind.VoidKeyword) {
|
||||
functionBody += getReturnStatement(functionEntity.returnType, sourceFile);
|
||||
}
|
||||
functionBody += '}';
|
||||
return functionBody;
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import { generateModuleDeclaration } from './generateModuleDeclaration';
|
||||
import { generateStaticFunction } from './generateStaticFunction';
|
||||
import { addToSystemIndexArray } from './generateSystemIndex';
|
||||
import { generateTypeAliasDeclaration } from './generateTypeAlias';
|
||||
import { generateExportFunction } from './generateExportFunction';
|
||||
|
||||
/**
|
||||
* generate mock file string
|
||||
@@ -54,7 +55,7 @@ export function generateSourceFileElements(rootName: string, sourceFileEntity: S
|
||||
|
||||
if (sourceFileEntity.moduleDeclarations.length > 0) {
|
||||
sourceFileEntity.moduleDeclarations.forEach(value => {
|
||||
mockApi += generateModuleDeclaration('', value, sourceFile, fileName, mockApi) + '\n';
|
||||
mockApi += generateModuleDeclaration('', value, sourceFile, fileName, mockApi, extraImport) + '\n';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -84,11 +85,17 @@ export function generateSourceFileElements(rootName: string, sourceFileEntity: S
|
||||
|
||||
if (sourceFileEntity.typeAliasDeclarations.length > 0) {
|
||||
sourceFileEntity.typeAliasDeclarations.forEach(value => {
|
||||
mockApi += generateTypeAliasDeclaration(value, false) + '\n';
|
||||
mockApi += generateTypeAliasDeclaration(value, false, sourceFile, extraImport) + '\n';
|
||||
mockFunctionElements.push({ elementName: value.typeAliasName, type: 'typeAlias' });
|
||||
});
|
||||
}
|
||||
|
||||
if (sourceFileEntity.functionDeclarations.length > 0) {
|
||||
sourceFileEntity.functionDeclarations.forEach(value => {
|
||||
mockApi += generateExportFunction(value, sourceFile, mockApi) + '\n';
|
||||
});
|
||||
}
|
||||
|
||||
if (sourceFileEntity.moduleDeclarations.length === 0 && (fileName.startsWith('ohos_') || fileName.startsWith('system_') || fileName.startsWith('webgl'))) {
|
||||
const mockNameArr = fileName.split('_');
|
||||
const mockName = mockNameArr[mockNameArr.length - 1];
|
||||
@@ -157,6 +164,9 @@ export function generateSourceFileElements(rootName: string, sourceFileEntity: S
|
||||
* generate import definition
|
||||
* @param importEntity
|
||||
* @param sourceFileName
|
||||
* @param heritageClausesArray
|
||||
* @param currentFilePath
|
||||
* @param dependsSourceFileList
|
||||
* @returns
|
||||
*/
|
||||
export function generateImportDeclaration(
|
||||
|
||||
@@ -39,9 +39,11 @@ import { generateVariableStatementDelcatation } from './generateVariableStatemen
|
||||
* @param moduleEntity
|
||||
* @param sourceFile
|
||||
* @param filename
|
||||
* @param extraImport
|
||||
* @returns
|
||||
*/
|
||||
export function generateModuleDeclaration(rootName: string, moduleEntity: ModuleBlockEntity, sourceFile: SourceFile, filename: string, mockApi: string): string {
|
||||
export function generateModuleDeclaration(rootName: string, moduleEntity: ModuleBlockEntity, sourceFile: SourceFile,
|
||||
filename: string, mockApi: string, extraImport: string[]): string {
|
||||
let moduleName = moduleEntity.moduleName.replace(/["']/g, '');
|
||||
let moduleBody = `export function mock${firstCharacterToUppercase(moduleName)}() {\n`;
|
||||
if (!(moduleEntity.exportModifiers.includes(SyntaxKind.DeclareKeyword) &&
|
||||
@@ -82,7 +84,7 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module
|
||||
|
||||
if (moduleEntity.typeAliasDeclarations.length > 0) {
|
||||
moduleEntity.typeAliasDeclarations.forEach(value => {
|
||||
outBody += generateTypeAliasDeclaration(value, true) + '\n';
|
||||
outBody += generateTypeAliasDeclaration(value, true, sourceFile, extraImport) + '\n';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -178,7 +180,6 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module
|
||||
/**
|
||||
* generate inner module for declare module
|
||||
* @param moduleEntity
|
||||
* @param sourceFile
|
||||
* @returns
|
||||
*/
|
||||
function generateInnerDeclareModule(moduleEntity: ModuleBlockEntity): string {
|
||||
@@ -196,9 +197,10 @@ function generateInnerDeclareModule(moduleEntity: ModuleBlockEntity): string {
|
||||
* generate inner module
|
||||
* @param moduleEntity
|
||||
* @param sourceFile
|
||||
* @param extraImport
|
||||
* @returns
|
||||
*/
|
||||
function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: SourceFile): string {
|
||||
function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: SourceFile, extraImport: string[]): string {
|
||||
const moduleName = moduleEntity.moduleName;
|
||||
let innerModuleBody = `const ${moduleName} = (()=> {`;
|
||||
|
||||
@@ -210,7 +212,7 @@ function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: Source
|
||||
|
||||
if (moduleEntity.typeAliasDeclarations.length > 0) {
|
||||
moduleEntity.typeAliasDeclarations.forEach(value => {
|
||||
innerModuleBody += generateTypeAliasDeclaration(value, true) + '\n';
|
||||
innerModuleBody += generateTypeAliasDeclaration(value, true, sourceFile, extraImport) + '\n';
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,22 +13,131 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { TypeAliasEntity } from '../declaration-node/typeAliasDeclaration';
|
||||
import type { TypeAliasEntity, TypeAliasTypeEntity } from '../declaration-node/typeAliasDeclaration';
|
||||
import { firstCharacterToUppercase, getOhosInterfacesDir } from '../common/commonUtils';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import type { SourceFile } from 'typescript';
|
||||
|
||||
/**
|
||||
* generate type alias
|
||||
* @param typeAliasEntity
|
||||
* @param isInner
|
||||
* @param sourceFile
|
||||
* @param extraImport
|
||||
* @returns
|
||||
*/
|
||||
export function generateTypeAliasDeclaration(typeAliasEntity: TypeAliasEntity, isInner: boolean): string {
|
||||
export function generateTypeAliasDeclaration(
|
||||
typeAliasEntity: TypeAliasEntity, isInner: boolean, sourceFile: SourceFile, extraImport: string[]
|
||||
): string {
|
||||
let typeAliasName = '';
|
||||
if (!isInner) {
|
||||
typeAliasName += `export const ${typeAliasEntity.typeAliasName} = `;
|
||||
} else {
|
||||
typeAliasName += `const ${typeAliasEntity.typeAliasName} = `;
|
||||
}
|
||||
|
||||
let typeAliasValue = '';
|
||||
typeAliasValue += `'[PC Preview] unknown ${typeAliasEntity.typeAliasName}'`;
|
||||
|
||||
const typeAliasTypeElements = typeAliasEntity.typeAliasTypeElements;
|
||||
|
||||
if (typeAliasTypeElements) {
|
||||
typeAliasValue += parseImportExpression(typeAliasTypeElements, sourceFile, extraImport);
|
||||
}
|
||||
|
||||
if (!typeAliasValue) {
|
||||
typeAliasValue += `'[PC Preview] unknown ${typeAliasEntity.typeAliasName}'`;
|
||||
}
|
||||
return typeAliasName + typeAliasValue + ';';
|
||||
}
|
||||
|
||||
function getImportFileFullPath(typeName: string): string {
|
||||
const importRelatePathTmp = typeName.match(/\('[^'()]+'\)/);
|
||||
if (!importRelatePathTmp) {
|
||||
return '';
|
||||
}
|
||||
const importRelatePath = importRelatePathTmp[0].substring(2, importRelatePathTmp[0].length - 2);
|
||||
const tmpRealPath = getOhosInterfacesDir() + importRelatePath.replace('../api', '').replace(/\//g, path.sep);
|
||||
if (fs.existsSync(tmpRealPath + '.d.ts')) {
|
||||
return tmpRealPath + '.d.ts';
|
||||
}
|
||||
|
||||
if (fs.existsSync(tmpRealPath + '.d.ets')) {
|
||||
return tmpRealPath + '.d.ets';
|
||||
}
|
||||
console.warn(`Can not find import \'${importRelatePath}\'`);
|
||||
return '';
|
||||
}
|
||||
|
||||
function pathToImportPath(currentFilePath: string, importFilePath: string): string {
|
||||
const currentFilePathSteps = currentFilePath.replace(/.d.e?ts/, '').split('/');
|
||||
const importFilePathSteps = importFilePath.replace(/.d.e?ts/, '').split(path.sep);
|
||||
const importFilePathStepsLength = importFilePathSteps.length;
|
||||
importFilePathSteps[importFilePathStepsLength - 1] = importFilePathSteps[importFilePathStepsLength - 1]
|
||||
.replace('@', '').replace(/\./g, '_');
|
||||
let differStepIndex: number;
|
||||
for (differStepIndex = 0; differStepIndex < currentFilePathSteps.length; differStepIndex++) {
|
||||
if (currentFilePathSteps[differStepIndex] !== importFilePathSteps[differStepIndex]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const currentFileDifferPathSteps = currentFilePathSteps.slice(differStepIndex);
|
||||
const importFileDifferPathSteps = importFilePathSteps.slice(differStepIndex);
|
||||
if (currentFileDifferPathSteps.length === importFileDifferPathSteps.length
|
||||
&& currentFileDifferPathSteps.length === 1) {
|
||||
return `./${path.basename(importFilePath)}`;
|
||||
} else {
|
||||
const steps = [];
|
||||
for (let i = 0; i < currentFileDifferPathSteps.length - 1; i++) {
|
||||
steps.push('..');
|
||||
}
|
||||
const fullSteps = steps.concat(importFileDifferPathSteps);
|
||||
return fullSteps.join('/');
|
||||
}
|
||||
}
|
||||
|
||||
function parseImportExpression(
|
||||
typeAliasTypeElements: TypeAliasTypeEntity[], sourceFile: SourceFile, extraImport: string[]
|
||||
): string {
|
||||
for (let i = 0; i < typeAliasTypeElements.length; i++) {
|
||||
const typeAliasTypeElement = typeAliasTypeElements[i];
|
||||
const typeName = typeAliasTypeElement.typeName;
|
||||
if (!typeName?.trim().startsWith('import(')) {
|
||||
continue;
|
||||
}
|
||||
const splitTypeName = typeName.split(')');
|
||||
const propertiesIndex = 1;
|
||||
const properties = splitTypeName[propertiesIndex];
|
||||
const importPath = getImportFileFullPath(typeName);
|
||||
const realImportPath = pathToImportPath(sourceFile.fileName, importPath);
|
||||
if (!importPath) {
|
||||
continue;
|
||||
}
|
||||
const importFileContent = fs.readFileSync(importPath, 'utf-8');
|
||||
if (properties.startsWith('.default')) {
|
||||
let result = importFileContent.match(/export\sdefault\sclass\s[a-zA-Z]+/);
|
||||
if (result) {
|
||||
const defaultModuleName = '_' + result[0].replace(/export\sdefault\sclass\s/, '');
|
||||
const importStr = `import ${defaultModuleName} from '${realImportPath}';\n`;
|
||||
!extraImport.includes(importStr) && extraImport.push(importStr);
|
||||
return `${defaultModuleName}${properties.replace('.default', '')}`;
|
||||
}
|
||||
result = importFileContent.match(/export\sdefault\s[a-zA-Z]+;/);
|
||||
if (result) {
|
||||
const moduleName = result[0]
|
||||
.replace(/export\sdefault\s/, '')
|
||||
.replace(';', '');
|
||||
const mockFunctionName = `mock${firstCharacterToUppercase(moduleName)}`;
|
||||
const importStr = `import {${mockFunctionName}} from '${realImportPath}';\n`;
|
||||
!extraImport.includes(importStr) && extraImport.push(importStr);
|
||||
return `${mockFunctionName}()${properties.replace('.default', '')}`;
|
||||
}
|
||||
} else {
|
||||
const moduleName = properties.replace('.', '').split('.')[0];
|
||||
const importStr = `import {${moduleName} as _${moduleName}} from '${realImportPath}';\n`;
|
||||
!extraImport.includes(importStr) && extraImport.push(importStr);
|
||||
return `_${properties.replace('.', '')}`;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user