diff --git a/src/vscode_plugin/changelog.md b/src/vscode_plugin/changelog.md index 294a072aaf5d4d4b3c623988e518328f16d2102c..256fcda8747c7a66ba887f7eb4a6d24f26a886ec 100644 --- a/src/vscode_plugin/changelog.md +++ b/src/vscode_plugin/changelog.md @@ -8,7 +8,7 @@ 2. 新增 OpenHarmony 交叉编译功能,详见:[OpenHarmony 交叉编译](https://gitee.com/openharmony/napi_generator/tree/master/src/vscode_plugin/doc/ohCrossCompile.md) -3. 新增dts2cpp功能:开发中,近期完成 +3. 新增dts2cpp功能,详见:[readme](https://gitee.com/openharmony/napi_generator/blob/master/src/vscode_plugin/readme.md) ### Bug修复 diff --git a/src/vscode_plugin/docs/usedts2cpp.md b/src/vscode_plugin/docs/usedts2cpp.md new file mode 100644 index 0000000000000000000000000000000000000000..b4cece5a969b82371b1b72c129f031545350ee2b --- /dev/null +++ b/src/vscode_plugin/docs/usedts2cpp.md @@ -0,0 +1,79 @@ +# dts2cpp使用文档 + +## 环境 + +DevEco Studio: Build Version: 4.1.0.400, built on April 9, 2024 + +## 创建工程 + +1.打开 DevEco Studio: + +选择Create Project -> Application -> Native C++ ,然后点击Next,将Project name修改为dts2cppTest,点击Finish,则工程创建成功。 + +![](../images/dts2cppTest_create_new_project.png) + +![](../images/dts2cppTest_create_new_project_finish.png) + +2.修改编译选项:在dts2cppTest/entry/build-profile.json5文件中buildOption/externalNativeOptions中增加abiFilters字段, 并将targets字段的runtimeOS改为OpenHarmony + +``` +"abiFilters": [ + "arm64-v8a", + "armeabi-v7a" +] +``` + +``` +"runtimeOS": "OpenHarmony" +``` + +![](../images/dts2cppTest_add_buildOption.png) + +## 测试生成物 + +1.将生成文件拷贝至工程相应路径下 + +1.1将生成目录下的cpp目录下的所有文件拷贝到工程目录dts2cppTest/entry/src/main/cpp目录下,并将所有cpp文件加入编译选项,在target_link_libraries中加入hilog: + +``` +libhilog_ndk.z.so +``` + +修改后的CMakeLists.txt文件如下所示: + +![](../images/dts2cppTest_project_cmakelist.png) + +1.2将生成目录下的ets目录下的ets文件(testdtsAbility.test.ets)拷贝到工程目录dts2cppTest/entry/src/ohosTest/ets/test目录下, + +在dts2cppTest/entry/src/ohosTest/ets/test/List.test.ets中导入testdtsAbility.test.ets: + +``` +import abilityTest from './Ability.test'; +import testdtsabilityTest from './testdtsAbility.test'; + +export default function testsuite() { + abilityTest(); + testdtsabilityTest(); +} +``` + +![](../images/dts2cppTest_testList.png) + +1.3将转换的dts文件 (testdts.d.ts) 中所有内容拷贝到 dts2cppTest/entry/src/main/cpp/types/libentry/index.d.ts中(不覆盖原有内容)。 + +2.确认生成物是否能编译 + +2.1对工程签名:File->Project Structure ->Project -> Signing Configs + +![](../images/dts2cppTest_Sign_configs.png) + +2.2运行dts2cppTest/entry/src/ohosTest/ets/test/testdtsAbility.test.ets中的测试集testdtsActsAbilityTest,用例成功运行,并打印出相关log。 + +![](../images/dts2cppTest_runtest.png) + +![](../images/dts2cppTest_success.png) + +例如:方法testFunc打印出默认对象值: + +![](../images/dts2cppTest_successLog.png) + diff --git a/src/vscode_plugin/images/dts2cppTest_Sign_configs.png b/src/vscode_plugin/images/dts2cppTest_Sign_configs.png new file mode 100644 index 0000000000000000000000000000000000000000..42d44193a53b69c4a6682ccdae49f1a68c7e84ac Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_Sign_configs.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_add_buildOption.png b/src/vscode_plugin/images/dts2cppTest_add_buildOption.png new file mode 100644 index 0000000000000000000000000000000000000000..c872e420eabbc2c77b316b9cc78964f1ca804690 Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_add_buildOption.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_create_new_project.png b/src/vscode_plugin/images/dts2cppTest_create_new_project.png new file mode 100644 index 0000000000000000000000000000000000000000..82b33a492e40c1c636e57cebdad7544078307aae Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_create_new_project.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_create_new_project_finish.png b/src/vscode_plugin/images/dts2cppTest_create_new_project_finish.png new file mode 100644 index 0000000000000000000000000000000000000000..2f4ea4ddb2271e9113ad751539f2f48ed7e6e18a Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_create_new_project_finish.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_project_cmakelist.png b/src/vscode_plugin/images/dts2cppTest_project_cmakelist.png new file mode 100644 index 0000000000000000000000000000000000000000..4e33b312ee31a6d69e4a64e6a704f0c558855be5 Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_project_cmakelist.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_runtest.png b/src/vscode_plugin/images/dts2cppTest_runtest.png new file mode 100644 index 0000000000000000000000000000000000000000..0acec8606bf15a5d444ca4ae3039789dcd9483e5 Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_runtest.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_success.png b/src/vscode_plugin/images/dts2cppTest_success.png new file mode 100644 index 0000000000000000000000000000000000000000..7ce02be2e0b0eb71a33f7f4f47283cd7119e67bc Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_success.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_successLog.png b/src/vscode_plugin/images/dts2cppTest_successLog.png new file mode 100644 index 0000000000000000000000000000000000000000..b041c0e3b5c073e02e10d89d07883074782ce6b9 Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_successLog.png differ diff --git a/src/vscode_plugin/images/dts2cppTest_testList.png b/src/vscode_plugin/images/dts2cppTest_testList.png new file mode 100644 index 0000000000000000000000000000000000000000..596f1dc0d8e42969595800538bb7aaef178c4de5 Binary files /dev/null and b/src/vscode_plugin/images/dts2cppTest_testList.png differ diff --git a/src/vscode_plugin/readme.md b/src/vscode_plugin/readme.md index d8e4b197807e191df622399e5f9a734727242b18..f0bb1426e9870c8331561cbd5f55fe35f58d3de5 100644 --- a/src/vscode_plugin/readme.md +++ b/src/vscode_plugin/readme.md @@ -34,6 +34,12 @@ VS Code 版本:1.73.0及以上 - **dts2cpp**:根据.d.ts文件生成OpenHarmony Native C++应用开发模板中的CPP文件。 + 验证过的平台如下: + + | 平台 | 版本 | + | ------------- | ------------------------------------------------------------ | + | DecEco Studio | 4.1 Release(Build Version: 4.1.0.400, built on April 9, 2024) | + - **OpenHarmony交叉编译**:根据三方库中Makefile或CmakeLists,调用OpenHarmony SDK中提供的工具链进行交叉编译,拼装 make 及 make install 命令并调用终端执行。生成对应于目标系统架构的二进制文件及头文件,默认安装至三方库路径下ohCrossCompile目录中。 - **snippets**: 根据 [snippetsApi](https://gitee.com/openharmony/napi_generator/tree/master/src/vscode_plugin/docs/snippetsApi.md) 中的命令提供各场景(结构体、枚举等)napi、Aki开发代码片段。 @@ -72,7 +78,7 @@ VS Code 版本:1.73.0及以上 * h2dtscpp: [h2dtscpp使用帮助文档](https://gitee.com/openharmony/napi_generator/blob/master/src/cli/h2dtscpp/docs/usage/INSTRUCTION_ZH.md) -* dts2cpp:开发中,近期完成 +* dts2cpp:[dts2cpp使用帮助文档](https://gitee.com/openharmony/napi_generator/tree/master/src/vscode_plugin/docs/usedts2cpp.md) * OpenHarmony交叉编译:[OpenHarmony交叉编译使用帮助文档](https://gitee.com/openharmony/napi_generator/tree/master/src/vscode_plugin/docs/uselibrary.md) diff --git a/src/vscode_plugin/src/datatype.ts b/src/vscode_plugin/src/datatype.ts index 9e6eabedbb7eb65e38533396cdf18a55619c61ed..eb346d5890878c95fe415943004f91c57a0169d8 100644 --- a/src/vscode_plugin/src/datatype.ts +++ b/src/vscode_plugin/src/datatype.ts @@ -65,12 +65,19 @@ export interface FuncObj { parameters: ParamObj[]; } +export interface TypeObj { + name: string, + alias: string, + members: ParamObj[] +} + export interface ParseObj { enums: EnumObj[]; unions: UnionObj[]; structs: StructObj[]; classes: ClassObj[]; funcs: FuncObj[]; + types?: TypeObj[]; } export interface ServiceRootInfo { diff --git a/src/vscode_plugin/src/extension.ts b/src/vscode_plugin/src/extension.ts index 89d1be3015f20b66941a4ea9a5437578937191ae..8dc58823f9d7f8a673f66652fa253dc9f83b7dea 100644 --- a/src/vscode_plugin/src/extension.ts +++ b/src/vscode_plugin/src/extension.ts @@ -27,7 +27,7 @@ import { parseTsFile } from './parsets'; import { genServiceFile } from './gensa'; import { genDtsFile } from './gendts'; import { genHdfFile } from './genhdf'; -import { genDtsCppFile } from './gendtscpp'; +import { genDtsCppFile, genCppFile } from './gendtscpp'; // ȡػַ const SELECTED_DIR = vscode.l10n.t('You selected a directory:'); @@ -506,21 +506,29 @@ export function activate(context: vscode.ExtensionContext) { // The code you place here will be executed every time your command is executed console.log('uri is : ' + uri.fsPath ); if (uri && uri.fsPath) { - const extname = path.extname(uri.fsPath); + vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: "Generating CPP...", + cancellable: false + }, async (progress) => { const filename = path.basename(uri.fsPath); console.log('get filename ' ); if (filename.endsWith('.d.ts')) { // Display a message box to the user - // parseTsFile(uri.fsPath) + // analyze let res = parseTsFile(uri.fsPath); console.info('res: ' + JSON.stringify(res)); - vscode.window.showInformationMessage('dts2cpp!'); + progress.report({ increment: 50, message: PARSE_COMPLETE }); + // generator + let out = path.dirname(uri.fsPath); + genCppFile(res, uri.fsPath, out); + progress.report({ increment: 100, message: GEN_COMPLETE + out }); } else { console.log('not dts uri is : ' + uri.fsPath ); // Display a message box to the user vscode.window.showInformationMessage(`${uri.fsPath} is not a .d.ts file!`); } - // generator + }); } }); context.subscriptions.push(dts2cpp); diff --git a/src/vscode_plugin/src/gendtscpp.ts b/src/vscode_plugin/src/gendtscpp.ts index 52b93e12f41ce3395751d4a03dcf70cc91cc7d47..bf2b45abb688cfcdeb9835474a76477c34c5788b 100644 --- a/src/vscode_plugin/src/gendtscpp.ts +++ b/src/vscode_plugin/src/gendtscpp.ts @@ -13,16 +13,18 @@ * limitations under the License. */ -import { DirTemp, DtscppRootInfo, FuncInfo, InterfaceList, TypeList } from "./datatype"; +import { DirTemp, DtscppRootInfo, FuncInfo, InterfaceList, TypeList, ParamObj, ParseObj, ClassObj, FuncObj } from "./datatype"; import { replaceAll } from "./common/tool"; import fs = require('fs'); import path = require("path"); import { napiFuncHTemplate, napiFuncInitTemplate } from "./template/func_template"; -import { dtscppout } from "./template/dtscpp/dtscppdir"; +import { cppout, dtscppout } from "./template/dtscpp/dtscppdir"; import { analyzeRootFunction, genDtsInterface, genTsFunction } from "./gendts"; import { generateDirectFunction } from "./gencpp"; import { generateFuncTestCase } from "./gentest"; +import { tsTransferType } from "./template/functypemap_template"; + interface GenResult { dtsContent: string; // dts文件中的内容 testContet: string; // abilitytest文件中的内容 @@ -128,13 +130,131 @@ function generateFuncCode(rootInfo: DtscppRootInfo) { return genResult; } +// h2dtscpp export function genDtsCppFile(rootInfo: DtscppRootInfo, out: string) { - // 生成dts声明文件 xxx.d.ts let res: GenResult = generateFuncCode(rootInfo); - - // h2dtscpp应该没有版本吧 genDir(dtscppout, res, rootInfo, out); + console.info('generate success!') +} +// dts2cpp +export function genCppFile(parseObj: ParseObj, tsFilePath: string, out: string) { + let rootInfo: DtscppRootInfo = { + funcs: parseObj.funcs, + rawFilePath: tsFilePath, + fileName: path.basename(tsFilePath, '.d.ts')// xxx + }; + let genResult: GenResult = generateFunctions(parseObj, tsFilePath); + genDir(cppout, genResult, rootInfo, out); console.info('generate success!') } +function generateFunctions(parseObj: ParseObj, tsFilePath: string) { + let cppfunctions: FuncInfo[] = getFunctions(parseObj); + let typeList: TypeList[] = getTypes(parseObj); + let interfaceList: InterfaceList[] = getInterfaces(parseObj); + + let genResult: GenResult = { + dtsContent: '', + testContet: '', + napiHContent: '', + napiInitContent: '', + napiCppContent: '', + }; + let rawFileName = path.basename(tsFilePath); + for (let i = 0; i < cppfunctions.length; i++) { + // 每个napi方法的init + genResult.napiInitContent += replaceAll(napiFuncInitTemplate, '[func_name_replace]', cppfunctions[i].genName); + // 每个napi方法的h声明 + genResult.napiHContent += genHFunction(cppfunctions[i], rawFileName); + // 每个Napi方法的cpp说明 + genResult.napiCppContent += generateDirectFunction(cppfunctions[i], rawFileName, typeList, interfaceList); + // gen test function + genResult.testContet += generateFuncTestCase(cppfunctions[i], rawFileName, typeList, interfaceList); + + } + return genResult; +} + +// 将interface列表中的js type全部转换为c type +function getInterfaces(parseObj: ParseObj) { + return parseObj.classes.map(cls => { + const getParams = (variables: ParamObj[]) => + variables.map(variable => ({ + name: variable.name, + type: getCTypeFromJS(variable.type), + arraySize: variable.arraySize + })); + + const getFunctions = (functions: FuncObj[]) => + functions.map(func => ({ + type: func.type, + name: func.name, + returns: getCTypeFromJS(func.returns), + parameters: getParams(func.parameters) + })); + + return { + interfaceName: cls.name, + interfaceBody: { + params: getParams(cls.variableList), + funcs: getFunctions(cls.functionList) + } + }; + }); +} + +function getTypes(parseObj: ParseObj) { + let typeList: TypeList[] = []; + for (let i = 0; i < parseObj.types!.length; i++) { + let typeObj: TypeList = { + typeName: parseObj.types![i].name, + typeBody: getCTypeFromJS(parseObj.types![i].alias), + }; + typeList.push(typeObj); + } + return typeList; +} + +function getFunctions(parseObj: ParseObj) { + let cppfunctions: FuncInfo[] = []; + for (let i = 0; i < parseObj.funcs.length; i++) { + let cppFuncInfo: FuncInfo = { + name: '', + params: [], + retType: '', + genName: '' + }; + cppFuncInfo.name = parseObj.funcs[i].name; + cppFuncInfo.genName = parseObj.funcs[i].name; + let parseParams = parseObj.funcs[i].parameters; + for (let i = 0; i < parseParams.length; ++i) { + let paramsRes = createFuncParam(parseParams[i]); + cppFuncInfo.params.push(paramsRes); + } + cppFuncInfo.retType = getCTypeFromJS(parseObj.funcs[i].returns); + cppfunctions.push(cppFuncInfo); + } + return cppfunctions; +} + +function getCTypeFromJS(type: string) { + let cType = type; + for (let index = 0; index < tsTransferType.length; index++) { + if (type === tsTransferType[index].fromType) { + cType = tsTransferType[index].tranferContent[0]; + } + } + return cType; +} + +function createFuncParam(params: ParamObj) { + let cppParam: ParamObj = { + name: '', + type: '', + arraySize: 0 + }; + cppParam.name = params.name; + cppParam.type = getCTypeFromJS(params.type); + return cppParam; +} diff --git a/src/vscode_plugin/src/parsets.ts b/src/vscode_plugin/src/parsets.ts index 7c9292526328d8a95ee3993b40be8c3f9338b446..867fc7d98df921b8c40664c94695bec3ac3dcbc7 100644 --- a/src/vscode_plugin/src/parsets.ts +++ b/src/vscode_plugin/src/parsets.ts @@ -18,6 +18,7 @@ import * as path from 'path'; import * as ts from 'typescript'; import { json } from 'stream/consumers'; import internal = require('stream'); +import { ParamObj, FuncObj, ClassObj, EnumObj, TypeObj, ParseObj } from './datatype' const fs = require('fs'); @@ -31,7 +32,7 @@ interface NameObj { escapedText: string; } -interface TypeObj { +interface TypeObject { pos: number; escapedText: string; } @@ -39,45 +40,19 @@ interface TypeObj { interface MemberObj { pos: number; name: NameObj; - type: TypeObj; + type: TypeObject; } - -export interface ParamItem { - type: string; - name: string; -} - -export interface TypeItem { - name: string; - subItemList: ParamItem[]; -} - -export interface EnumItem { - name: string; - subItemList: string[]; -} - -export interface FuncItem { - name: string; - returns: string; - parameters: ParamItem[]; -} - -export interface ClassObj { - name: string; - funcs: FuncItem[]; -} - -export interface ParseObj { - classList: ClassObj[]; - enumList: EnumItem[]; - typeList: TypeItem[]; -} +const NUMBER_TYPE = 148; +const STRING_TYPE = 152; +const BOOLEAN_TYPE = 134; +const VOID_TYPE = 114; +const ARRAY_TYPE = 185; +const OBJECT_TYPE = 180; let gchecker: ts.TypeChecker; -function getTypeAliasSubtypes(typeAlias: ts.TypeAliasDeclaration, list: ParamItem[]) { +function getTypeAliasSubtypes(typeAlias: ts.TypeAliasDeclaration, list: ParamObj[]) { // 检查类型是否为类型节点 const typeNode = typeAlias.type; // console.log('getTypeAliasSubtypes'); @@ -102,6 +77,7 @@ function getTypeAliasSubtypes(typeAlias: ts.TypeAliasDeclaration, list: ParamIte list.push({ type: kindStr, name: nameObj.escapedText, + arraySize: 0 }) return `(${nameObj.escapedText}:${kindStr})`; }); @@ -114,18 +90,55 @@ function getTypeAliasSubtypes(typeAlias: ts.TypeAliasDeclaration, list: ParamIte return []; } +function getParamType(paramType: any) { + if (paramType === undefined) { + return 'void'; + } + let paramText = paramType.kind === NUMBER_TYPE ? 'number' : // 类型为 number + paramType.kind === STRING_TYPE ? 'string' : // 类型为 string + paramType.kind === BOOLEAN_TYPE ? 'boolean' : // 类型为 boolean + paramType.kind === VOID_TYPE ? 'void' : + 'any'; // 默认any类型 + if (paramType.kind === OBJECT_TYPE) { + const type = paramType.typeName.escapedText; + if (paramType.typeArguments) { + const subType = paramType.typeArguments[0].kind === NUMBER_TYPE ? 'number' : + paramType.typeArguments[0].kind === STRING_TYPE ? 'string' : + paramType.typeArguments[0].kind === BOOLEAN_TYPE ? 'boolean' : 'any'; + if (type === 'Array') { + paramText = 'Array<' + subType + '>'; + } + } else { + return type + } + } + if (paramType.kind === ARRAY_TYPE) { + const subType = paramType.elementType.kind === NUMBER_TYPE ? 'number' : + paramType.elementType.kind === STRING_TYPE ? 'string' : + paramType.elementType.kind === BOOLEAN_TYPE ? 'boolean' : + 'any'; + paramText = 'Array<' + subType + '>'; + } + return paramText; +} + export function parseTsFile(filePath: string): ParseObj { let parseRes: ParseObj = { - classList: [], - enumList: [], - typeList: [], + enums: [], + unions: [], + structs: [], + classes: [], + funcs: [], + types: [], } function visitor(node: ts.Node) { if (ts.isClassDeclaration(node) && node.name) { console.log(`Class: ${node.name.text}, ${node.members}`); let classItem: ClassObj = { name: node.name.text, - funcs: [], + alias: '', + functionList: [], + variableList: [] }; try { node.members.forEach(member => { @@ -140,6 +153,7 @@ export function parseTsFile(filePath: string): ParseObj { let returnObjStr = JSON.stringify(member.type); // console.log(`returnObjStr: ${returnObjStr} `); let returnObj = JSON.parse(returnObjStr); + returnStr = getParamType(member.type); if (returnObj.typeName) { let returnNameStr = JSON.stringify(returnObj.typeName); let returnName = JSON.parse(returnNameStr).escapedText; @@ -162,15 +176,17 @@ export function parseTsFile(filePath: string): ParseObj { returnStr = `${returnName} <${returnArgs}>` }; } - let paramResList: ParamItem[] = []; + let paramResList: ParamObj[] = []; const params = member.parameters.map(param => { // `${param.name}: ${param.type ? param.type : 'any'}` let paramObjStr = JSON.stringify(param.name); let paramStr = JSON.parse(paramObjStr).escapedText; let paramTypeStr: string = 'any'; + if (param.type) { let paramTypeObjStr = JSON.stringify(param.type); // console.log(`paramTypeObjStr: ${paramTypeObjStr} }`); + paramTypeStr = getParamType(param.type); if (JSON.parse(paramTypeObjStr).typeName) { paramTypeStr = JSON.parse(paramTypeObjStr).typeName.escapedText; } @@ -178,17 +194,29 @@ export function parseTsFile(filePath: string): ParseObj { paramResList.push({ name: paramStr, type: paramTypeStr, + arraySize: 0 }) return `${paramStr}: ${paramTypeStr}` }).join(', '); console.log(` Method: ${methodName}, Return Type: ${returnStr}, Parameters: ${params}`); - classItem.funcs.push({ + classItem.functionList.push({ name: methodName, returns: returnStr, parameters: paramResList, + type: '', }); - parseRes.classList.push(classItem); + } else if (ts.isPropertyDeclaration(member) || ts.isPropertyAssignment(member)) { // 判断是否是类的成员变量 + if ('type' in member && 'text' in member.name) { + let paramTypeText = getParamType(member.type); + let parameter: ParamObj = { + name: member.name.text, + type: paramTypeText, + arraySize: 0 + } + classItem.variableList.push(parameter); + } } + parseRes.classes.push(classItem); }); } catch (error) { console.error('Error processing node:', error); @@ -196,32 +224,64 @@ export function parseTsFile(filePath: string): ParseObj { } else if (ts.isEnumDeclaration(node) && node.name) { try { console.log(`Enum: ${node.name.text}`); - let enumItem: EnumItem = { + let enumItem: EnumObj = { name: node.name.text, - subItemList: [], + alias: '', + members: [], }; // console.log(`Enum: ${node.name.text}, ${node.members.length}`); node.members.forEach(member => { const memJsonStr = JSON.stringify(member.name); const memJsonObj = JSON.parse(memJsonStr); // console.log(`Member: ${memJsonObj.escapedText}`) - enumItem.subItemList.push(memJsonObj.escapedText); + enumItem.members.push(memJsonObj.escapedText); }) - parseRes.enumList.push(enumItem); + parseRes.enums.push(enumItem); } catch (error) { console.error('Error processing node:', error); } - } else if (ts.isTypeAliasDeclaration(node) && node.name) { console.log(`Type: ${node.name.text}`); - let typeItem: TypeItem = { + let typeItem: TypeObj = { name: node.name.text, - subItemList: [], + alias: getParamType(node.type), + members: [], }; // console.log(`Type: ${node.name.text}, ${node.typeParameters} ${typeof(node.type)}`); - const subtypes = getTypeAliasSubtypes(node, typeItem.subItemList); - parseRes.typeList.push(typeItem); + const subtypes = getTypeAliasSubtypes(node, typeItem.members); + parseRes.types!.push(typeItem); console.log(`subtypes : ${subtypes}`); + } else if (ts.isFunctionDeclaration(node) && node.name) { + console.log(`Type: ${node.name.text}`); + const parameters = node.parameters; + let parames: ParamObj[] = []; + parameters.forEach(param => { + let paramName = ''; + if ('text' in param.name) { + paramName = param.name.text; // 参数名称,如 "v1" + } + const paramType = param.type; // 参数类型节点 + let paramText = getParamType(paramType); + + console.log(` ${paramName}: ${paramText}`); + let parameter: ParamObj = { + name: paramName, + type: paramText, + arraySize: 0 + } + parames.push(parameter); + }); + + // 获取返回值类型 + const returnTypeNode = node.type; + let returnTypeText = getParamType(returnTypeNode); + let funcItem: FuncObj = { + name: node.name.text, + returns: returnTypeText, + parameters: parames, + type: '', + } + parseRes.funcs.push(funcItem); } ts.forEachChild(node, visitor); } diff --git a/src/vscode_plugin/src/template/dtscpp/dts2cpp_h_template.ts b/src/vscode_plugin/src/template/dtscpp/dts2cpp_h_template.ts new file mode 100644 index 0000000000000000000000000000000000000000..380e461839ecb7b6c36e642937b243d0446d2ee2 --- /dev/null +++ b/src/vscode_plugin/src/template/dtscpp/dts2cpp_h_template.ts @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 { FileTemp } from "../../datatype"; + +export let dts2hTemplate: FileTemp = { + name: '[fileName].h', + content: ` + // Business h file + ` +} \ No newline at end of file diff --git a/src/vscode_plugin/src/template/dtscpp/dtscppdir.ts b/src/vscode_plugin/src/template/dtscpp/dtscppdir.ts index 0c0b1dc7c0bd228d663bdc7fec690049cb6be1c9..750343888fbf2a5990fb0a90b1dfbcd1e1c7211a 100644 --- a/src/vscode_plugin/src/template/dtscpp/dtscppdir.ts +++ b/src/vscode_plugin/src/template/dtscpp/dtscppdir.ts @@ -14,6 +14,7 @@ */ import { DirTemp } from "../../datatype"; +import { dts2hTemplate } from "./dts2cpp_h_template"; import { napiCommonCppTemplate } from "./dtscpp_commoncpp_template"; import { napiCommonHTemplate } from "./dtscpp_commonh_template"; import { indexdtsTemplate } from "./dtscpp_dts_template"; @@ -51,4 +52,16 @@ export let dtscppout: DirTemp = { name: 'testh2dtscpp', files: [dtscppReadmeTemplate], dirs: [dtscpp_cppdir, dtscpp_etsdir] +} + +export let dts2cpp_cppdir: DirTemp = { + name: 'cpp', + files: [napiCommonHTemplate, napiCommonCppTemplate, napiHTemplate, napiInitTemplate, napiCppTemplate, dts2hTemplate], + dirs: [] +} + +export let cppout: DirTemp = { + name: 'testdts2cpp', + files: [], + dirs: [dts2cpp_cppdir, dtscpp_etsdir] } \ No newline at end of file diff --git a/src/vscode_plugin/src/template/functypemap_template.ts b/src/vscode_plugin/src/template/functypemap_template.ts index d0f12922ff57508bb12dd94fe45e353173351b73..38be3c96e93551a86650b3397df74a90848b2ee8 100644 --- a/src/vscode_plugin/src/template/functypemap_template.ts +++ b/src/vscode_plugin/src/template/functypemap_template.ts @@ -129,3 +129,19 @@ export let idlTransferType: FuncTransferMap[] = [ tranferContent: ['String'] }, ] + +// 将ts type转换为 c type +export let tsTransferType: FuncTransferMap[] = [ + { + fromType: 'boolean', + tranferContent: ['bool'] + }, + { + fromType: 'string', + tranferContent: ['std::string'] + }, + { + fromType: 'number', + tranferContent: ['int32_t', 'uint32_t', 'int', 'int64_t', 'uint64_t'] + } +] diff --git a/src/vscode_plugin/test/testdts.d.ts b/src/vscode_plugin/test/testdts.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..a773eeca8606e91e9fd4aa1d5b3863b087a4ec68 --- /dev/null +++ b/src/vscode_plugin/test/testdts.d.ts @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. +*/ + +type MyType = number; +export class test +{ + a: string; + b: number; + c: boolean; +} +export function testFunc(v1: string, v2: boolean, v3: MyType): test; \ No newline at end of file