• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15const { NapiLog } = require("../tools/NapiLog");
16const fs = require("fs");
17const os = require("os");
18const { AllParseFileList } = require("../tools/common");
19const path = require('path');
20
21function parseFileAll(hFilePath) {
22    let execSync = require("child_process").execSync;
23    let cmd = "";
24    if(fs.existsSync("./hdc/service/service-gen/src/gen/header_parser.py")) {
25        // call python file (for debug test)
26        cmd = "python ./hdc/service/service-gen/src/gen/header_parser.py " + hFilePath;
27    } else {
28        // call exe file (for real runtime)
29        let sysInfo = os.platform();
30        let execPath = path.dirname(process.execPath);
31        let exeFile = sysInfo === 'win32' ? path.join(execPath, "header_parser.exe") :
32                                            path.join(execPath, "header_parser");
33        cmd = exeFile + " " + hFilePath;
34    }
35
36    let parseResult = null;
37    let stdout = execSync(cmd);
38    parseResult = JSON.parse(stdout.toString()).result;
39    parseResult.rawContent = fs.readFileSync(hFilePath, 'UTF-8');
40    return parseResult;
41}
42
43function analyzeNameSpace(rootInfo, parseResult) {
44    if (parseResult.namespaces.length == 0) {
45        return;
46    }
47    let lastNameSpace = parseResult.namespaces[parseResult.namespaces.length - 1];
48    rootInfo.nameSpace = lastNameSpace.split('::');
49}
50
51function createParam(parseParamInfo) {
52    let param = {};
53    param.name = parseParamInfo.name;
54    param.type = parseParamInfo.reference ? parseParamInfo.type.replace("&", "").trim(): parseParamInfo.type
55    param.rawType = parseParamInfo.raw_type;
56    param.isPointer = (parseParamInfo.pointer == 1);
57    param.isReference = (parseParamInfo.reference == 1);
58    param.isArray = (parseParamInfo.array == 1);
59    param.isConstant = (parseParamInfo.constant == 1);
60    return param;
61}
62
63function createFuncInfo(parseFuncInfo) {
64    let funcInfo = {
65        "name": "", // 方法名
66        "params": [], // 参数列表
67        "retType": "", // 返回值
68        "rawStr": "" // 方法原始代码
69    }
70    funcInfo.name = parseFuncInfo.name;
71
72    let parseParams = parseFuncInfo.parameters;
73    for(var i = 0; i < parseParams.length; ++i) {
74        let param = createParam(parseParams[i]);
75        funcInfo.params.push(param);
76    }
77
78    funcInfo.retType = parseFuncInfo.returns === '' ? parseFuncInfo.rtnType : parseFuncInfo.returns;
79    funcInfo.rawStr = parseFuncInfo.debug;
80    return funcInfo;
81}
82
83function createClassFunctions(parseFuncs) {
84    let funcList = [];
85    for(var i = 0; i < parseFuncs.length; ++i) {
86        if (!(parseFuncs[i].constructor || parseFuncs[i].destructor)) { // 构造和析构方法不需要生成remote接口代码
87            let funcInfo = createFuncInfo(parseFuncs[i]);
88            funcList.push(funcInfo);
89        }
90    }
91    return funcList;
92}
93
94function createClassInfo(parseClassInfo) {
95    let classInfo = {
96        "name": "",
97        "namespace": [],
98        "properties": [],
99        "functions": [],
100        "extends":[]
101    }
102    classInfo.name = parseClassInfo.name;
103    classInfo.namespace = parseClassInfo.namespace.split('::');
104    classInfo.functions = createClassFunctions(parseClassInfo.methods.public);
105
106    return classInfo;
107}
108
109function analyzeClasses(rootInfo, parseClasses) {
110    if (parseClasses.length == 0) {
111        NapiLog.logError("Can not find any class.");
112        return;
113    }
114
115    let firstClassName = null; // JSON集合中第一个class名称
116    let serviceClassName = null;// JSON集合中带“@ServiceClass”注解的class名称
117    let i = 0;
118    for(var className in parseClasses) {
119        if (++i == 1) {
120            firstClassName = className;
121        }
122
123        let doxygen = parseClasses[className].doxygen;
124        if (doxygen && doxygen.includes("@ServiceClass")) {
125            serviceClassName = className;
126            break;
127        }
128    }
129
130    if (parseClasses.length == 1) {
131        // h文件中只有唯一的一个类,基于该类的接口定义生成service
132        rootInfo.serviceName = firstClassName;
133        let classInfo = createClassInfo(parseClasses[firstClassName]);
134        rootInfo.class.push(classInfo);
135    } else {
136        // h文件中有多个类,基于带@ServiceClass注解的类生成service
137        if (serviceClassName == null) {
138            NapiLog.logError("There must be one class that contains @ServiceClass annotations.");
139            return;
140        }
141        rootInfo.serviceName = serviceClassName;
142        let classInfo = createClassInfo(parseClasses[serviceClassName]);
143        rootInfo.class.push(classInfo);
144    }
145}
146
147function doAnalyze(hFilePath, cmdParam) {
148    let parseResult = parseFileAll(hFilePath);
149    parseResult.isInclude = false;
150    AllParseFileList.push(parseResult);
151    let rootInfo = {
152        "serviceName": "",
153        "nameSpace": [],
154        "class": [],
155        "includes": [],
156        "using": [],
157        "serviceId": cmdParam.serviceId == null ? "9002" : cmdParam.serviceId,
158        "rawContent": parseResult.rawContent
159    }
160
161    analyzeNameSpace(rootInfo, parseResult);
162    analyzeClasses(rootInfo, parseResult.classes);
163    rootInfo.includes = parseResult.includes;
164    rootInfo.using = parseResult.using;
165    return rootInfo;
166}
167
168module.exports = {
169    doAnalyze
170}
171