Skip to content

Commit

Permalink
更新了cpp , cs 代码分析逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwang committed Dec 5, 2019
1 parent dae2814 commit 815e7b3
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 13 deletions.
19 changes: 16 additions & 3 deletions src/code/server/codeCompleting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ export class CodeCompleting {
return completeItem;
}

private static commentVarTypeTips(uri: string, line: number): CompletionItem {
//TODO 这里要加入判断一下本行有没有数据
let completeItem = {
label: "@type",
kind: CompletionItemKind.Snippet,
insertText: "@type ",
detail: "comment var type",
insertTextFormat: InsertTextFormat.Snippet
};
return completeItem;
}

//把字符串按. 或者 : 分割成数组。若不含: . 则数组中只有一个元素
private static splitStringwithTrigger(str){
let userInputTxt_DotToBlank = str.replace(/[\.:]/g, ' ');
Expand Down Expand Up @@ -253,10 +265,11 @@ export class CodeCompleting {
let prefix = Tools.getTextByPosition(luaText , pos);
// 文档注释
if (prefix == "---") {
if (Tools.isNextLineHasFunction(luaText, pos) == false) {
return completingArray;
if (Tools.isNextLineHasFunction(luaText, pos) == true) {
completingArray.push(this.getDocCommentCompletingItem(uri, pos.line + 1));
}
completingArray.push(this.getDocCommentCompletingItem(uri, pos.line + 1));

completingArray.push(this.commentVarTypeTips(uri, pos.line));
return completingArray;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import path = require('path');
import dir = require('path-reader');
import fs = require('fs');
import { parseAst, Language, Node } from 'univac';
import { Logger } from './codeLogManager';
import { CodeSymbol } from './codeSymbol';
import * as Tools from './codeTools';
import { Logger } from '../codeLogManager';
import { CodeSymbol } from '../codeSymbol';
import * as Tools from '../codeTools';

export class CppCodeProcessor {
// workspace 根目录,server初始化时设置。
Expand Down
32 changes: 32 additions & 0 deletions src/code/server/codeExport/nativeCodeExportBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as Tools from '../codeTools';
import { CodeSymbol } from '../codeSymbol';
import { CppCodeProcessor } from './cppCodeProcessor';
import { SluaCSharpProcessor } from './sluaCSharpProcessor';
import fs = require('fs');

//基类的作用是完成一些公共方法,对外暴露接口,屏蔽下层
export class NativeCodeExportBase {
// 导出文件存放根路径
private static _LuaPandaInterfaceIntelliSenseResPath;
public static get LuaPandaInterfaceIntelliSenseResPath() {
if(!this._LuaPandaInterfaceIntelliSenseResPath){
this._LuaPandaInterfaceIntelliSenseResPath = Tools.getVSCodeOpenedFolder() + "/.vscode/LuaPanda/IntelliSenseRes/";
}
return this._LuaPandaInterfaceIntelliSenseResPath;
}

// 加载原生接口导出的分析结果
public static loadIntelliSenseRes() {
// 如果文件存在,刷新
let dirPath = this.LuaPandaInterfaceIntelliSenseResPath;
if (fs.existsSync(dirPath)) {
CodeSymbol.refreshPreLoadSymbals(dirPath);
}
}

// 收到需要预处理的文件
public static processNativeCodeDir(anaPath){
CppCodeProcessor.processCppDir(anaPath);
SluaCSharpProcessor.processluaCSDir(anaPath);
}
}
155 changes: 155 additions & 0 deletions src/code/server/codeExport/sluaCSharpProcessor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import * as Tools from '../codeTools';
import { Logger } from '../codeLogManager';
import fs = require('fs');
import dir = require('path-reader');
import path = require('path');
import { CodeSymbol } from '../codeSymbol';

export class SluaCSharpProcessor {
private static _sluaCSharpInterfaceIntelliSenseResPath;

// 加载原生接口导出的分析结果
public static loadIntelliSenseRes() {
CodeSymbol.refreshPreLoadSymbals(this.sluaCSharpInterfaceIntelliSenseResPath);
}

// sluaUE的分析路径
public static get sluaCSharpInterfaceIntelliSenseResPath() {
if(!this._sluaCSharpInterfaceIntelliSenseResPath){
this._sluaCSharpInterfaceIntelliSenseResPath = Tools.getVSCodeOpenedFolder() + "/.vscode/LuaPanda/IntelliSenseRes/SluaCSharpInterface/";
}
return this._sluaCSharpInterfaceIntelliSenseResPath;
}

// 解析文件夹
public static processluaCSDir(cppDir: string) {
let intelLuaPath = this.sluaCSharpInterfaceIntelliSenseResPath;
if(!intelLuaPath){
Logger.ErrorLog('未打开文件夹,无法使用此功能!');
Tools.showTips('未打开文件夹,无法使用此功能!');
}

// 生成一个子目录对应用户代码路径
let subDir = cppDir;
subDir = subDir.replace(/\//g, ' ');
subDir = subDir.replace(/\\/g, ' ');
subDir = subDir.replace(/:/g, '');
subDir = subDir.trim();
subDir = subDir.replace(/ /g, '-');

// 移除已有文件夹
// this.removeCppInterfaceIntelliSenseRes(path.join(this.cppInterfaceIntelliSenseResPath, subDir));
// 读取用户路径下的文件列表
// let cppHeaderFiles = this.getCppHeaderFiles(cppDir);
// let cppSourceFiles = this.getCppSourceFiles(cppDir);

// 从cppDir中读出files列表
let files = this.getCSharpFiles(cppDir);

this.readSluaCSSymbols(files, subDir);
CodeSymbol.refreshPreLoadSymbals(intelLuaPath);
Tools.showTips('处理完成!');
}

private static getCSharpFiles(dirPath: string) {
let options = {
sync: true,
recursive: true,
valuetizer:function(stat:fs.Stats, fileShortName: string, fileFullPath: string) {
if (stat.isDirectory()) {
return fileFullPath;
}
return fileShortName.match(/\.cs$/)? fileFullPath : null;
}
};

return dir.files(dirPath, 'file', null, options);
}

public static readSluaCSSymbols(filepath, writepath){
let wtpath = this.sluaCSharpInterfaceIntelliSenseResPath + writepath;
this.makeDirSync(wtpath);
// 读取文件内容
for (const file of filepath) {
let codeTxt = Tools.getFileContent(file);
if(codeTxt){
let luaTxt = this.parseSluaCSSymbols(codeTxt);
if(luaTxt && luaTxt != ""){
let aaac = wtpath + '/' + path.basename(file, "cs") + "lua";
fs.writeFileSync(aaac, luaTxt);
}
}
}
}

private static makeDirSync(dirPath: string) {
if (fs.existsSync(dirPath)) {
return;
}
let baseDir = path.dirname(dirPath);
this.makeDirSync(baseDir);
fs.mkdirSync(dirPath);
}

public static parseSluaCSSymbols(codeTxt){
let currentClass; //当前文件中的类
let parentClass; //父类
let members = []; //类中的成员
//用正则分析出主成员和继承关系
let createTypeMetatableREG = /createTypeMetatable\((.*)\)/;
let dver = codeTxt.match(createTypeMetatableREG);
if(!dver) return;

if(dver && dver.length === 2){
let paramsArray = dver[1].split(',');
if(paramsArray.length === 3){
// 无继承关系
currentClass = paramsArray[2].trim().match(/typeof\((.*)\)/)[1];
}else if(paramsArray.length === 4){
// 有继承关系
currentClass = paramsArray[2].trim().match(/typeof\((.*)\)/)[1];
parentClass = paramsArray[3].trim().match(/typeof\((.*)\)/)[1].replace('_','.');
}
}

//获取所有成员
let memberREG = /addMember\((.*?)\)/g;
let dver2 = codeTxt.match(memberREG);
if(dver2) {
for (const mems of dver2) {
let paras = mems.match(/addMember\(l,("(.*?)"|(.*?))(,|\))/);
if(paras[2]){
//函数 addMember(l,getItem);\n\
let functionObj = new Object();
functionObj['var'] = paras[2] ;
functionObj['type'] = "variable";
members.push(functionObj);
}else if(paras[3]){
//成员 addMember(l,"name",get_name,set_name,true);\n\
let varObj = new Object();
varObj['var'] = paras[3] + '()';
varObj['type'] = "function";
members.push(varObj);
}
}
}

// 构建lua文本
let luaCode = currentClass + " = {}";
if(parentClass){
luaCode += " ---@type " + parentClass;
}
luaCode += '\n'
for (const oneMember of members) {
if (oneMember.type === "variable") {
luaCode += currentClass + '.' + oneMember.var + ' = nil\n';
}else if(oneMember.type === "function"){
luaCode += "function " + currentClass + '.' + oneMember.var + ' end\n';
}

}
// luaCode 写入文件
console.log(luaCode);
return luaCode;
}
}
6 changes: 5 additions & 1 deletion src/code/server/codeSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,14 @@ export class CodeSymbol {
//在预制文档中搜索
public static searchPreLoadSymbols(symbolStr, searchMethod){
let retSymbols = new Array<Tools.SymbolInformation>();

this.preLoadSymbolMap.forEach(element => {
let res = element.searchMatchSymbal(symbolStr, searchMethod, Tools.SearchRange.AllSymbols);
retSymbols = retSymbols.concat(res);
if(res.length > 0){
retSymbols = retSymbols.concat(res);
}
});

return retSymbols;
}

Expand Down
8 changes: 8 additions & 0 deletions src/code/server/codeTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ export function getVScodeExtensionPath(){
return VScodeExtensionPath;
}

let VSCodeOpenedFolder;
export function getVSCodeOpenedFolder(){
if(!VSCodeOpenedFolder){
VSCodeOpenedFolder = initParameter.rootPath;
}
return VSCodeOpenedFolder;
}

export function setVScodeExtensionPath(_VScodeExtensionPath:string){
VScodeExtensionPath = _VScodeExtensionPath;
}
Expand Down
12 changes: 6 additions & 6 deletions src/code/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ import { CodeEditor } from './codeEditor';
import { CodeFormat } from './codeFormat';
import { CodeLinting } from './codeLinting';
import { CodeReference } from './codeReference';
import { CppCodeProcessor } from './cppCodeProcessor';

import { NativeCodeExportBase } from './codeExport/nativeCodeExportBase';

// Create a connection for the server. The connection uses Node's IPC as a transport.
// Also include all preview / proposed LSP features.
Expand Down Expand Up @@ -100,7 +99,6 @@ connection.onInitialize((initPara: InitializeParams) => {
Tools.setInitPara(initPara);
Tools.setToolsConnection(connection);
Logger.connection = connection;
CppCodeProcessor.setWorkspaceRootPath(initPara.rootPath);

Logger.DebugLog(Tools.getInitPara().rootPath);

Expand All @@ -123,8 +121,8 @@ connection.onInitialize((initPara: InitializeParams) => {
// 分析默认位置(扩展中)的lua文件
let resLuaPath = Tools.getVScodeExtensionPath() + '/res/lua'; //安装插件后地址
CodeSymbol.refreshPreLoadSymbals(resLuaPath);
CppCodeProcessor.loadIntelliSenseRes();

// 分析导出接口文件
NativeCodeExportBase.loadIntelliSenseRes();
Logger.DebugLog("init success");

//读取标记文件,如果关闭了标记,那么
Expand Down Expand Up @@ -173,7 +171,7 @@ connection.onInitialize((initPara: InitializeParams) => {
connection.onNotification("preAnalysisCpp", (message) =>{
let msgObj = JSON.parse(message);
let anaPath = msgObj['path'];
CppCodeProcessor.processCppDir(anaPath);
NativeCodeExportBase.processNativeCodeDir(anaPath);
});

connection.onInitialized(() => {
Expand Down Expand Up @@ -257,6 +255,8 @@ connection.onDocumentSymbol(
let uri = handler.textDocument.uri;
let decUri = Tools.urlDecode(uri);
let retSyms = CodeSymbol.getCertainDocSymbolsReturnArray(decUri, null, Tools.SearchRange.AllSymbols);
// Tools.createTrieTree(retSyms);

let retSymsArr: any[];
try {
retSymsArr = Tools.getOutlineSymbol(retSyms);
Expand Down

0 comments on commit 815e7b3

Please sign in to comment.