• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2/*
3* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16import { FuncObj, GenInfo, ParamObj } from "../datatype";
17import { classMethodGetParamTemplate, classMethodNoParamTemplate, classMethodTemplate, classPropertyGetTemplate,
18  classPropertySetTemplate, classTemplate, funcGetParamTemplate, napiFuncCppTemplate, napiFuncRetTemplate,
19  paramGenTemplate } from "../../template/func_template";
20import { replaceAll } from "../../common/tool";
21import * as path from 'path';
22import * as fs from 'fs';
23import { transCkey2NapiInkey, transCkey2NapiOutkey } from "./gencommonfunc";
24
25export function genClassMethodContent(funcInfo: FuncObj, className: string, classMethodContent: string) {
26  let methodContent = replaceAll(classMethodTemplate, '[class_method_name_replace]', funcInfo.name);
27  methodContent = replaceAll(methodContent, '[class_name_replace]', className);
28  if (funcInfo.parameters.length <= 0) {
29    methodContent = replaceAll(methodContent, '[class_method_param_in]', classMethodNoParamTemplate);
30  } else {
31    // 方法入参替换
32    let paramGenResult = '';
33    let methodParamIn = replaceAll(classMethodGetParamTemplate, '[param_count_replace]', 'PARAMS' + funcInfo.parameters.length);
34    for (let i = 0; i < funcInfo.parameters.length; ++i) {
35      // 这里是入参替换 比如输入2个参数 double/int  napi_get_double_value/ napi_get_int32_value
36      let getParamInTemplate = transCkey2NapiInkey(funcInfo.parameters[i].type);
37      // 如果getParamInTemplate是空,则默认是对象输入,不做任何处理
38      if (getParamInTemplate === '') {
39        paramGenResult += '// Todo: handle object input.\n';
40        continue;
41      }
42      let getParam = replaceAll(getParamInTemplate, '[param_index_replace]',
43        'PARAMS' + i);
44      getParam = replaceAll(getParam, '[param_name_replace]',
45        funcInfo.parameters[i].name);
46      let paramGen = replaceAll(paramGenTemplate, '[param_index_replace]',
47        'PARAMS' + i);
48      paramGen = replaceAll(paramGen, '[param_name_replace]',
49        funcInfo.parameters[i].name);
50      paramGen = replaceAll(paramGen, '[getParam_replace]', getParam);
51      paramGenResult += paramGen;
52    }
53    // 替换get param in
54    methodParamIn = replaceAll(methodParamIn, '[class_method_get_param]', paramGenResult);
55    methodContent = replaceAll(methodContent, '[class_method_param_in]', methodParamIn);
56  }
57  // 方法返回值替换
58  let returnGenResult = genCppReturnGen(funcInfo);
59  methodContent = replaceAll(methodContent, '[class_method_return]', returnGenResult);
60  // 该class的所有成员方法内容拼接起来
61  classMethodContent += methodContent;
62  return classMethodContent;
63}
64
65export function genClassGetSetContent(variableInfo: ParamObj, className: string, classPropertyGetSetContent: string) {
66  let name = variableInfo.name.toLocaleLowerCase();
67  name = name.substring(0, 1).toLocaleUpperCase() + name.substring(1);
68  // class的属性get函数生成
69  let getPropertyContent = replaceAll(classPropertyGetTemplate, '[class_property_name_replace]', name);
70  getPropertyContent = replaceAll(getPropertyContent, '[class_name_replace]', className);
71  let returnGetfuncContent = transCkey2NapiOutkey(variableInfo.type);
72  returnGetfuncContent = replaceAll(returnGetfuncContent, '[return_name_replace]', variableInfo.name);
73  getPropertyContent = replaceAll(getPropertyContent, '[class_property_get]', returnGetfuncContent);
74  classPropertyGetSetContent += getPropertyContent;
75  // class的属性set函数生成
76  let setPropertyContent = replaceAll(classPropertySetTemplate, '[class_property_name_replace]', name);
77  setPropertyContent = replaceAll(setPropertyContent, '[class_name_replace]', className);
78  let returnSetfuncContent = transCkey2NapiInkey(variableInfo.type);
79  returnSetfuncContent = replaceAll(returnSetfuncContent, '[param_index_replace]', 'PARAMS0');
80  returnSetfuncContent = replaceAll(returnSetfuncContent, '[param_name_replace]', variableInfo.name);
81  setPropertyContent = replaceAll(setPropertyContent, '[class_property_set]', returnSetfuncContent);
82  classPropertyGetSetContent += setPropertyContent;
83  return classPropertyGetSetContent;
84}
85
86// 方法输入参数的处理,只处理基本类型,像数组/map/set/class/struct等都全部当作
87// object,且不做处理
88export function getCppParamGen(funcInfo: FuncObj): string {
89  // 处理输入的参数,生成napi的参数处理代码
90  if (funcInfo.parameters.length === 0) {
91    return '// no input params';
92  }
93
94  // 下面这段代码是不是可以优化一下,把下面这段代码提取出来,放到一个函数中,class与struct生成成员方法的时候也可以调用
95  let paramGenResult = '';
96  for (let i = 0; i < funcInfo.parameters.length; ++i) {
97    let getParamInTemplate = transCkey2NapiInkey(funcInfo.parameters[i].type);
98    // 如果getParamInTemplate是空,则默认是对象输入,不做任何处理
99    if (getParamInTemplate === '') {
100      paramGenResult += '// Todo: handle object input.\n';
101      continue;
102    }
103    let getParam = replaceAll(getParamInTemplate, '[param_index_replace]',
104      'PARAMS' + i);
105    getParam = replaceAll(getParam, '[param_name_replace]',
106      funcInfo.parameters[i].name);
107    let paramGen = replaceAll(paramGenTemplate, '[param_index_replace]',
108      'PARAMS' + i);
109    paramGen = replaceAll(paramGen, '[param_name_replace]',
110      funcInfo.parameters[i].name);
111    paramGen = replaceAll(paramGen, '[getParam_replace]', getParam);
112    paramGenResult += paramGen;
113  }
114  let genParamReplace = replaceAll(funcGetParamTemplate, '[param_length]',
115    'PARAMS' + funcInfo.parameters.length);
116  genParamReplace = replaceAll(genParamReplace, '[func_name_replace]',
117    funcInfo.name);
118  genParamReplace = replaceAll(genParamReplace, '[getAllParam_replace]',
119    paramGenResult);
120  return genParamReplace
121}
122
123// 方法返回值的处理
124export function genCppReturnGen(funcInfo: FuncObj): string {
125  // 如果函数返回值是空,直接返回NULL
126  if (funcInfo.returns === 'void') {
127    return '    return NULL;\n';
128  }
129  let returnName = funcInfo.name;
130  let funcReturnReplace = replaceAll(napiFuncRetTemplate, '[return_name]',
131    returnName);
132  let retGenResult = transCkey2NapiOutkey(funcInfo.returns);
133  retGenResult = replaceAll(retGenResult, '[return_name_replace]', returnName);
134  funcReturnReplace = replaceAll(funcReturnReplace, '[func_name_replace]',
135    funcInfo.name);
136  funcReturnReplace = replaceAll(funcReturnReplace, '[return_replace]',
137    retGenResult);
138  return funcReturnReplace;
139}
140
141export function doGenNapiCppFile(rootInfo: GenInfo, fileContent: string) {
142    let napiCppContent = '';
143
144    // class的实现
145    if (rootInfo.parseObj && rootInfo.parseObj.classes) {
146      let classesContent = '';
147      rootInfo.parseObj.classes.forEach(classInfo => {
148        // 拿到每个class的信息 这里是类的主体
149        let className = classInfo.name; // class的名字
150        let classInfoContent = replaceAll(classTemplate, '[class_name_replace]', className)
151
152        let classPropertyGetSetContent = '';
153        // class中属性的生成 把一个class的所有属性都生成对应的get set函数
154        classInfo.variableList.forEach(variableInfo => {
155          classPropertyGetSetContent = genClassGetSetContent(variableInfo, className, classPropertyGetSetContent);
156        });
157        classInfoContent = replaceAll(classInfoContent, '[class_property_get_set_replace]',
158          classPropertyGetSetContent)
159
160        let classMethodContent = '';
161        // class中方法的生成 把一个class的所有方法都生成对应的函数
162        classInfo.functionList.forEach(funcInfo => {
163          // 替换每个方法主体 生成每个方法的函数
164          classMethodContent = genClassMethodContent(funcInfo, className, classMethodContent);
165        });
166        classInfoContent = replaceAll(classInfoContent, '[class_method_content_replace]',
167          classMethodContent);
168        // 所有class拼接起来
169        classesContent += classInfoContent;
170      });
171      // 将class的生成内容写入cpp文件
172      napiCppContent += classesContent;
173    }
174
175    // struct的实现
176    if (rootInfo.parseObj && rootInfo.parseObj.structs) {
177      // structs的生成内容
178      let structsContent = '';
179      rootInfo.parseObj.structs.forEach(structInfo => {
180        let className = structInfo.name;
181        let structInfoContent = replaceAll(classTemplate, '[class_name_replace]', className)
182
183        let classPropertyGetSetContent = '';
184        // struct中属性的生成 把一个struct的所有属性都生成对应的get set函数
185        structInfo.members.forEach(variableInfo => {
186          classPropertyGetSetContent = genClassGetSetContent(variableInfo, className, classPropertyGetSetContent);
187        });
188        structInfoContent = replaceAll(structInfoContent, '[class_property_get_set_replace]',
189          classPropertyGetSetContent)
190
191        let structMethodContent = '';
192        // struct中方法的生成 把一个class的所有方法都生成对应的函数
193        structInfo.functions.forEach(funcInfo => {
194          // 替换每个方法主体 生成每个方法的函数
195          structMethodContent = genClassMethodContent(funcInfo, className, structMethodContent);
196        });
197        structInfoContent = replaceAll(structInfoContent, '[class_method_content_replace]',
198          structMethodContent);
199        // 所有struct拼接起来
200        structsContent += structInfoContent;
201      });
202      // 将struct的生成内容写入cpp文件
203      napiCppContent += structsContent;
204    }
205
206    // funcs的napi实现
207    if (rootInfo.parseObj && rootInfo.parseObj.funcs) {
208      rootInfo.parseObj.funcs.forEach(funcInfo => {
209        // 替换每个方法主体
210        let hFileName = path.basename(rootInfo.rawFilePath);
211        let bodyReplace = replaceAll(napiFuncCppTemplate, '[func_name_replace]',
212          funcInfo.name);
213        bodyReplace = replaceAll(bodyReplace, '[get_error_msg_tag]',
214          funcInfo.name);
215        bodyReplace = replaceAll(bodyReplace, '[file_introduce_replace]',
216          hFileName);
217        // 生成方法注释
218        let funcInfoParams = funcInfo.parameters.length > 0 ? '' : 'void';
219        let funcInfoParamTemp = '[paramName]: [paramType]; ';
220        for (let i = 0; i < funcInfo.parameters.length; i++) {
221          let funcInfoParamReplace = replaceAll(funcInfoParamTemp, '[paramName]',
222            funcInfo.parameters[i].name);
223          funcInfoParamReplace = replaceAll(funcInfoParamReplace, '[paramType]',
224            funcInfo.parameters[i].type);
225          funcInfoParams += funcInfoParamReplace;
226        }
227        bodyReplace = replaceAll(bodyReplace, '[input_introduce_replace]',
228          funcInfoParams === '' ? 'void' : funcInfoParams);
229        bodyReplace = replaceAll(bodyReplace, '[output_introduce_replace]',
230          funcInfo.returns);
231        // 方法参数的处理,解析参数类型,生成napi的参数处理代码
232        let paramGenResult = getCppParamGen(funcInfo);
233        bodyReplace = replaceAll(bodyReplace, '[func_getParam_replace]',
234          paramGenResult);
235        // 方法返回值的处理,解析返回值类型,生成napi的返回值处理代码
236        let returnGenResult = genCppReturnGen(funcInfo);
237        bodyReplace = replaceAll(bodyReplace, '[func_return_replace]',
238          returnGenResult);
239        // 组合一个个方法
240        napiCppContent += bodyReplace;
241      });
242    }
243
244    fileContent = replaceAll(fileContent, '[fileName]', rootInfo.fileName);
245    fileContent = replaceAll(fileContent, '[func_content_replace]', napiCppContent);
246    return fileContent;
247}
248export function genNapiCppFile(rootInfo: GenInfo, filePath: string,
249  fileContent: string) {
250  fileContent = doGenNapiCppFile(rootInfo, fileContent);
251  fs.writeFileSync(filePath, fileContent);
252}