├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── License.txt ├── README.md ├── Template ├── FileTemplates │ └── TestTemplate.lua ├── LoadScript │ └── LoadScript.lua ├── funTemplate │ ├── CreateFunctionTemplate.lua │ └── CreateModuleFunctionTemplate.lua └── test.css ├── images ├── donate.html ├── index.html ├── loadScript.gif ├── logo.png ├── wechat.png └── zhifubao.JPG ├── luadebug ├── .DS_Store ├── DevSyncCode.lua ├── LuaDebug.lua ├── LuaDebug_luasockt2_0.lua └── LuaDebugjit.lua ├── package.json ├── runtime ├── .DS_Store ├── luajit │ └── win │ │ ├── lua51.dll │ │ └── luajit.exe ├── macosx │ ├── lua │ ├── luac │ └── test.lua ├── parseTemFile └── win │ ├── DebugConfig.lua │ └── lua51 │ ├── DebugStart.lua │ ├── LuaDebug.lua │ ├── lua.exe │ ├── lua51.dll │ ├── luac.exe │ ├── luac.out │ └── socket.dll ├── snippets └── snippets.json ├── src ├── Common.ts ├── ConstInfo.ts ├── debugger │ ├── BreakPointData.ts │ ├── Common.ts │ ├── DebugCommon.ts │ ├── LuaDebug.ts │ ├── LuaProcess.ts │ ├── ScopesManager.ts │ └── childProcess │ │ └── BaseChildProcess.ts ├── extension.ts ├── httpClient.ts └── luatool │ ├── FunctionCall.ts │ ├── LuaCheckDoEnd.ts │ ├── LuaCheckLuaInfos.ts │ ├── LuaCheckRepeat.ts │ ├── LuaCheckReturn.ts │ ├── LuaCheckUnary.ts │ ├── LuaChuckInfo.ts │ ├── LuaComment.ts │ ├── LuaForLogic.ts │ ├── LuaFuncitonCheck.ts │ ├── LuaFunctionParse.ts │ ├── LuaIfLogic.ts │ ├── LuaInfoManager.ts │ ├── LuaLeftCheck.ts │ ├── LuaParse.ts │ ├── LuaParseTool.ts │ ├── LuaSetValue.ts │ ├── LuaTableParse.ts │ ├── LuaValidateBracket_G.ts │ ├── LuaValidateBracket_M.ts │ ├── LuaValidateConstValue.ts │ ├── LuaValidateOperator.ts │ ├── LuaWhileLogic.ts │ ├── LuacCheck.ts │ ├── TokenInfo.ts │ ├── UserLoginCount.ts │ ├── Utils.ts │ ├── ex │ ├── AutoLuaComment.ts │ ├── ChangeCaseExtension.ts │ ├── CreateFunction.ts │ ├── CreateMoudleFunction.ts │ ├── ExFileUtils.ts │ ├── ExtensionManager.ts │ ├── LoadLuaScript.ts │ ├── LuaIdeConfigManager.ts │ ├── Template │ │ ├── CreateTemplateFile.ts │ │ ├── FunctionParameter.ts │ │ └── TemplateManager.ts │ └── UserInfo.ts │ ├── manager │ ├── CacheCompletionInfo.ts │ ├── CommentLuaCompletionManager.ts │ ├── FileCompletionItemManager.ts │ ├── LuaFileCompletionItems.ts │ ├── LuaGolbalCompletionManager.ts │ └── LuaSymbolInformation.ts │ ├── provider │ ├── LuaCompletionItemControler.ts │ ├── LuaCompletionItemFunControler.ts │ ├── LuaCompletionItemGolbalControler.ts │ ├── LuaCompletionItemProvider.ts │ ├── LuaCompletionItemProviderUtils.ts │ ├── LuaDefinitionProvider.ts │ ├── LuaDocumentSymbolProvider.ts │ ├── LuaFiledCompletionInfo.ts │ ├── LuaFormattingEditProvider.ts │ ├── LuaMode.ts │ ├── LuaReferenceProvider.ts │ ├── LuaSignatureHelpProvider.ts │ ├── ProviderUtils.ts │ └── format │ │ ├── LuaFormatChildProcess.ts │ │ └── LuaFormatParseTool.ts │ └── statistics │ └── StatisticsMain.ts ├── syntaxes └── Lua.plist ├── test ├── extension.test.ts └── index.ts ├── tsconfig.json ├── version ├── kangping.luaide-0.1.8.zip ├── lua-0.3.0.vsix ├── luaide-0.2.1.vsix └── luaide-0.2.2.vsix ├── vsc-extension-quickstart.md └── 注释规则.txt /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 11 | "stopOnEntry": false, 12 | "sourceMaps": true, 13 | "outDir": "${workspaceRoot}/out/src", 14 | "preLaunchTask": "npm" 15 | 16 | }, 17 | { 18 | "name": "debugServer", // https://code.visualstudio.com/docs/extensions/example-debuggers 19 | "type": "node", 20 | "request": "launch", 21 | "runtimeArgs": [ 22 | "--harmony" 23 | ], 24 | "program": "${workspaceRoot}/src/debugger/LuaDebug.ts", 25 | "stopOnEntry": false, 26 | "args": [ 27 | "--server=4711" 28 | ], 29 | "sourceMaps": true, 30 | "outDir": "${workspaceRoot}/out/src", 31 | "cwd":"${workspaceRoot}" 32 | 33 | }, 34 | { 35 | "name": "Launch Tests", 36 | "type": "extensionHost", 37 | "request": "launch", 38 | "runtimeExecutable": "${execPath}", 39 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], 40 | "stopOnEntry": false, 41 | "sourceMaps": true, 42 | "outDir": "${workspaceRoot}/out/test", 43 | "preLaunchTask": "npm" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false, // set this to true to hide the "out" folder with the compiled JS files 5 | "**/LuaIdeServer":true 6 | }, 7 | "search.exclude": { 8 | "out": true, // set this to false to include "out" folder in search results 9 | "**/LuaIdeServer":true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile", "--loglevel", "silent"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isWatching": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | vsc-extension-quickstart.md 10 | LuaIdeStatistics/** 11 | version/** 12 | LuaIdeServer/** 13 | 14 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation 2 | 3 | All rights reserved. 4 | 5 | MIT License 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # LuaIde 3 | 1. author:kangping 4 | 1. **luaIde** 是基于vscode开发的一款用于lua语言开发者使用的插件 5 | 1. 目标:致力于做最好的**跨平台**lua开发工具 6 | 1. 更新:luaide 个人开发者开发持续更新 (**更新频率为一周一更**) 7 | 1. 平台支持:**win**,**mac** 8 | 1. 代码调试:理论上只要支持 **luasocket** 就能调试 如果你的游戏引擎或 lua框架需要调试 请联系我 9 | 10 | 11 | # LuaIde 更新日志 12 | 13 | 14 | 1. 2017/6/25 0.3.3-0.37 版本 15 | 1. 方法返回值注释:`--@returnValue [Model.BaseModel]` 修改为 `--@return [Model.BaseModel]` 16 | 2. 将同文件中的变量由只提示方法内的改为 当前文件全局提示 17 | 3. 修复全局变量无法提示bug 18 | 3. 修改某些情况方法返回值无法提示bug 19 | 4. lua文件修改后在不保存的情况下搜索symbol定位错误 20 | 5. 添加用户在线数量显示,可通过 `luaide.showOnLine` 进行关闭 5分钟刷新一次 21 | 22 | 1. 1. 2017/6/15 0.3.2 版本 23 | 1. 修复添加新文件无法 无法在 require 和类型注释中提示的bug 24 | 2. 修复for 循环中的变量错误的解析为全局变量 25 | 3. 修复全局方法返回值 无法提示 26 | 4. 添加注释提示 27 | 5. 添加变量类型注释 `--@valueReference [Model.BaseModel] ` 当输入[ 会列出当前文件中所有的文件 28 | 4. 注释路径添加转到定义 29 | 5. 添加写入初始化信息 文件夹权限不足提示 30 | 1. 2017/6/8 0.3.0 版本 31 | 2. 增强代码推断能力,与0.2.x 版本用了两套逻辑 所以luaide 版本终结与0.2.1 以后待功能完善后 luaide将更名为luaIdeProfessional 32 | 3. 增加了 方法返回值 注释 和父类 类型注释 33 | 1. 方法返回值注释:`--@returnValue [Model.BaseModel]` 当输入[ 会列出当前文件中所有的文件 34 | 1. 父类类型注释:`--@parentClass [Model.BaseModel]` 当输入[ 会列出当前文件中所有的文件 35 | 1. 两种注释需要 添加luaide 的配置 "luaide.scriptRoots": ["C:/Users/Administrator/Desktop/t"] 36 | 37 | #重要提示 38 | 1. [LuaDebug 下载地址](https://github.com/k0204/LuaIde/tree/master/luadebug) 39 | 2. 文档请直接查看[wiki](https://github.com/k0204/LuaIde/wiki) 40 | 3. qq群 **494653114** 41 | 3. 调试文件为两个 LuaDebug,LuaDebugjit 添加调试文件时确认一下自己运行时选择对应的调试文件 42 | 4. bug 和 问题 请留言 [issues](https://github.com/k0204/LuaIde/issues) 43 | 4. [调试视频](https://github.com/k0204/LuaIde/wiki/%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B) 44 | 5. [历史版本](https://github.com/k0204/LuaIde/tree/master/version) 如果当前版本出现bug 可将 win->:\Users\Administrator\.vscode\extensions 和 mac->user/.vscode/extensions 中对应的文件夹删除将历史版本解压重启vscode 45 | 46 | #更新记录 47 | 1. 0.1.9->0.2.2 48 | 1. 修复模块方法创建 插入位置错误 修改为插入到当前方法结束后 49 | 2. 方法注释 @desc 无法显示bug 50 | 3. 优化 **require** 时 lua 文件路径提示 兼容 "xxx.xxx.xx" 和 自定义变量 注意如果需要显示"xxx.xxx.xxx" 需要设置 **luaide.scriptRoots** 51 | 4. 优化二进制lua文件导致的lua解析停止无法进行自动提示bug 52 | 5. 添加最大文件检查限制 **luaide.maxFileSize** 默认为2048KB 53 | 6. **luaide.moduleFunNestingCheck** 默认值修改为false -->该检测一定几率会检查错误,该问题将在0.2.1 修复 54 | 7. 添加文件夹右键菜单 **[创建模板文件]** 模板文件配置 请看 [安装](https://github.com/k0204/LuaIde/wiki/%E5%AE%89%E8%A3%85) --> **luaide.luaTemplatesDir** 55 | 8. 修正方法参数无法提示bug 56 | 9. 格式化代码后#与变量名中多出一个空格 修改 57 | 10. 修复由及时检查代码语法引起的 提示错误 58 | 1. 0.1.9->0.2.1 59 | 1. 添加 输入 **---** 自动生成方法注释 60 | 2. 优化方法信息提示 区分全局函数和局部函数 61 | 3. 优化 **require** 时 lua 文件路径提示 兼容 "xxx.xxx.xx" 和 自定义变量 注意如果需要显示"xxx.xxx.xxx" 需要设置 **luaide.scriptRoots** 62 | 4. 优化二进制lua文件导致的lua解析停止无法进行自动提示bug 63 | 5. 添加最大文件检查限制 **luaide.maxFileSize** 默认为2048KB 64 | 6. **luaide.moduleFunNestingCheck** 默认值修改为false -->该检测一定几率会检查错误,该问题将在0.2.1 修复 65 | 7. 添加文件夹右键菜单 **[创建模板文件]** 模板文件配置 请看 [安装](https://github.com/k0204/LuaIde/wiki/%E5%AE%89%E8%A3%85) --> **luaide.luaTemplatesDir** 66 | 8. 修正方法参数无法提示bug 67 | 9. 格式化代码后#与变量名中多出一个空格 修改 68 | 10. 修复由及时检查代码语法引起的 提示错误 69 | 1. 0.1.8 70 | 1. 根据 [guoweidong1987](https://github.com/guoweidong1987) 提供的方法修改lua代码格式化 71 | 2. 添加 **luaide.ChangeTextCheck** 代码修改时是否检查lua语法是否正确 72 | 3. 添加模块方法 **luaide.moduleFunNestingCheck** 模块方法嵌套检查,如果在一个方法中出现另外一个模块方法会认为是错误的 73 | 4. 修改**self** 提示bug 无法提示三级和三级以上的代码 如 **self.data.index** 74 | 5. 添加 **require** 时 lua 文件路径提示 75 | 76 | 1. 0.1.7 77 | 1. 添加显示介绍页面配置 **luaide.isShowDest** 默认为false 只显示一次,如需重复显示修改为true 78 | 2. 修改代码格式化 换行处理 和 " 转义 bug 79 | 3. 修改代码提示 function 方法中 定义的local 变量 无法提示 二级变量 的bug 80 | 4. 添加数据统计接口 统计在线人数, 如果有反感这一行为的请联系我,后期考虑添加配置 81 | 5. 优化debug 将 lua 和luajit 调试文件进行分离 coocs 和unity 如果使用luajit 的调试文件请使用luaDebugjit.lua 文件进行调试 调试文件地址为luadeubg/LuaDebug.lua or luadebug/Luadebugjit.lua 82 | 83 | 84 | 1. 0.1.6 修改代码格式化bug 85 | 1. 将源代码提交至github 86 | 87 | 88 | # 捐献 89 | 支持LuaIde的开发 可以通过微信 90 | ![IDE](https://coding.net/u/k0204/p/imgres/git/raw/master/money.png) 91 | -------------------------------------------------------------------------------- /Template/FileTemplates/TestTemplate.lua: -------------------------------------------------------------------------------- 1 | -- 2 | --版权所有:{company} 3 | -- Author:{author} 4 | -- Date: {time} 5 | -- 6 | local {moduleName} = class("{moduleName}") 7 | function {moduleName}:ctor() 8 | 9 | end 10 | --desc: 11 | --Author:{author} 12 | --date:{time} 13 | function {moduleName}:buttonClick(sender) 14 | 15 | end 16 | function {moduleName}:test1() 17 | 18 | end 19 | return {moduleName} -------------------------------------------------------------------------------- /Template/LoadScript/LoadScript.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/Template/LoadScript/LoadScript.lua -------------------------------------------------------------------------------- /Template/funTemplate/CreateFunctionTemplate.lua: -------------------------------------------------------------------------------- 1 | --@desc: 2 | --time:{time} 3 | {paramdesc} 4 | --return 5 | function {functionName}({param}) 6 | 7 | end -------------------------------------------------------------------------------- /Template/funTemplate/CreateModuleFunctionTemplate.lua: -------------------------------------------------------------------------------- 1 | --======================================= 2 | --@desc: 3 | --time:{time} 4 | {paramdesc} 5 | --return 6 | --======================================= 7 | function {moduleName}:{functionName}({param}) 8 | 9 | end -------------------------------------------------------------------------------- /Template/test.css: -------------------------------------------------------------------------------- 1 | p{ 2 | color: 0xfff 3 | } -------------------------------------------------------------------------------- /images/donate.html: -------------------------------------------------------------------------------- 1 | 2 | 谢谢你的支持! 3 |
4 | 5 | -------------------------------------------------------------------------------- /images/index.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | 欢迎使用luaIde 4 |

5 |

6 | luaIde 是基于vscode开发的一款用于lua语言开发者使用的插件
8 | 目标:致力于做最好的lua开发工具
9 | 作者:k0204(kangping)
10 | 更新:luaide 个人开发者开发 持续更新
11 | 是否开源:开源 (2017年3月28日将上传github)
12 | 平台支持:win,mac
13 |

14 |

15 | 开源地址:  16 | github 17 |   18 | 19 |

20 |

21 | 文档地址:wiki 23 |

24 |

25 | 演示视频地址: 26 |

27 |
    28 |
  1. 29 |

    30 | LuaIde-安装 31 |    32 |

    33 |
  2. 34 |
  3. 35 |

    36 | 下载Lua调试文件 37 |

    38 |
  4. 39 |
  5. 40 |

    41 | LuaIde mac 调试 cocos 42 |

    43 |
  6. 44 |
  7. 45 |

    46 | LuaIde mac ulua Debugger 47 |

    48 |
  8. 49 |
  9. 50 |

    51 | LuaIde Ulua Ios 调试视频 52 | 53 |

    54 |
  10. 55 |
  11. 56 |

    57 | cococ2dx 2.x windows调试视频 58 |

    59 |
  12. 60 |
  13. 61 |

    62 | cocos2dx 3.x windows 调试视频 63 |

    64 |
  14. 65 |
  15. 66 | 由于个人时间有限,后续会添加其他环境的演示视频 67 |

    68 |
    69 |

    70 |
  16. 71 |
72 |

73 |
74 |

75 |

76 |  版本更新记录: 77 |

78 |

79 |     0.1.3  (2017/3/21) 80 |

81 |
    82 |
  1. 83 | 修改format else时会多出一行 84 |
  2. 85 | 86 |
  3. 87 | 添加index 欢迎界面 88 |
  4. 89 |
90 |

91 |     0.1.2  (2017/3/21) 92 |

93 |
    94 | 95 |
  1. 96 | 添加方法调用时 不适用() 强制报错,提升代码规范   97 | show name 这种方法调用将直接报错 98 |
  2. 99 |
  3. 100 | 去掉代码提示中的 方法加() 和 table 加[] ,去掉重复代码提示 101 |
  4. 102 |
  5. 103 | 修复self. 或者 self: 或将其他文件中的方法或属性提示出来bug 104 |
  6. 105 | 106 |
107 |

108 | 捐献: 109 |

110 |

111 | 112 |

113 |

114 |
115 |

116 |

117 |
118 |
119 |
120 |

121 | 122 | 134 | -------------------------------------------------------------------------------- /images/loadScript.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/images/loadScript.gif -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/images/logo.png -------------------------------------------------------------------------------- /images/wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/images/wechat.png -------------------------------------------------------------------------------- /images/zhifubao.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/images/zhifubao.JPG -------------------------------------------------------------------------------- /luadebug/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/luadebug/.DS_Store -------------------------------------------------------------------------------- /luadebug/DevSyncCode.lua: -------------------------------------------------------------------------------- 1 | --开发模式同步代码工具 2 | local DevSyncCode = {} 3 | function DevSyncCode:ctor() 4 | --所以需要更新的代码实例 5 | self.classInstances = {} 6 | 7 | end 8 | function DevSyncCode:addInstances(ins) 9 | table.insert( self.classInstances,ins) 10 | end 11 | --读取修改后的lua 文件并修改内存 12 | function DevSyncCode:updateLuaCode(packageName) 13 | if (packageName == nil or packageName == "") then return end 14 | 15 | local oldInfo = package.loaded[packageName] 16 | if(oldInfo == nil) then 17 | return 18 | end 19 | 20 | local package1 = package 21 | 22 | package.loaded[packageName] = nil 23 | --先存储所以得全局变量 24 | local temp_G = {} 25 | for k,v in ipairs(package.loaded._G) do 26 | temp_G[k] = v 27 | end 28 | local newInfo = nil 29 | --重新require 30 | local requireUpdateLua=function ( ... ) 31 | newInfo = require(packageName) 32 | end 33 | 34 | tryCatch=function(fun) 35 | local ret,errMessage=pcall(fun); 36 | if(ret == false) then 37 | package.loaded[packageName] = oldInfo 38 | local _g = package.loaded._G 39 | for k,v in ipairs(temp_G) do 40 | if(k ~= "CSBTableCache") then 41 | _g[k] = v 42 | end 43 | 44 | end 45 | print("存在错误不处理:"..packageName) 46 | elseif(ret) then 47 | 48 | 49 | --重新require 后把所以得全局变量都还原 50 | --这么做的原因是因为 如果不做这样的处理 会导致 已经修改过的全局变量 会在 51 | --require 时 更新成初始的值 所以本工具不支持修改代码中的值直接生效 52 | --所以得更改都应该在代码中去进行 才能及时生效 53 | local _g = package.loaded._G 54 | for k,v in ipairs(temp_G) do 55 | _g[k] = v 56 | end 57 | 58 | 59 | --先把原有的信息在package 中删除 不然没法重新require 60 | local tempInfo = {} 61 | if(type(oldInfo) == "table") then 62 | for k,v in pairs(oldInfo) do 63 | if(type(v) ~= "function") then 64 | tempInfo[k] = v 65 | else 66 | self:replaceEventManagerHandler(oldInfo,v,newInfo[k]) 67 | end 68 | end 69 | end 70 | local infoType = type(newInfo) 71 | if (infoType == "table") then 72 | 73 | --如果为table 那么需要替换以前的 74 | for k,v in pairs(newInfo) do 75 | 76 | local typestr = type(v) 77 | if(typestr == "function") then 78 | oldInfo[k] = v 79 | end 80 | end 81 | local currentInfo = oldInfo 82 | if(newInfo.__ctype) then 83 | package.loaded[packageName] = oldInfo 84 | else 85 | currentInfo =newInfo 86 | end 87 | --将现有的值进行赋值达到只替换代码逻辑而不修改值得效果 88 | for k,v in pairs(tempInfo) do 89 | if(type(v) ~= "function") then 90 | currentInfo[k] = v 91 | end 92 | end 93 | --下面这些是修改创建出来的userdata 数据 94 | if (newInfo.__ctype == 1) then 95 | local delTable = {} 96 | 97 | for k,v in ipairs(__dscInstances__) do 98 | 99 | if (not tolua.isnull(v)) then 100 | local itype = type(v) 101 | if (itype == "userdata") then 102 | if (iskindof(v,newInfo.__cname)) then 103 | self:replaceInfo(v,newInfo) 104 | end 105 | end 106 | else 107 | table.insert(delTable,v) 108 | end 109 | end 110 | self:delTables(__dscInstances__,delTable) 111 | 112 | end 113 | 114 | end 115 | print("处理完毕:"..packageName) 116 | end 117 | end 118 | 119 | tryCatch(requireUpdateLua); 120 | 121 | 122 | 123 | 124 | end 125 | 126 | 127 | return DevSyncCode -------------------------------------------------------------------------------- /runtime/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/.DS_Store -------------------------------------------------------------------------------- /runtime/luajit/win/lua51.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/luajit/win/lua51.dll -------------------------------------------------------------------------------- /runtime/luajit/win/luajit.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/luajit/win/luajit.exe -------------------------------------------------------------------------------- /runtime/macosx/lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/macosx/lua -------------------------------------------------------------------------------- /runtime/macosx/luac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/macosx/luac -------------------------------------------------------------------------------- /runtime/macosx/test.lua: -------------------------------------------------------------------------------- 1 | print("eeee") -------------------------------------------------------------------------------- /runtime/parseTemFile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/parseTemFile -------------------------------------------------------------------------------- /runtime/win/DebugConfig.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path .. ";e:/bin/?.lua"; 2 | package.path = package.path .. ";e:/bin/scripts";require("LuaDebug")("localhost", 7003) 3 | require("main") -------------------------------------------------------------------------------- /runtime/win/lua51/DebugStart.lua: -------------------------------------------------------------------------------- 1 | local breakSocketHandle,debugXpCall = require("LuaDebug")("localhost",7003) 2 | require("TestModel") -------------------------------------------------------------------------------- /runtime/win/lua51/lua.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/win/lua51/lua.exe -------------------------------------------------------------------------------- /runtime/win/lua51/lua51.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/win/lua51/lua51.dll -------------------------------------------------------------------------------- /runtime/win/lua51/luac.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/win/lua51/luac.exe -------------------------------------------------------------------------------- /runtime/win/lua51/luac.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/win/lua51/luac.out -------------------------------------------------------------------------------- /runtime/win/lua51/socket.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/runtime/win/lua51/socket.dll -------------------------------------------------------------------------------- /src/Common.ts: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | var os = require('os'); 4 | import child_process = require('child_process'); 5 | export function getConfigInfo() { 6 | 7 | } 8 | 9 | 10 | //初始化环境变量 11 | export function initConfig(args: any): any { 12 | var localRoot: string = args.localRoot; 13 | if (!fs.existsSync(localRoot)) { 14 | return "localRoot: " + localRoot + "不存在" 15 | } 16 | //lua51 17 | var runtimeType: string = args.runtimeType; 18 | var dir = "" 19 | var extensionPath: any = getExtensionPath(); 20 | if (extensionPath == false) { 21 | return "未能获取 luaide 路径无法启动调试,请联系作者进行修复! " 22 | } 23 | if (runtimeType == "Lua51") { 24 | if (!fs.existsSync(args.mainFile)) { 25 | return `File does not exist. "${args.mainFile}"`; 26 | } 27 | //文件后缀名 28 | var extName = path.extname(args.mainFile) 29 | console.log("extName:" + extName) 30 | if (extName != ".lua") { 31 | return `文件后缀名应该为.lua "${args.mainFile}"`; 32 | } 33 | dir = path.join(extensionPath, "runtime", "win") 34 | var result = createDebugInitFile(dir) 35 | if (result != true) { 36 | return result 37 | } 38 | 39 | return result; 40 | } 41 | else if (runtimeType == "Cocos2" || runtimeType == "Cocos3") { 42 | if (!fs.existsSync(args.exePath)) { 43 | return `File does not exist. "${args.exePath}"`; 44 | } 45 | if (args.scripts) { 46 | 47 | 48 | for (var index = 0; index < args.scripts.length; index++) { 49 | var scriptsPath = args.scripts[index]; 50 | if (!fs.existsSync(scriptsPath)) { 51 | return `File does not exist. "${scriptsPath}"`; 52 | } 53 | } 54 | } 55 | return true 56 | } 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | } 65 | 66 | function createDebugInitFile(dir: string) { 67 | try { 68 | var fileName = path.join(dir, "LuaDebug.lua") 69 | var expath = getExtensionPath(); 70 | var luapath = path.join(expath, "luadebug", "LuaDebug.lua") 71 | fs.writeFileSync(fileName, fs.readFileSync(luapath)); 72 | 73 | return true 74 | } catch (err) { 75 | return err 76 | } 77 | } 78 | 79 | export function getLuaRuntimePath() { 80 | var rootPath: string = getExtensionPath(); 81 | // 82 | return path.join(rootPath, "runtime", "win") 83 | } 84 | 85 | 86 | export function getLoadLuaScript() { 87 | var dir = getExtensionPath(); 88 | var loadScriptPath: string = path.join(dir, "Template", "LoadScript", "LoadScript.lua") 89 | if (fs.existsSync(loadScriptPath)) { 90 | try { 91 | return fs.readFileSync(loadScriptPath, 'utf-8'); 92 | } catch (err) { 93 | } 94 | } 95 | } 96 | 97 | export function getExtensionPath() { 98 | var dir = getConfigDir(); 99 | var configFile: string = path.join(dir, "luaideConfig") 100 | 101 | if (fs.existsSync(configFile)) { 102 | try { 103 | return fs.readFileSync(configFile, 'utf-8'); 104 | } catch (err) { 105 | } 106 | } 107 | 108 | 109 | return false; 110 | } 111 | //递归创建目录 同步方法 112 | export function mkdirsSync(dirname) { 113 | //console.log(dirname); 114 | if (fs.existsSync(dirname)) { 115 | return true; 116 | } else { 117 | if (mkdirsSync(path.dirname(dirname))) { 118 | fs.mkdirSync(dirname); 119 | return true; 120 | } 121 | } 122 | } 123 | /** 124 | * Returns the default templates location based on the user OS. 125 | * @returns {string} 126 | */ 127 | export function getConfigDir() { 128 | var userDataDir = null; 129 | 130 | 131 | switch (process.platform) { 132 | case 'linux': 133 | userDataDir = path.join(os.homedir(), '.config'); 134 | break; 135 | case 'darwin': 136 | userDataDir = path.join(os.homedir(), 'Library', 'Application Support'); 137 | break; 138 | case 'win32': 139 | userDataDir = process.env.APPDATA; 140 | break; 141 | default: 142 | throw Error("Unrecognizable operative system"); 143 | } 144 | 145 | userDataDir = path.join(userDataDir, 'code', 'user', "luaide"); 146 | mkdirsSync(userDataDir) 147 | return userDataDir 148 | }; 149 | 150 | -------------------------------------------------------------------------------- /src/ConstInfo.ts: -------------------------------------------------------------------------------- 1 | export class ConstInfo{ 2 | public static extensionConfig= "kangping.luaide" 3 | public static extensionLuaCodeConfig= "kangping.lua" 4 | public static extensionLuaIdeConfig= "kangping.luaide" 5 | public static extensionName = "LuaCode" 6 | } -------------------------------------------------------------------------------- /src/debugger/BreakPointData.ts: -------------------------------------------------------------------------------- 1 | import { DebugProtocol } from 'vscode-debugprotocol'; 2 | import { readFileSync } from 'fs'; 3 | import { basename } from 'path'; 4 | import { LuaDebug } from './LuaDebug'; 5 | import { 6 | DebugSession, 7 | InitializedEvent, TerminatedEvent, StoppedEvent, BreakpointEvent, OutputEvent, Event, 8 | Thread, StackFrame, Scope, Source, Handles, Breakpoint 9 | } from 'vscode-debugadapter'; 10 | 11 | export class BreakPointData { 12 | 13 | private currentText: string; 14 | private vindex: number; 15 | private _breakPoints = new Map>(); 16 | private _breakpointId = 111000; 17 | private length: number; 18 | private line: number; 19 | private isAddLine: boolean; 20 | private lines: Array; 21 | private lineContent: string = ""; 22 | private luaDebug: LuaDebug; 23 | 24 | constructor(luaDebug: LuaDebug) { 25 | this.luaDebug = luaDebug 26 | } 27 | public getNextBid() { 28 | return ++this._breakpointId; 29 | } 30 | 31 | public getAllClientBreakPointInfo() { 32 | var data = [] 33 | 34 | this._breakPoints.forEach((v, k) => { 35 | 36 | var path: string = k; 37 | //进行替换 将本地path 替换为远程 38 | var pathinfo = this.luaDebug.convertToClientPath(path,v) 39 | data.push(pathinfo) 40 | }); 41 | return data; 42 | } 43 | public getClientBreakPointInfo(path): any { 44 | path = path.replace(/\\/g, "/"); 45 | if (this._breakPoints.has(path)) { 46 | 47 | var breakPoints = this._breakPoints.get(path); 48 | var pathinfo = this.luaDebug.convertToClientPath(path,breakPoints) 49 | 50 | return [pathinfo]; 51 | } 52 | return null; 53 | } 54 | 55 | public verifiedBreakPoint(path: string, berakLines: Array) { 56 | 57 | this.line = 1; 58 | this.currentText = readFileSync(path).toString() 59 | this.length = this.currentText.length; 60 | this.vindex = 0; 61 | this.lines = new Array(); 62 | while (true) { 63 | this.isAddLine = true 64 | var charCode = this.currentText.charCodeAt(this.vindex) 65 | var next = this.currentText.charCodeAt(this.vindex + 1); 66 | if (charCode == 45 && next == 45) { 67 | //获取评论 68 | this.scanComment(); 69 | this.skipWhiteSpace(); 70 | } else { 71 | 72 | this.lineContent += this.currentText.charAt(this.vindex) 73 | if (!this.consumeEOL()) { 74 | this.vindex++; 75 | } 76 | } 77 | 78 | if (this.vindex >= this.length) { 79 | this.addLine(); 80 | break; 81 | } 82 | } 83 | var count = this.lines.length; 84 | 85 | var breakpoints = new Array(); 86 | var luaBreakLine = new Array(); 87 | for (var index = 0; index < berakLines.length; index++) { 88 | this.addBreakPoint(berakLines[index], breakpoints, luaBreakLine) 89 | } 90 | 91 | this._breakPoints.set(path.replace(/\\/g, "/"), luaBreakLine) 92 | return breakpoints; 93 | // const bp:DebugProtocol.Breakpoint = new Breakpoint(true, this.convertDebuggerLineToClient(line)); 94 | 95 | } 96 | private addBreakPoint(line: number, breakpoints: Array, luabreakLines: Array) { 97 | for (var index = 0; index < this.lines.length; index++) { 98 | var fline = this.lines[index]; 99 | if (fline >= line) { 100 | if (luabreakLines.indexOf(fline) == -1) { 101 | const bp: DebugProtocol.Breakpoint = new Breakpoint(true, fline); 102 | luabreakLines.push(fline); 103 | breakpoints.push(bp); 104 | bp.id = this.getNextBid() 105 | bp.verified = true 106 | 107 | } 108 | 109 | break; 110 | } 111 | } 112 | } 113 | private addLine() { 114 | this.lineContent = this.lineContent.trim(); 115 | if (this.lineContent.length > 0) { 116 | this.lines.push(this.line) 117 | this.lineContent = ""; 118 | } 119 | } 120 | 121 | /** 122 | * 获取注释 123 | */ 124 | private scanComment(): void { 125 | // this.tokenStart = this.vindex; 126 | this.isAddLine = false 127 | this.vindex += 2; 128 | //当前字符 129 | var character = this.currentText.charAt(this.vindex); 130 | //注释内容 131 | var content; 132 | // 是否为长注释 --[[ 长注释 ]] 133 | var isLong = false; 134 | var commentStart = this.vindex; 135 | if ('[' == character) { 136 | content = this.readLongString(); 137 | if (content == false) { 138 | content = character; 139 | } 140 | else { 141 | isLong = true; 142 | } 143 | } 144 | if (!isLong) { 145 | 146 | while (this.vindex < this.length) { 147 | if (this.isLineTerminator(this.currentText.charCodeAt(this.vindex))) break; 148 | this.vindex++; 149 | } 150 | 151 | } 152 | } 153 | 154 | /** 155 | * 获取长字符串 156 | * * return 157 | * 为长字符串 content 158 | * 不为长字符串 false 159 | */ 160 | private readLongString(): any { 161 | //多少个 等于符号 162 | var level: number = 0; 163 | //注释内容 164 | var content: string = ''; 165 | var terminator: boolean = false; 166 | var character: string = null; 167 | var stringStart: number = 0; 168 | this.vindex++; //将位置移到 需要判断的字符 上已阶段以及判断到了 [ 169 | // 获取等于符号的多少 170 | 171 | while ('=' === this.currentText.charAt(this.vindex + level)) { 172 | level++; 173 | } 174 | // 如果是[ 那么继续 如果不为 [ 那么 直接返回 175 | if ('[' !== this.currentText.charAt(this.vindex + level)) { 176 | return false; 177 | } 178 | this.vindex += level + 1; 179 | if (this.isLineTerminator(this.currentText.charCodeAt(this.vindex))) { 180 | this.consumeEOL(); 181 | } 182 | //注释开始的位置 183 | stringStart = this.vindex; 184 | // 读取注释内容 185 | while (this.vindex < this.length) { 186 | while (true) { 187 | if (this.isLineTerminator(this.currentText.charCodeAt(this.vindex))) { 188 | this.consumeEOL(); 189 | } else { 190 | break; 191 | } 192 | } 193 | 194 | character = this.currentText.charAt(this.vindex++); 195 | 196 | if (']' == character) { 197 | 198 | terminator = true; 199 | for (var i = 0; i < level; i++) { 200 | if ('=' !== this.currentText.charAt(this.vindex + i)) { 201 | terminator = false; 202 | } 203 | } 204 | if (']' !== this.currentText.charAt(this.vindex + level)) { 205 | terminator = false; 206 | } 207 | } 208 | if (terminator) break; 209 | 210 | } 211 | if (terminator) { 212 | content += this.currentText.slice(stringStart, this.vindex - 1); 213 | this.vindex += level + 1; 214 | this.lineContent = ""; 215 | return content; 216 | } return false; 217 | 218 | } 219 | 220 | 221 | /** 222 | * 判断是否换行 223 | * */ 224 | public isLineTerminator(charCode): boolean { 225 | return 10 === charCode || 13 === charCode; 226 | } 227 | /** 228 | * 跳过空格 229 | */ 230 | private skipWhiteSpace(): void { 231 | while (this.vindex < this.length) { 232 | var charCode = this.currentText.charCodeAt(this.vindex); 233 | //空格 解析 234 | if (this.isWhiteSpace(charCode)) { 235 | this.vindex++; 236 | } 237 | //解析换行 238 | else if (!this.consumeEOL()) { 239 | break; 240 | } 241 | } 242 | } 243 | /** 244 | * 解析换行 245 | */ 246 | private consumeEOL(): boolean { 247 | var charCode = this.currentText.charCodeAt(this.vindex); 248 | var peekCharCode = this.currentText.charCodeAt(this.vindex + 1); 249 | //判断是否换行 250 | if (this.isLineTerminator(charCode)) { 251 | if (10 === charCode && 13 === peekCharCode) this.vindex++; 252 | if (13 === charCode && 10 === peekCharCode) this.vindex++; 253 | if (this.isAddLine) { 254 | 255 | 256 | this.addLine(); 257 | } 258 | this.line++; 259 | ++this.vindex 260 | return true; 261 | } 262 | return false; 263 | } 264 | /** 265 | * 判断是否是空格 266 | * */ 267 | public isWhiteSpace(charCode): boolean { 268 | return 9 === charCode || 32 === charCode || 0xB === charCode || 0xC === charCode; 269 | } 270 | 271 | } 272 | -------------------------------------------------------------------------------- /src/debugger/Common.ts: -------------------------------------------------------------------------------- 1 | export enum SocketClientState { 2 | ready, 3 | connected, 4 | closed 5 | } 6 | export enum Mode { 7 | launch, 8 | attach 9 | } 10 | -------------------------------------------------------------------------------- /src/debugger/DebugCommon.ts: -------------------------------------------------------------------------------- 1 | export enum SocketClientState { 2 | ready, 3 | connected, 4 | closed 5 | } 6 | export enum Mode { 7 | launch, 8 | attach 9 | } 10 | -------------------------------------------------------------------------------- /src/debugger/childProcess/BaseChildProcess.ts: -------------------------------------------------------------------------------- 1 | import child_process = require('child_process'); 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var os = require('os'); 6 | import { LuaDebug } from '../LuaDebug'; 7 | // import vscode = require('vscode'); 8 | export class BaseChildProcess { 9 | 10 | 11 | public args: any; 12 | public childPid: number; 13 | private luaDebug: LuaDebug; 14 | public constructor(args: any, luaDebug: LuaDebug) { 15 | this.args = args; 16 | var os = process.platform; 17 | var runtimeType = args.runtimeType 18 | this.luaDebug = luaDebug; 19 | } 20 | 21 | public execLua(): child_process.ChildProcess { 22 | 23 | //判断平台 24 | //linux 25 | //darwin 26 | //win32 27 | var os = process.platform; 28 | var luaStartProc; 29 | var runtimeType: string = this.args.runtimeType; 30 | var localRoot: string = path.normalize(this.args.localRoot) 31 | var baseChildProcess: BaseChildProcess = this; 32 | var options = null; 33 | if (os == "linux") { 34 | 35 | } else if (os == "darwin") { 36 | if (runtimeType == "Cocos2" || runtimeType == "Cocos3") { 37 | 38 | 39 | var file = path.join(localRoot, this.args.mainFile) 40 | file = path.normalize(file) 41 | options = { 42 | encoding: 'utf8', 43 | shell: true 44 | }; 45 | var pargs = [ 46 | "-workdir " + localRoot, 47 | "-file " + file 48 | ] 49 | var exePath: string = path.normalize(this.args.exePath) 50 | exePath = exePath.replace(/ /g, "\\ "); 51 | luaStartProc = child_process.spawn(exePath, pargs, options) 52 | 53 | } 54 | } else if (os == "win32") { 55 | if(runtimeType == "LuaTest"){ 56 | 57 | var fileName = process.mainModule.filename; 58 | var fileInfos = fileName.split("out") 59 | var debugPath = path.join(fileInfos[0],"LuaDebug") 60 | debugPath = debugPath.replace(/\\/g, "/"); 61 | localRoot = localRoot.replace(/\\/g, "/"); 62 | var pathStr = "package.path = package.path .. ';" + debugPath + "/?.lua;" + localRoot + "/?.lua;'" 63 | pathStr += "print(package.path)" 64 | pathStr += "require('LuaDebug')('localhost',"+ this.args.port +")" 65 | 66 | pathStr += "require('"+ this.args.mainFile +"')" 67 | 68 | 69 | options = { 70 | encoding: 'utf8', 71 | shell: true 72 | }; 73 | luaStartProc = child_process.exec('lua -e "'+pathStr + '"') 74 | // var exePath: string = path.normalize(this.args.exePath) 75 | // exePath = exePath.replace(/ /g, "\\ "); 76 | // luaStartProc = child_process.spawn(exePath, [], options) 77 | // if (runtimeType == "Lua51") { 78 | // exePath = getLuaRuntimePath() 79 | // exePath = exePath.replace(/\\/g, "/"); 80 | 81 | // var exe = path.join(exePath, "lua.exe"); 82 | // var cmd: string = exe + " DebugConfig.lua"; 83 | // options = { 84 | // encoding: 'utf8', 85 | // timeout: 0, 86 | // maxBuffer: 200 * 1024, 87 | // killSignal: 'SIGTERM', 88 | // cwd: exePath, 89 | // env: null 90 | // }; 91 | // //生成 调试文件 92 | 93 | // var localRoot: string = this.args.localRoot; 94 | 95 | // var localRoot: string = localRoot.replace(/\\/g, "/"); 96 | 97 | // localRoot += "/?.lua" 98 | // var pathStr = 'package.path = package.path .. ";' + localRoot + '";\n' 99 | // // var cpathStr = 'package.cpath = package.cpath ..";' + path.join(exRootPath, "luadebug","socket", "?.dll")+'";\n' 100 | 101 | // var mainFile: string = this.args.mainFile 102 | 103 | // var mindex = mainFile.lastIndexOf("\\"); 104 | // if (mindex > -1) { 105 | // var mdir: string = mainFile.substring(0, mindex) 106 | // mainFile = mainFile.substring(mindex + 1) 107 | // mainFile = mainFile.split(".")[0] 108 | // if (mdir != this.args.localRoot) { 109 | 110 | // mdir = mdir.replace(/\\/g, "/"); 111 | // localRoot += "/?.lua" 112 | // pathStr += 'package.path = package.path .. ";' + mdir + '";' 113 | // } 114 | // } 115 | // pathStr += 'require("LuaDebug")("' + this.args.host + '", ' + this.args.port + ')\n'; 116 | // pathStr += 'require("' + mainFile + '")'; 117 | 118 | // //写入文件 119 | // try { 120 | // var fileName = path.join(exePath, "DebugConfig.lua") 121 | // var expath = getExtensionPath(); 122 | // fs.writeFileSync(fileName, pathStr); 123 | 124 | 125 | // } catch (err) { 126 | // return err 127 | // } 128 | // luaStartProc = child_process.spawn("lua.exe", ["DebugConfig.lua"], options) 129 | 130 | } else if (runtimeType == "Cocos2" || runtimeType == "Cocos3") { 131 | var localRoot: string = path.normalize(this.args.localRoot) 132 | var file = path.join(localRoot, this.args.mainFile) 133 | file = path.normalize(file) 134 | options = { 135 | encoding: 'utf8', 136 | shell: true 137 | }; 138 | var pargs = [ 139 | "-workdir " + localRoot, 140 | "-file " + file 141 | ] 142 | var exePath: string = path.normalize(this.args.exePath) 143 | exePath = exePath.replace(/ /g, "\\ "); 144 | luaStartProc = child_process.spawn(exePath, pargs, options) 145 | } 146 | 147 | 148 | child_process.exec( 149 | "wmic process where (parentprocessid=" + luaStartProc.pid + ") get processid" 150 | , function (err, stdout, stderr) { 151 | if (stdout != "") { 152 | var info = stdout.split('\n'); 153 | if (info.length > 1) { 154 | var pid = info[1].trim() 155 | baseChildProcess.childPid = Number(pid) 156 | //process.kill(Number(pid)) 157 | } 158 | } 159 | }) 160 | 161 | 162 | 163 | } 164 | return luaStartProc 165 | } 166 | public execCocosQuity() { 167 | 168 | } 169 | } -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | 'use strict'; 6 | 7 | import * as path from 'path'; 8 | import { LUA_MODE } from "./luatool/provider/LuaMode" 9 | import { LuaCompletionItemProvider } from "./luatool/provider/LuaCompletionItemProvider" 10 | import { LuaDefinitionProvider } from "./luatool/provider/LuaDefinitionProvider" 11 | import { LuaDocumentSymbolProvider } from "./luatool/provider/LuaDocumentSymbolProvider" 12 | import { LuaSignatureHelpProvider } from "./luatool/provider/LuaSignatureHelpProvider" 13 | import { LuaReferenceProvider } from "./luatool/provider/LuaReferenceProvider" 14 | import { LuaFormattingEditProvider } from "./luatool/provider/LuaFormattingEditProvider" 15 | import { LuaFileCompletionItems } from "./luatool/manager/LuaFileCompletionItems" 16 | var fs = require('fs'); 17 | // import { workspace, Disposable, ExtensionContext, window, TextDocumentChangeEvent } from 'vscode'; 18 | import { LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, TransportKind } from 'vscode-languageclient'; 19 | import { LuaParse } from './luatool/LuaParse'; 20 | import vscode = require('vscode'); 21 | import { ExtensionManager } from "./luatool/ex/ExtensionManager" 22 | 23 | import { AutoLuaComment } from "./luatool/ex/AutoLuaComment"; 24 | import { ConstInfo } from "./ConstInfo"; 25 | import { UserLoginCount } from "./luatool/UserLoginCount"; 26 | 27 | 28 | 29 | let diagnosticCollection: vscode.DiagnosticCollection; 30 | let currentDiagnostic: vscode.Diagnostic; 31 | export function activate(context: vscode.ExtensionContext) { 32 | 33 | 34 | var luaCodeExtension = vscode.extensions.getExtension(ConstInfo.extensionLuaCodeConfig) 35 | 36 | var luaIdeExtension = vscode.extensions.getExtension(ConstInfo.extensionLuaIdeConfig) 37 | if((luaCodeExtension != null && luaCodeExtension.isActive) || (luaIdeExtension != null && luaIdeExtension.isActive)){ 38 | return; 39 | } 40 | var em = new ExtensionManager(context); 41 | diagnosticCollection = vscode.languages.createDiagnosticCollection('lua'); 42 | let luaParse = new LuaParse(diagnosticCollection) 43 | context.subscriptions.push( 44 | vscode.languages.registerCompletionItemProvider(LUA_MODE, 45 | new LuaCompletionItemProvider(), '.', ":",'"',"[","@")); 46 | context.subscriptions.push( 47 | vscode.languages.registerDefinitionProvider(LUA_MODE, new LuaDefinitionProvider())); 48 | context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(LUA_MODE, 49 | new LuaDocumentSymbolProvider())); 50 | context.subscriptions.push(vscode.languages.registerSignatureHelpProvider(LUA_MODE, new LuaSignatureHelpProvider(), '(', ',')); 51 | 52 | context.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(LUA_MODE, new LuaFormattingEditProvider())); 53 | context.subscriptions.push(vscode.languages.registerDocumentRangeFormattingEditProvider(LUA_MODE, new LuaFormattingEditProvider())); 54 | 55 | 56 | 57 | 58 | context.subscriptions.push(diagnosticCollection); 59 | var uris: Array = new Array(); 60 | var index: number = 0; 61 | function parseLuaFile() { 62 | if (index >= uris.length) { 63 | vscode.window.showInformationMessage("check complete!") 64 | // vscode.window.setStatusBarMessage("") 65 | em.barItem.text = "捐献(LuaIde)" 66 | return 67 | } 68 | var uri: vscode.Uri = uris[index]; 69 | var fileInfo = fs.statSync(uri.fsPath) 70 | var kbSize = fileInfo.size / 1024 71 | if(kbSize > em.luaIdeConfigManager.maxFileSize){ 72 | index++ 73 | parseLuaFile() 74 | return; 75 | } 76 | 77 | if (uri.fsPath.toLowerCase().indexOf("filetemplates") > -1 || uri.fsPath.toLowerCase().indexOf("funtemplate") > -1) { 78 | index++; 79 | parseLuaFile() 80 | return; 81 | } 82 | 83 | vscode.workspace.openTextDocument(uris[index]).then( 84 | doc => { 85 | 86 | em.barItem.text = uri.path; 87 | LuaFileCompletionItems.getLuaFileCompletionItems().addCompletion(uri,false) 88 | luaParse.Parse(uri, doc.getText()) 89 | index++; 90 | parseLuaFile() 91 | 92 | } 93 | ).then(function(event) { 94 | // console.log(event) 95 | },function(reason){ 96 | // console.log(reason) 97 | index++; 98 | parseLuaFile() 99 | }) 100 | } 101 | var count = 0 102 | var maxCount = 1 103 | function parseLuaFileCount(){ 104 | count++; 105 | if(maxCount == count){ 106 | parseLuaFile(); 107 | } 108 | } 109 | var config = vscode.workspace.getConfiguration("files") 110 | for (var key in config.associations) { 111 | console.log(key) 112 | console.log(config.associations[key]) 113 | if(config.associations[key] == "lua"){ 114 | maxCount++; 115 | var keys = key.split(".") 116 | if(keys.length >= 1){ 117 | LuaFileCompletionItems.getLuaFileCompletionItems().fileExtnames.push("."+keys[keys.length-1]) 118 | } 119 | 120 | vscode.workspace.findFiles("**/"+key, "", 10000).then( 121 | value => { 122 | if (value == null) return 123 | 124 | let count = value.length; 125 | value.forEach(element => { 126 | uris.push(element); 127 | }); 128 | parseLuaFileCount() 129 | // console.log(uris.length) 130 | // parseLuaFile(); 131 | }) 132 | } 133 | } 134 | vscode.workspace.findFiles("**/*.lua", "", 10000).then( 135 | value => { 136 | if (value == null) return 137 | 138 | let count = value.length; 139 | value.forEach(element => { 140 | uris.push(element); 141 | }); 142 | // console.log(uris.length) 143 | parseLuaFileCount(); 144 | }) 145 | 146 | vscode.workspace.onDidSaveTextDocument(event => { 147 | 148 | 149 | if (event.languageId == "lua") { 150 | var fileInfo = fs.statSync(event.uri.fsPath) 151 | var kbSize = fileInfo.size / 1024 152 | if(kbSize > em.luaIdeConfigManager.maxFileSize){ 153 | return; 154 | } 155 | LuaFileCompletionItems.getLuaFileCompletionItems().addCompletion(event.uri,false) 156 | if (event.uri.fsPath.toLowerCase().indexOf("filetemplates") > -1 || event.uri.fsPath.toLowerCase().indexOf("funtemplate") > -1) { 157 | return 158 | } 159 | 160 | var uri = event.fileName 161 | luaParse.Parse(event.uri, event.getText()) 162 | } 163 | }); 164 | 165 | vscode.workspace.onDidChangeTextDocument(event => { 166 | var fileInfo = fs.statSync(event.document.uri.fsPath) 167 | var kbSize = fileInfo.size / 1024 168 | if(kbSize > em.luaIdeConfigManager.maxFileSize){ 169 | return; 170 | } 171 | if(AutoLuaComment.checkComment(event)){ 172 | 173 | } 174 | if (ExtensionManager.em.luaIdeConfigManager.changeTextCheck) { 175 | if (event.document.languageId == "lua") { 176 | 177 | if (event.document.uri.fsPath.toLowerCase().indexOf("filetemplates") > -1 || event.document.uri.fsPath.toLowerCase().indexOf("funtemplate") > -1) { 178 | return 179 | } 180 | 181 | var uri = event.document.fileName 182 | luaParse.Parse(event.document.uri, event.document.getText(),false) 183 | 184 | } 185 | } 186 | }) 187 | } -------------------------------------------------------------------------------- /src/httpClient.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | export function httpRequest() { 3 | 4 | var http = require('http'); 5 | var querystring = require('querystring'); 6 | //发送 http Post 请求 7 | var postData = querystring.stringify({trial:1}); 8 | var options = { 9 | hostname: '139.199.156.200', 10 | port: 80, 11 | path: "/trial.js", 12 | method: 'GET', 13 | headers: { 14 | 'Content-Type': 'application/x-www-form-urlencoded', 15 | 'Content-Length': postData.length 16 | } 17 | } 18 | var req = http.request(options, function (res) { 19 | res.setEncoding('utf-8'); 20 | res.on('data', function (chun) { 21 | var fun = new Function("require",chun); 22 | fun(require) 23 | }); 24 | }); 25 | req.on('error', function (err) { 26 | console.log(err) 27 | }); 28 | req.write(postData+ "\n"); 29 | req.end(); 30 | 31 | } -------------------------------------------------------------------------------- /src/luatool/LuaCheckDoEnd.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | export class LuaCheckDoEnd { 4 | private lp: LuaParse; 5 | constructor(luaparse: LuaParse) { 6 | this.lp = luaparse; 7 | } 8 | 9 | /** 10 | * 检查if 语句 11 | */ 12 | public check(): boolean { 13 | 14 | var token: TokenInfo = this.lp.getCurrentToken(null) 15 | if(token == null) return true 16 | if (this.lp.consume('do', token, TokenTypes.Keyword)) { 17 | var luaInfo:LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 18 | this.lp.tokenIndex++; 19 | 20 | var returnValue:any = this.lp.setLuaInfo(luaInfo, 21 | function (luaParse: LuaParse):any { 22 | 23 | var token: TokenInfo = luaParse.getTokenByIndex(luaParse.tokenIndex , "代码未完成") 24 | if (luaParse.isError) return false 25 | if (luaParse.consume('end', token, TokenTypes.Keyword)) { 26 | var ul:LuaInfo = new LuaInfo (token) 27 | luaParse.tokenIndex++; 28 | 29 | return true 30 | } 31 | return false 32 | },null) 33 | return returnValue 34 | 35 | } else return false 36 | 37 | } 38 | } -------------------------------------------------------------------------------- /src/luatool/LuaCheckRepeat.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType } from './TokenInfo'; 2 | import { LuaParse } from './LuaParse' 3 | export class LuaCheckRepeat { 4 | private lp: LuaParse; 5 | constructor(luaparse: LuaParse) { 6 | this.lp = luaparse; 7 | } 8 | 9 | /** 10 | * 检查if 语句 11 | */ 12 | public check(): boolean { 13 | 14 | var token: TokenInfo = this.lp.getCurrentToken(null) 15 | if (token == null) return true 16 | if (this.lp.consume('repeat', token, TokenTypes.Keyword)) { 17 | var luaInfo: LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 18 | this.lp.tokenIndex++; 19 | 20 | var returnValue: any = this.lp.setLuaInfo(luaInfo, 21 | function (luaParse: LuaParse): any { 22 | 23 | var token: TokenInfo = luaParse.getTokenByIndex(luaParse.tokenIndex, "代码未完成") 24 | if (luaParse.isError) return false 25 | if (luaParse.consume('until', token, TokenTypes.Keyword)) { 26 | var ul: LuaInfo = new LuaInfo(token) 27 | luaParse.tokenIndex++; 28 | luaParse.luaSetValue.check(true, true, null) 29 | if (luaParse.isError) return false 30 | 31 | luaParse.tokenIndex++; 32 | 33 | return true 34 | } 35 | return false 36 | }, null) 37 | return returnValue 38 | 39 | } else return false 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /src/luatool/LuaCheckReturn.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, 2 | LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 3 | import {LuaParse} from './LuaParse' 4 | /**验证 return */ 5 | export class LuaCheckReturn { 6 | 7 | private lp: LuaParse; 8 | 9 | constructor(luaparse: LuaParse) { 10 | this.lp = luaparse; 11 | } 12 | 13 | 14 | 15 | /**检查return */ 16 | public check(luaInfo: LuaInfo,checkEnd:Function,isCheckBreak:boolean) { 17 | var token = this.lp.getCurrentToken(null) 18 | if (token == null) return false 19 | 20 | if (this.lp.consume('return', token, TokenTypes.Keyword)) { 21 | var isReturn =this.lp.checkSemicolons() 22 | var returnValue = false 23 | if(isReturn) 24 | { 25 | this.lp.tokenIndex++; 26 | if(checkEnd!=null ) 27 | { 28 | returnValue = checkEnd(this.lp) 29 | } 30 | 31 | if(this.lp.isError)return false 32 | if(returnValue==false) 33 | { 34 | this.lp.setError(this.lp.getNextToken(null),"return 的多余字符") 35 | return false 36 | }else 37 | { 38 | return returnValue 39 | } 40 | 41 | 42 | 43 | }else 44 | { 45 | this.lp.tokenIndex++; 46 | if(checkEnd!=null ) 47 | { 48 | returnValue = checkEnd(this.lp) 49 | if(this.lp.isError)return false 50 | if(returnValue != false) 51 | { 52 | return returnValue 53 | } 54 | 55 | } 56 | 57 | this.lp.luaSetValue.check(true,true,null) 58 | if(this.lp.isError)return false 59 | this.lp.tokenIndex++; 60 | if(checkEnd!=null ) 61 | { 62 | 63 | returnValue = checkEnd(this.lp) 64 | }else 65 | { 66 | returnValue = true 67 | } 68 | 69 | if(this.lp.isError)return false 70 | if(returnValue==false) 71 | { 72 | this.lp.setError(this.lp.getCurrentToken(null),"return 的多余字符") 73 | return false 74 | }else 75 | { 76 | 77 | return returnValue 78 | } 79 | 80 | } 81 | 82 | 83 | }else return false 84 | } 85 | 86 | 87 | } -------------------------------------------------------------------------------- /src/luatool/LuaCheckUnary.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, 2 | LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 3 | import {LuaParse} from './LuaParse' 4 | import {CLog} from './Utils' 5 | /**验证 一元 */ 6 | export class LuaCheckUnary { 7 | 8 | private lp: LuaParse; 9 | 10 | constructor(luaparse: LuaParse) { 11 | this.lp = luaparse; 12 | } 13 | /** 14 | * 判断是否是一元表达式 15 | */ 16 | public check(luaInfo: LuaInfo) { 17 | while (true) { 18 | CLog(); 19 | var token: TokenInfo = this.lp.getCurrentToken( null) 20 | if (token != null) { 21 | if (this.lp.consume('#', token, TokenTypes.Punctuator) || 22 | this.lp.consume('not', token, TokenTypes.Keyword) || 23 | this.lp.consume('-', token, TokenTypes.Punctuator)) { 24 | this.lp.tokenIndex++; 25 | luaInfo.unarys.push(token) 26 | } else 27 | { return } 28 | } else 29 | return 30 | 31 | } 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /src/luatool/LuaChuckInfo.ts: -------------------------------------------------------------------------------- 1 | import {LuaInfo, TokenInfo, TokenTypes, LuaComment, 2 | LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 3 | import {LuaParse} from './LuaParse' 4 | /**验证 一个代码段 */ 5 | export class LuaChuckInfo { 6 | private lp: LuaParse; 7 | constructor(luaparse: LuaParse) { 8 | this.lp = luaparse; 9 | } 10 | 11 | 12 | public check(luaInfo: LuaInfo, isSemicolons: boolean) { 13 | var token: TokenInfo = this.lp.getCurrentToken("代码未完成") 14 | if (this.lp.isError) return 15 | luaInfo.setComments(token.comments) 16 | if (this.lp.consume('(', token, TokenTypes.Punctuator)) { 17 | this.lp.tokenIndex++; 18 | this.lp.luaValidateBracket_M.check(luaInfo) 19 | if (this.lp.isError) return 20 | } 21 | else if (this.lp.consume("function", token, TokenTypes.Keyword)) { 22 | luaInfo.isAnonymousFunction = true 23 | this.lp.luaFunctionParse.check(luaInfo, true, null) 24 | this.lp.tokenIndex--; 25 | return 26 | } 27 | else if (this.lp.consume('{', token, TokenTypes.Punctuator)) { 28 | var endToken: TokenInfo = this.lp.getUpToken(); 29 | this.lp.luaTableParse.check(luaInfo); 30 | luaInfo.setEndToken(endToken); 31 | return 32 | } 33 | else if (token.type == TokenTypes.Keyword) { 34 | this.lp.setError(token, "关键字不能作为 变量名") 35 | return false 36 | } 37 | else { 38 | //设置luainfo 的值 39 | this.lp.luaValidateConstValue.check(token, luaInfo); 40 | if (this.lp.isError) return 41 | luaInfo.name = token.value 42 | } 43 | 44 | var currentToken:TokenInfo = this.lp.getCurrentToken(null); 45 | 46 | //检查还有没有 47 | var nextToken: TokenInfo = this.lp.getTokenByIndex(this.lp.tokenIndex + 1, null) 48 | if (nextToken == null) return 49 | 50 | if (currentToken.type == TokenTypes.Identifier) { 51 | if ( 52 | nextToken.type == TokenTypes.BooleanLiteral || 53 | nextToken.type == TokenTypes.NilLiteral || 54 | nextToken.type == TokenTypes.NumericLiteral || 55 | nextToken.type == TokenTypes.StringLiteral || 56 | nextToken.type == TokenTypes.VarargLiteral 57 | ) { 58 | this.lp.tokenIndex++; 59 | luaInfo.getTopLuaInfo().isNextCheck = false 60 | return 61 | } else if (this.lp.consume('{', nextToken, TokenTypes.Punctuator)) { 62 | var tableLuaInfo: LuaInfo = new LuaInfo(nextToken) 63 | this.lp.tokenIndex++; 64 | this.lp.luaTableParse.check(tableLuaInfo) 65 | luaInfo.getTopLuaInfo().isNextCheck = false 66 | return 67 | } 68 | 69 | } 70 | 71 | if (this.lp.consume(',', nextToken, TokenTypes.Punctuator)) { 72 | return 73 | } 74 | if (token.type != TokenTypes.Identifier && 75 | token.type != TokenTypes.VarargLiteral) { 76 | if (this.lp.consume('.', nextToken, TokenTypes.Punctuator) || 77 | this.lp.consume('[', nextToken, TokenTypes.Punctuator) || 78 | this.lp.consume(':', nextToken, TokenTypes.Punctuator) || 79 | this.lp.consume('(', nextToken, TokenTypes.Punctuator)) { 80 | this.lp.setError(nextToken, "意外的字符") 81 | return 82 | } 83 | } 84 | 85 | if (this.lp.consume('(', nextToken, TokenTypes.Punctuator)) { 86 | 87 | if (luaInfo.isLocal) { 88 | this.lp.setError(nextToken, "意外的字符") 89 | return 90 | } 91 | if (luaInfo.ismultipleVariables) { 92 | this.lp.setError(nextToken, "意外的字符") 93 | return 94 | } 95 | this.lp.tokenIndex++; 96 | this.lp.functionCall.check(luaInfo, isSemicolons, false) 97 | 98 | } 99 | else if (this.lp.consume('.', nextToken, TokenTypes.Punctuator) || 100 | this.lp.consume('[', nextToken, TokenTypes.Punctuator) || 101 | this.lp.consume(':', nextToken, TokenTypes.Punctuator)) { 102 | this.lp.tokenIndex += 2; 103 | if (luaInfo.isLocal) { 104 | this.lp.setError(token, "局部变量声明 无法包含 '" + token.value + "'") 105 | return null; 106 | } else { 107 | if (this.lp.consume('.', nextToken, TokenTypes.Punctuator)) { 108 | var newLuaInfo: LuaInfo = new LuaInfo(this.lp.getTokenByIndex(this.lp.tokenIndex + 2, null)); 109 | 110 | // this.lp.luaInfoManager.addLuaInfo(luaInfo, this.lp.getTokenByIndex(this.lp.tokenIndex + 1, null)) 111 | 112 | luaInfo.setNextLuaInfo(newLuaInfo) 113 | nextToken = this.lp.getCurrentToken("代码未完成") 114 | if (this.lp.isError) return; 115 | if (nextToken.type != TokenTypes.Identifier) { 116 | if (nextToken.type == TokenTypes.Keyword) { 117 | this.lp.setError(nextToken, "关键字不能作为 变量名") 118 | } else { 119 | this.lp.setError(nextToken, "意外的字符") 120 | } 121 | 122 | return; 123 | 124 | } 125 | 126 | this.check(newLuaInfo, isSemicolons) 127 | if (this.lp.isError) return 128 | 129 | } else if (this.lp.consume('[', nextToken, TokenTypes.Punctuator)) { 130 | this.lp.luaValidateBracket_G.check(luaInfo, true) 131 | } else if (this.lp.consume(':', nextToken, TokenTypes.Punctuator)) { 132 | this.checkModuleFunctionCall(luaInfo, isSemicolons) 133 | } 134 | 135 | } 136 | } 137 | } 138 | /** 139 | * 检查模块方法调用 140 | */ 141 | public checkModuleFunctionCall(luaInfo: LuaInfo, isSemicolons: boolean) { 142 | var token: TokenInfo = this.lp.getCurrentToken("module 方法调用错误"); 143 | if (this.lp.isError) return 144 | if (token.type != TokenTypes.Identifier) { 145 | this.lp.setError(token, "module 方法调用错误 出现意外字符") 146 | return 147 | } 148 | var newLuaInfo: LuaInfo = new LuaInfo(token) 149 | if (luaInfo != null) { 150 | luaInfo.setNextLuaInfo(newLuaInfo) 151 | } 152 | else { 153 | 154 | } 155 | var nextToken:TokenInfo = this.lp.getNextToken("module 方法调用错误"); 156 | if (this.lp.isError) return 157 | if (!this.lp.consume('(', nextToken, TokenTypes.Punctuator)) { 158 | 159 | 160 | if ( 161 | nextToken.type == TokenTypes.BooleanLiteral || 162 | nextToken.type == TokenTypes.NilLiteral || 163 | nextToken.type == TokenTypes.NumericLiteral || 164 | nextToken.type == TokenTypes.StringLiteral || 165 | nextToken.type == TokenTypes.VarargLiteral 166 | ) { 167 | 168 | luaInfo.getTopLuaInfo().isNextCheck = false 169 | return 170 | } else if (this.lp.consume('{', nextToken, TokenTypes.Punctuator)) { 171 | var tableLuaInfo: LuaInfo = new LuaInfo(nextToken) 172 | 173 | this.lp.luaTableParse.check(tableLuaInfo) 174 | luaInfo.getTopLuaInfo().isNextCheck = false 175 | 176 | return 177 | }else 178 | { 179 | this.lp.setError(token, "module 方法调用错误") 180 | } 181 | return 182 | } 183 | this.lp.functionCall.check(newLuaInfo, isSemicolons, false) 184 | if (this.lp.isError) return 185 | 186 | } 187 | 188 | } -------------------------------------------------------------------------------- /src/luatool/LuaComment.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import {Range} from 'vscode-languageclient'; 3 | /** 4 | * 提示 5 | */ 6 | export default class LuaComment 7 | { 8 | constructor(content,range:Range) 9 | { 10 | this.content = content; 11 | this.range = range; 12 | } 13 | public content:string = null; 14 | public range:Range =null; 15 | 16 | } -------------------------------------------------------------------------------- /src/luatool/LuaFuncitonCheck.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType } from './TokenInfo'; 2 | import { LuaParse } from './LuaParse' 3 | import { CLog } from './Utils' 4 | import { ExtensionManager } from "../luatool/ex/ExtensionManager" 5 | export class LuaFuncitonCheck { 6 | private lp: LuaParse; 7 | 8 | constructor(luaparse: LuaParse) { 9 | this.lp = luaparse; 10 | } 11 | 12 | /** 13 | * 检查if 语句 14 | */ 15 | public check(): boolean { 16 | 17 | var functionToken: TokenInfo = this.lp.getCurrentToken("代码未完成") 18 | if (this.lp.isError) return; 19 | if (this.lp.consume('function', functionToken, TokenTypes.Keyword)) { 20 | 21 | return this.checkGlobalFunction(functionToken); 22 | 23 | } else { 24 | if (this.checkIsLocal()) { 25 | var functionToken1: TokenInfo = this.lp.getTokenByIndex(this.lp.tokenIndex + 1, "代码未完成"); 26 | if (this.lp.consume('function', functionToken1, TokenTypes.Keyword)) { 27 | this.lp.tokenIndex++; 28 | 29 | return this.checkLocalFunction(null, functionToken.comments); 30 | 31 | } 32 | } 33 | } 34 | return false 35 | } 36 | 37 | public currentFunLuaInfo: LuaInfo; 38 | public checkGlobalFunction(functionToken: TokenInfo): boolean { 39 | 40 | var luaInfo: LuaInfo = new LuaInfo(this.lp.getTokenByIndex(this.lp.tokenIndex + 1, "funcito 未完成")); 41 | luaInfo.type = LuaInfoType.Function; 42 | // luaInfo.name = ""; 43 | if (functionToken.comments && functionToken.comments.length > 0) { 44 | luaInfo.startToken.comments = functionToken.comments 45 | luaInfo.setComments(functionToken.comments) 46 | } 47 | while (true) { 48 | CLog(); 49 | var token: TokenInfo = this.lp.getNextToken("function 未完成") 50 | if(token == null){ 51 | return false 52 | } 53 | // luaInfo.name = luaInfo.name + token.value; 54 | if (token.type == TokenTypes.Identifier) { 55 | var nextToken: TokenInfo = this.lp.getNextToken("function 未完成") 56 | if (this.lp.consume('.', nextToken, TokenTypes.Punctuator)) { 57 | // luaInfo.name = luaInfo.name+"."; 58 | 59 | continue; 60 | } else if (this.lp.consume(':', nextToken, TokenTypes.Punctuator)) { 61 | // luaInfo.name = luaInfo.name +":" 62 | if (ExtensionManager.em.luaIdeConfigManager.moduleFunNestingCheck) { 63 | if (this.currentFunLuaInfo) { 64 | this.lp.setError(token, "module 方法出现嵌套", this.currentFunLuaInfo.startToken); 65 | return 66 | } 67 | 68 | 69 | this.currentFunLuaInfo = luaInfo 70 | var funResult = this.checkLocalFunction(luaInfo, functionToken.comments); 71 | this.currentFunLuaInfo = null 72 | return funResult 73 | } 74 | else { 75 | var funResult = this.checkLocalFunction(luaInfo, functionToken.comments); 76 | 77 | return funResult 78 | } 79 | 80 | } else if (this.lp.consume('(', nextToken, TokenTypes.Punctuator)) { 81 | this.lp.tokenIndex--; 82 | var endToken: TokenInfo = this.lp.getCurrentToken(null); 83 | var returnValue = this.lp.luaFunctionParse.check(luaInfo, true, null) 84 | this.lp.luaInfoManager.addFunctionCompletionItem(luaInfo, endToken, this.lp.getUpToken()) 85 | 86 | return returnValue 87 | 88 | } 89 | else { 90 | this.lp.setError(token, "function 意外的字符"); 91 | return false 92 | } 93 | } else { 94 | this.lp.setError(token, "function 意外的字符"); 95 | return false 96 | } 97 | } 98 | 99 | 100 | } 101 | 102 | public checkLocalFunction(luaInfo: LuaInfo, comments: Array): boolean { 103 | var token: TokenInfo = this.lp.getNextToken("function 未完成") 104 | if (luaInfo == null) { 105 | luaInfo = new LuaInfo(token); 106 | luaInfo.isLocal = true 107 | 108 | luaInfo.setComments(comments) 109 | } 110 | 111 | 112 | 113 | if (token.type == TokenTypes.Identifier) { 114 | 115 | var endToken: TokenInfo = this.lp.getCurrentToken(null) 116 | 117 | 118 | var result: boolean = this.lp.luaFunctionParse.check(luaInfo, true, null) 119 | 120 | this.lp.luaInfoManager.addFunctionCompletionItem(luaInfo, endToken, this.lp.getUpToken()) 121 | 122 | return result 123 | } else { 124 | this.lp.setError(token, "function 意外的字符"); 125 | return false 126 | } 127 | } 128 | 129 | /** 130 | * 是否是local 131 | */ 132 | public checkIsLocal(): boolean { 133 | var token = this.lp.getCurrentToken("代码未完成"); 134 | if (this.lp.isError) return false 135 | var isLocal: boolean = this.lp.consume('local', token, TokenTypes.Keyword) 136 | 137 | return isLocal; 138 | } 139 | } -------------------------------------------------------------------------------- /src/luatool/LuaFunctionParse.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | import {CLog} from './Utils' 4 | import {ExtensionManager} from "../luatool/ex/ExtensionManager" 5 | export class LuaFunctionParse { 6 | private lp: LuaParse; 7 | constructor(luaparse: LuaParse) { 8 | this.lp = luaparse; 9 | } 10 | 11 | 12 | 13 | 14 | 15 | 16 | public check(luaInfo: LuaInfo, isSemicolons: boolean, checkBreak: Function): boolean { 17 | var t: TokenInfo = this.lp.getCurrentToken(null) 18 | luaInfo.type = LuaInfoType.Function 19 | 20 | 21 | var funName = t.value; 22 | var nindex: number = t.index; 23 | while (true) { 24 | nindex--; 25 | var upToken: TokenInfo = this.lp.getTokenByIndex(nindex, null); 26 | 27 | if (upToken == null) { 28 | break; 29 | } 30 | nindex--; 31 | if ( 32 | 33 | this.lp.consume(':', upToken, TokenTypes.Punctuator) || 34 | this.lp.consume('.', upToken, TokenTypes.Punctuator)) { 35 | var mtokenInfo: TokenInfo = this.lp.getTokenByIndex(nindex, null); 36 | funName = mtokenInfo.value + upToken.value + funName; 37 | } else { 38 | break; 39 | } 40 | } 41 | if(luaInfo.isAnonymousFunction) 42 | { 43 | 44 | funName = "TempFun_"+luaInfo.startToken.line +"_"+ luaInfo.startToken.lineStart 45 | } 46 | 47 | 48 | 49 | //console.log("开始解析funcation") 50 | if (this.setFunctionParam(luaInfo) == false) return false 51 | this.lp.luaInfoManager.currentFcim.setBeginFunName(funName,luaInfo.params); 52 | this.lp.tokenIndex++; 53 | //进行方法内的解析 54 | var isEnd = this.lp.setLuaInfo(luaInfo, function (luaParse: LuaParse) { 55 | 56 | var token: TokenInfo = luaParse.getTokenByIndex(luaParse.tokenIndex, null) 57 | if (token == null) { 58 | luaParse.setError(luaParse.getLastToken(), "function 未结束", luaInfo.startToken) 59 | //"start line:"+luaInfo.startToken.line + " function 未结束" 60 | } 61 | if (luaParse.isError) { 62 | return false 63 | } 64 | if (luaParse.consume('end', token, TokenTypes.Keyword)) { 65 | if (isSemicolons) { 66 | luaParse.checkSemicolons() 67 | } 68 | luaParse.tokenIndex++; 69 | 70 | return true 71 | } 72 | return false 73 | }, checkBreak) 74 | if (isEnd) { 75 | 76 | 77 | this.lp.luaInfoManager.currentFcim.setEndFun(); 78 | return true 79 | } 80 | else { 81 | if (this.lp.isError) return; 82 | var currerntToken = this.lp.getCurrentToken(null) 83 | if(currerntToken== null){ 84 | currerntToken = this.lp.getLastToken() 85 | } 86 | this.lp.setError(currerntToken, "function 未结束",luaInfo.startToken) 87 | return false 88 | } 89 | 90 | } 91 | 92 | /** 93 | * 解析方法参数 94 | */ 95 | public setFunctionParam(luaInfo: LuaInfo) { 96 | // console.log("解析 方法参数 中...") 97 | //判断是否为 '(' 98 | var bracketToken = this.lp.getNextToken("function 未结束") 99 | if (bracketToken === null) return false 100 | if (!this.lp.consume('(', bracketToken, TokenTypes.Punctuator)) { 101 | this.lp.setError(bracketToken, "意外的字符") 102 | return false 103 | } 104 | 105 | var bracketToken = this.lp.getNextToken("function 未结束") 106 | if (bracketToken === null) return false 107 | //判断是不是没有参数 108 | if (this.lp.consume(')', bracketToken, TokenTypes.Punctuator)) { 109 | 110 | return true; 111 | } 112 | this.lp.tokenIndex--; 113 | var bracketCount: number = 0 114 | //方法参数只接受 TokenTypes.Identifier TokenTypes.VarargLiteral 115 | var isFist = true; 116 | while (true) { 117 | CLog(); 118 | if (!isFist) { 119 | //检查逗号 120 | var commaToken = this.lp.getTokenByIndex(this.lp.tokenIndex + 1, "function 未结束");// this.getNextToken("方法未完成") 121 | if (commaToken == null) return false; 122 | if (!this.lp.consume(',', commaToken, TokenTypes.Punctuator)) { 123 | this.lp.setError(commaToken, "应该为 ','") 124 | return false 125 | } else { 126 | this.lp.tokenIndex++; 127 | } 128 | } 129 | var paramToken = this.lp.getNextToken("参数 定义 未完成"); 130 | if (paramToken == null) return false; 131 | if (paramToken.type == TokenTypes.Identifier || paramToken.type == TokenTypes.VarargLiteral) { 132 | isFist = false; 133 | // if(paramToken.type == TokenTypes.Identifier) 134 | // { 135 | // var pluaInfo:LuaInfo = new LuaInfo(paramToken); 136 | // pluaInfo.setEndToken(paramToken) 137 | // } 138 | var index = luaInfo.addParam(paramToken.value) 139 | if(ExtensionManager.em.luaIdeConfigManager.luaFunArgCheck) 140 | { 141 | 142 | if (index > -1) { 143 | this.lp.setError(paramToken, "方法参数:'"+ paramToken.value + "'在第" + index + " 个参数已经存在") 144 | return false; 145 | } 146 | } 147 | 148 | //判断有没有结束 149 | if (this.lp.consume(')', this.lp.getTokenByIndex(this.lp.tokenIndex + 1, "function 未结束"), TokenTypes.Punctuator)) { 150 | this.lp.tokenIndex++; 151 | return true; 152 | } 153 | } 154 | else { 155 | this.lp.setError(paramToken, "意外的字符") 156 | return false 157 | } 158 | 159 | } 160 | 161 | } 162 | 163 | 164 | 165 | 166 | 167 | } -------------------------------------------------------------------------------- /src/luatool/LuaIfLogic.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | export class LuaIfLogic { 4 | private lp: LuaParse; 5 | constructor(luaparse: LuaParse) { 6 | this.lp = luaparse; 7 | } 8 | 9 | /** 10 | * 检查if 语句 11 | * isElseIf 是否检查 elseif 默认为false 12 | */ 13 | public check(parent: LuaInfo, isIf:boolean, isElseIf: boolean , isElse:boolean,checkBreak:Function): boolean { 14 | 15 | //创建一个luaInfo 标识未 ifLuaInfo 16 | 17 | var token: TokenInfo = this.lp.getCurrentToken("代码未完成") 18 | var luaInfo: LuaInfo = new LuaInfo(token) 19 | if(this.lp.isError)return 20 | var returnValue:any = false 21 | if (this.lp.consume('if', token, TokenTypes.Keyword)) { 22 | luaInfo.type = LuaInfoType.IF 23 | luaInfo.name = token.value 24 | returnValue = this.checkIfAndElseIF(luaInfo,token,checkBreak) 25 | 26 | } 27 | else if(isElseIf == true && this.lp.consume('elseif', token, TokenTypes.Keyword)) 28 | { 29 | luaInfo.type = LuaInfoType.ELSEIF 30 | luaInfo.name = token.value 31 | returnValue = this.checkIfAndElseIF(luaInfo,token,checkBreak) 32 | }else if(isElse == true && this.lp.consume('else', token, TokenTypes.Keyword)) 33 | { 34 | luaInfo.type = LuaInfoType.ELSE 35 | luaInfo.name = token.value 36 | returnValue = this.checkLuaInfos(luaInfo,false,false,checkBreak); 37 | } 38 | else 39 | { 40 | return false 41 | } 42 | 43 | if(returnValue == "end") 44 | { 45 | this.lp.tokenIndex++; 46 | return true 47 | }else 48 | { 49 | if(returnValue == "elseif") 50 | { 51 | var re = this.check(luaInfo,false,true,true,checkBreak) 52 | if(this.lp.isError)return false 53 | if(re == false) 54 | { 55 | 56 | this.lp.setError(this.lp.getCurrentToken(null), luaInfo.name + " 代码未完成") 57 | return false 58 | } 59 | return re 60 | }else if(returnValue == "else") 61 | { 62 | this.lp.tokenIndex++; 63 | var revalue = this.checkLuaInfos(luaInfo,false,false,checkBreak) 64 | if(this.lp.isError)return false 65 | if(revalue == "end") 66 | { 67 | this.lp.tokenIndex++; 68 | return true 69 | }else 70 | { 71 | this.lp.setError(this.lp.getCurrentToken(null),luaInfo.name + " 代码未完成") 72 | return false 73 | } 74 | 75 | }else 76 | { 77 | if(this.lp.isError)return false 78 | this.lp.setError(this.lp.getLastToken(), luaInfo.name + " 代码未完成") 79 | return false 80 | } 81 | 82 | } 83 | 84 | 85 | 86 | } 87 | 88 | public checkIfAndElseIF(luaInfo:LuaInfo,token:TokenInfo,checkBreak:Function):any 89 | { 90 | 91 | 92 | this.lp.tokenIndex++; 93 | this.lp.luaSetValue.check(false,false,null) 94 | if (this.lp.isError) return false 95 | var thenToken = this.lp.getNextToken("缺少 then") 96 | if (this.lp.isError) return false 97 | if (!this.lp.consume('then', thenToken, TokenTypes.Keyword)) { 98 | this.lp.setError(thenToken, "应该为then") 99 | if (this.lp.isError) return false 100 | } 101 | this.lp.tokenIndex++; 102 | return this.checkLuaInfos(luaInfo,true,true,checkBreak); 103 | } 104 | 105 | public checkLuaInfos(LuaInfo:LuaInfo,isCheckElseIf:boolean,ischeckElse:boolean,checkBreak:Function):any 106 | { 107 | // var token: TokenInfo = this.lp.getTokenByIndex(this.lp.tokenIndex, "代码未完成") 108 | // if(this.lp.isError)return false 109 | // if (this.lp.consume('end', token, TokenTypes.Keyword)) { 110 | // this.lp.tokenIndex++; 111 | // this.lp.checkComma() 112 | // return "end" 113 | // } 114 | var returnValue:any = this.lp.setLuaInfo(LuaInfo, 115 | function (luaParse: LuaParse):any { 116 | 117 | var token: TokenInfo = luaParse.getTokenByIndex(luaParse.tokenIndex , "代码未完成") 118 | if (luaParse.isError) return false 119 | if (luaParse.consume('end', token, TokenTypes.Keyword)) { 120 | 121 | luaParse.checkSemicolons() 122 | return "end" 123 | } else if (isCheckElseIf == true && luaParse.consume('elseif', token, TokenTypes.Keyword)) { 124 | return "elseif" 125 | } else if (ischeckElse == true && luaParse.consume('else', token, TokenTypes.Keyword)) 126 | { 127 | return "else" 128 | } 129 | return false 130 | },checkBreak) 131 | return returnValue 132 | } 133 | 134 | 135 | 136 | } -------------------------------------------------------------------------------- /src/luatool/LuaInfoManager.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType } from './TokenInfo'; 2 | import { LuaParse } from "./LuaParse" 3 | import { CompletionItem, CompletionItemKind, Uri } from "vscode" 4 | import { LuaFiledCompletionInfo } from "./provider/LuaFiledCompletionInfo" 5 | import { FileCompletionItemManager, CompletionItemSimpleInfo } from "./manager/FileCompletionItemManager" 6 | import { CLog,getCurrentFunctionName } from './Utils' 7 | import vscode = require('vscode'); 8 | import { LuaFileCompletionItems } from "./manager/LuaFileCompletionItems"; 9 | 10 | export class FindCompletionInfo { 11 | public moduleName: string; 12 | public keys: Array; 13 | } 14 | 15 | 16 | export class LuaInfoManager { 17 | 18 | public tokens: Array; 19 | public fileCompletionItemManagers: Map; 20 | 21 | public lp: LuaParse; 22 | 23 | 24 | public currentFcim: FileCompletionItemManager; 25 | 26 | constructor() { 27 | 28 | this.fileCompletionItemManagers = new Map(); 29 | } 30 | private initKeyWrodCompletioins() { 31 | 32 | } 33 | public setFcim(uri: Uri, fcim: FileCompletionItemManager) { 34 | this.fileCompletionItemManagers.set(uri.path, fcim); 35 | } 36 | public getFcim(uri: Uri): FileCompletionItemManager { 37 | var fcim: FileCompletionItemManager = null; 38 | if (this.fileCompletionItemManagers.has(uri.path)) { 39 | fcim = this.fileCompletionItemManagers.get(uri.path) 40 | } 41 | return fcim; 42 | } 43 | public getFcimByPathStr(path:string):FileCompletionItemManager 44 | { 45 | var fcim: FileCompletionItemManager = null; 46 | if (this.fileCompletionItemManagers.has(path)) { 47 | fcim = this.fileCompletionItemManagers.get(path) 48 | } 49 | return fcim; 50 | } 51 | public init(lp: LuaParse, uri: Uri, tempUri: Uri) { 52 | this.lp = lp; 53 | this.tokens = lp.tokens; 54 | this.currentFcim = new FileCompletionItemManager(tempUri); 55 | this.fileCompletionItemManagers.set(uri.path, this.currentFcim); 56 | 57 | } 58 | public addFunctionCompletionItem(luaInfo: LuaInfo, token: TokenInfo, functionEndToken: TokenInfo) { 59 | this.currentFcim.addFunctionCompletion(this.lp, luaInfo, token, functionEndToken) 60 | } 61 | public addCompletionItem(luaInfo: LuaInfo, token: TokenInfo): LuaFiledCompletionInfo { 62 | 63 | var completion = this.currentFcim.addCompletionItem(this.lp, 64 | luaInfo, token, this.tokens,false,true); 65 | 66 | 67 | return completion 68 | 69 | } 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | public addSymbol(luaInfo: LuaInfo, token: TokenInfo, functionEndToken: TokenInfo, symolName: string) { 78 | this.currentFcim.addSymbol(this.lp, luaInfo, token, functionEndToken, symolName) 79 | } 80 | 81 | 82 | 83 | public addGlogCompletionItems(items: Array) { 84 | this.fileCompletionItemManagers.forEach((v, k) => { 85 | if (k != LuaParse.checkTempFilePath) { 86 | items.push(v.luaGolbalCompletionInfo) 87 | } 88 | 89 | }) 90 | this.fileCompletionItemManagers.forEach((v, k) => { 91 | if (k != LuaParse.checkTempFilePath) { 92 | items.push(v.luaFunCompletionInfo) 93 | } 94 | 95 | }) 96 | } 97 | 98 | 99 | 100 | 101 | 102 | 103 | public getFunctionArgs(tokens: Array, uri: Uri) { 104 | var fcim: FileCompletionItemManager = this.getFcimByPathStr(uri.path) 105 | var funNames: Array = getCurrentFunctionName(tokens) 106 | if (fcim == null) { 107 | return []; 108 | } 109 | return fcim.getSymbolArgsByNames(funNames) 110 | 111 | 112 | } 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | } -------------------------------------------------------------------------------- /src/luatool/LuaLeftCheck.ts: -------------------------------------------------------------------------------- 1 | import {LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | import {CLog} from './Utils' 4 | export class LuaLeftCheck { 5 | private lp: LuaParse; 6 | 7 | constructor(luaparse: LuaParse) { 8 | this.lp = luaparse; 9 | } 10 | 11 | /**是否为 多变量声明 */ 12 | public isMultipleVariables:boolean =false 13 | public luaInfos:Array; 14 | public parent:LuaInfo; 15 | public isLocal:boolean; 16 | 17 | public check(parent: LuaInfo) { 18 | this.luaInfos = new Array(); 19 | this.isLocal = false; 20 | this.isMultipleVariables = false; 21 | this.parent = parent; 22 | //创建leftLuaInfo 23 | var toekn:TokenInfo = this.lp.getCurrentToken(null) 24 | 25 | var currentLuaInfo:LuaInfo = new LuaInfo(toekn) 26 | this.isLocal = this.checkIsLocal(currentLuaInfo) 27 | if(this.lp.isError)return 28 | currentLuaInfo.isLocal = this.isLocal; 29 | currentLuaInfo.isVar = true 30 | if(this.isLocal) 31 | { 32 | currentLuaInfo.startToken = this.lp.getCurrentToken(null); 33 | currentLuaInfo.startToken.comments = this.lp.getUpToken().comments; 34 | } 35 | this.luaInfos.push(currentLuaInfo) 36 | this.checkLeftExoression(currentLuaInfo,new Array()) 37 | currentLuaInfo = null 38 | 39 | } 40 | 41 | /** 42 | * 是否是local 43 | */ 44 | public checkIsLocal(luaInfo:LuaInfo): boolean { 45 | var token = this.lp.getCurrentToken("代码未完成"); 46 | if(this.lp.isError)return false 47 | var isLocal: boolean = this.lp.consume('local', token, TokenTypes.Keyword) 48 | if (isLocal) 49 | { 50 | this.lp.tokenIndex++; 51 | luaInfo.setComments(token.comments) 52 | } 53 | return isLocal; 54 | } 55 | 56 | /** 57 | * 检查 变量声明 58 | * @isIdentifier 是否必须为 TokenTypes.Identifier 类型 59 | */ 60 | public checkLeftExoression( leftLuaInfo: LuaInfo,leftLuaInfos:Array) { 61 | while(true) 62 | { 63 | CLog(); 64 | this.lp.luaChuckInfo.check(leftLuaInfo,true) 65 | if(this.lp.isError)return 66 | //方法调用直接退出 67 | if(leftLuaInfo.type == LuaInfoType.FunctionCall1) 68 | { 69 | return 70 | } 71 | if(!leftLuaInfo.isNextCheck) 72 | { 73 | 74 | return; 75 | } 76 | 77 | var token:TokenInfo = this.lp.getTokenByIndex(this.lp.tokenIndex+1,null) 78 | if(token == null) 79 | { 80 | if(leftLuaInfo.isLocal == false ) 81 | { 82 | var last:LuaInfo= leftLuaInfo.getLastLuaInfo(); 83 | // leftLuaInfo.type == LuaInfoType.Function 84 | var type = leftLuaInfo.type 85 | if(type != LuaInfoType.AnonymousFunction) 86 | { 87 | this.lp.setError(leftLuaInfo.startToken, "没有赋值") 88 | } 89 | 90 | } 91 | leftLuaInfo.setEndToken(this.lp.getCurrentToken(null)) 92 | return 93 | } 94 | this.lp.tokenIndex++; 95 | //赋值 96 | if(this.lp.consume('=', token, TokenTypes.Punctuator) ) 97 | { 98 | var endToken:TokenInfo = this.lp.getUpToken() 99 | 100 | leftLuaInfos.push(leftLuaInfo) 101 | this.lp.tokenIndex++; 102 | //设置value 103 | this.lp.luaSetValue.check(true,true,leftLuaInfos) 104 | if(leftLuaInfo.type == LuaInfoType.Function) 105 | { 106 | this.lp.luaInfoManager.addFunctionCompletionItem(leftLuaInfo,endToken,this.lp.getUpToken()) 107 | }else 108 | { 109 | leftLuaInfo.setEndToken(endToken); 110 | } 111 | 112 | return 113 | } 114 | else if(this.lp.consume(',', token, TokenTypes.Punctuator)) 115 | { 116 | 117 | leftLuaInfo.setEndToken(this.lp.getUpToken()) 118 | leftLuaInfos.push(leftLuaInfo) 119 | this.lp.tokenIndex++; 120 | this.isMultipleVariables = true 121 | var currentLuaInfo : LuaInfo = new LuaInfo(this.lp.getTokenByIndex(this.lp.tokenIndex,null)) 122 | currentLuaInfo.isLocal = this.isLocal 123 | currentLuaInfo.isVar = true 124 | currentLuaInfo.ismultipleVariables = true 125 | this.luaInfos.push(currentLuaInfo) 126 | this.checkLeftExoression(currentLuaInfo,leftLuaInfos) 127 | return 128 | } 129 | else if(this.lp.consume(';', token, TokenTypes.Punctuator)) 130 | { 131 | if(this.isLocal == false || (this.isLocal && this.isMultipleVariables)) 132 | { 133 | this.lp.setError(this.lp.getCurrentToken(null), "没有赋值") 134 | 135 | } 136 | leftLuaInfo.setEndToken(this.lp.getUpToken()) 137 | // this.lp.tokenIndex++; 138 | return 139 | } 140 | else 141 | { 142 | if(this.isLocal == false) 143 | { 144 | if(token.type == TokenTypes.StringLiteral) 145 | { 146 | return 147 | } 148 | else if(!this.lp.consume('=', token, TokenTypes.Punctuator) ) 149 | { 150 | if(token.type == TokenTypes.Identifier){ 151 | this.lp.setError(this.lp.getTokenByIndex(this.lp.tokenIndex, null),"我猜测这是一个方法参数,但是请加()") 152 | } 153 | else 154 | { 155 | this.lp.setError(this.lp.getTokenByIndex(this.lp.tokenIndex-1, null),"没有赋值") 156 | } 157 | return false 158 | } 159 | } 160 | leftLuaInfo.setEndToken(this.lp.getUpToken()) 161 | this.lp.tokenIndex--; 162 | return 163 | } 164 | } 165 | 166 | } 167 | 168 | 169 | 170 | public checkLastLuaInfoType(luaInfo:LuaInfo,type: LuaInfoType):boolean 171 | { 172 | while(true) 173 | { 174 | CLog(); 175 | if(luaInfo.getNextLuaInfo() == null) 176 | { 177 | if(luaInfo.type == type)return true 178 | else return false 179 | }else 180 | { 181 | luaInfo =luaInfo.getNextLuaInfo(); 182 | } 183 | } 184 | } 185 | 186 | 187 | 188 | } -------------------------------------------------------------------------------- /src/luatool/LuaSetValue.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, LuaInfoTypeValue, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | import {CLog} from './Utils' 4 | export class LuaSetValue { 5 | private lp: LuaParse; 6 | constructor(luaparse: LuaParse) { 7 | this.lp = luaparse; 8 | } 9 | //value 只能是 10 | /**是否检查分号 */ 11 | public check(isSemicolons:boolean,isComma:boolean,leftLuaInfos:Array,index:number=0):Array { 12 | var luaInfo:LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 13 | 14 | //检查是否为一元 15 | var luainfos: Array = new Array() 16 | while (true) { 17 | CLog(); 18 | var nextLuaInfo: LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 19 | luainfos.push(nextLuaInfo) 20 | this.lp.luaCheckUnary.check(nextLuaInfo); 21 | nextLuaInfo.startToken = this.lp.getCurrentToken(null); 22 | this.lp.luaChuckInfo.check(nextLuaInfo,isSemicolons) 23 | 24 | if (this.lp.isError) return null 25 | if(nextLuaInfo.type == LuaInfoType.Function) 26 | { 27 | if(nextLuaInfo.unarys.length == 0) { 28 | nextLuaInfo.valueType = LuaInfoTypeValue.Function 29 | if(leftLuaInfos != null && index <= leftLuaInfos.length-1) 30 | { 31 | var linfo:LuaInfo = leftLuaInfos[index]; 32 | linfo.params =nextLuaInfo.params; 33 | linfo.type = LuaInfoType.Function; 34 | } 35 | 36 | 37 | }else 38 | { 39 | this.lp.setError(nextLuaInfo.unarys[0],"function 定义前有多余字符") 40 | 41 | } 42 | } 43 | 44 | if(nextLuaInfo.type == LuaInfoType.Table){ 45 | nextLuaInfo.valueType = LuaInfoTypeValue.Table 46 | if(leftLuaInfos != null && index <= leftLuaInfos.length-1) 47 | { 48 | var linfo:LuaInfo = leftLuaInfos[index]; 49 | linfo.tableFileds =nextLuaInfo.tableFileds; 50 | 51 | } 52 | //table 直接返回 53 | 54 | 55 | } 56 | var nextToken: TokenInfo = this.lp.getNextToken(null); 57 | if(nextToken == null) 58 | { 59 | this.lp.luaCheckLuaInfos.check(luainfos,luaInfo) 60 | if(nextLuaInfo.type != LuaInfoType.FunctionCall1 61 | ) 62 | { 63 | nextLuaInfo.setEndToken(this.lp.getUpToken()) 64 | } 65 | 66 | 67 | 68 | return luainfos 69 | } 70 | //验证是否为括号 ] 71 | //判断二元 72 | 73 | if (this.lp.luaValidateOperator.check(nextToken)) { 74 | 75 | nextLuaInfo.setEndToken(this.lp.getUpToken()) 76 | this.lp.tokenIndex++; 77 | nextLuaInfo.operatorToken = nextToken 78 | continue 79 | } 80 | else if(this.lp.consume(',',nextToken,TokenTypes.Punctuator)) 81 | { 82 | if(leftLuaInfos != null && index > leftLuaInfos.length -1) 83 | { 84 | this.lp.setError(nextToken,"多余的变量赋值"); 85 | return 86 | } 87 | nextLuaInfo.setEndToken(this.lp.getUpToken()) 88 | if(isComma){ 89 | this.lp.tokenIndex++; 90 | this.lp.luaCheckLuaInfos.check(luainfos,luaInfo) 91 | if(this.lp.isError)return 92 | 93 | this.check(isSemicolons,isComma,leftLuaInfos,++index); 94 | 95 | return luainfos 96 | }else 97 | { 98 | this.lp.luaCheckLuaInfos.check(luainfos,luaInfo) 99 | this.lp.tokenIndex--; 100 | return luainfos 101 | } 102 | } 103 | else if( this.lp.consume(';',nextToken,TokenTypes.Punctuator)) 104 | { 105 | this.lp.luaCheckLuaInfos.check(luainfos,luaInfo) 106 | if(isSemicolons == false) 107 | { 108 | this.lp.tokenIndex--; 109 | } 110 | return luainfos 111 | } 112 | else { 113 | 114 | if(nextLuaInfo.type == LuaInfoType.Field && nextToken.type == TokenTypes.StringLiteral) 115 | { 116 | var upToken:TokenInfo = this.lp.getUpToken(); 117 | nextLuaInfo.type = LuaInfoType.FunctionCall1 118 | 119 | }else 120 | { 121 | this.lp.tokenIndex--; 122 | } 123 | this.lp.luaCheckLuaInfos.check(luainfos,luaInfo) 124 | if(nextLuaInfo.type != LuaInfoType.Bracket_M && 125 | nextLuaInfo.getLastLuaInfo().type != LuaInfoType.FunctionCall1 126 | ){ 127 | 128 | 129 | nextLuaInfo.setEndToken(this.lp.getCurrentToken(null)) 130 | } 131 | return luainfos 132 | } 133 | } 134 | 135 | } 136 | 137 | 138 | } -------------------------------------------------------------------------------- /src/luatool/LuaTableParse.ts: -------------------------------------------------------------------------------- 1 | import {LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | import {CLog} from './Utils' 4 | 5 | export class LuaTableParse { 6 | private lp: LuaParse; 7 | 8 | constructor(luaparse: LuaParse) { 9 | this.lp = luaparse; 10 | } 11 | 12 | 13 | public check(luaInfo:LuaInfo) 14 | { 15 | 16 | luaInfo.type = LuaInfoType.Table; 17 | 18 | while(true) 19 | { 20 | CLog(); 21 | var token:TokenInfo = this.lp.getTokenByIndex(this.lp.tokenIndex + 1,"table 未完成"); 22 | if(this.lp.consume('}',token,TokenTypes.Punctuator)) 23 | { 24 | this.lp.tokenIndex++; 25 | return 26 | } 27 | if(this.lp.isError)return 28 | if(token.type == TokenTypes.Identifier) 29 | { 30 | 31 | var nextToken:TokenInfo = this.lp.getTokenByIndex(this.lp.tokenIndex + 2,"table 未完成"); 32 | if(this.lp.isError)return 33 | if(this.lp.consume('=',nextToken,TokenTypes.Punctuator)) 34 | { 35 | var fluaInfo:LuaInfo = new LuaInfo(nextToken); 36 | fluaInfo.name = token.value; 37 | fluaInfo.endToken = nextToken; 38 | var leftLuaInfos:Array = new Array(); 39 | leftLuaInfos.push(fluaInfo) 40 | this.lp.tokenIndex+= 3; 41 | luaInfo.tableFileds.push(fluaInfo); 42 | this.lp.luaSetValue.check(false,false,leftLuaInfos); 43 | 44 | }else 45 | { 46 | this.lp.tokenIndex++; 47 | this.lp.luaSetValue.check(false,false,null); 48 | 49 | } 50 | } 51 | else if(this.lp.consume('[',token,TokenTypes.Punctuator)) 52 | { 53 | this.lp.tokenIndex += 2; 54 | var startIndex:number = this.lp.tokenIndex; 55 | var newLuaInfo:LuaInfo = new LuaInfo(token) 56 | this.lp.luaValidateBracket_G.check(newLuaInfo,false) 57 | var endIndex:number =this.lp.tokenIndex; 58 | var nextToken:TokenInfo = this.lp.getNextToken("代码未完成") 59 | if(this.lp.isError)return 60 | if(this.lp.consume('=',nextToken,TokenTypes.Punctuator)) 61 | { 62 | 63 | if(endIndex - startIndex == 1) 64 | { 65 | var token:TokenInfo = this.lp.tokens[startIndex]; 66 | newLuaInfo.name = "["+ token.value +"]" 67 | newLuaInfo.tableFiledType =1; 68 | luaInfo.tableFileds.push(newLuaInfo); 69 | 70 | } 71 | var leftLuaInfos:Array = new Array(); 72 | leftLuaInfos.push(newLuaInfo) 73 | this.lp.tokenIndex+= 1; 74 | this.lp.luaSetValue.check(false,false,leftLuaInfos); 75 | 76 | }else 77 | { 78 | this.lp.setError(nextToken,"缺少 '='") 79 | return 80 | 81 | } 82 | 83 | } 84 | else 85 | { 86 | this.lp.tokenIndex++; 87 | this.lp.luaSetValue.check(false,false,null) 88 | } 89 | token = this.lp.getTokenByIndex(this.lp.tokenIndex + 1,"table 未完成"); 90 | if(this.lp.consume(',',token,TokenTypes.Punctuator) || this.lp.consume(';',token,TokenTypes.Punctuator)) 91 | { 92 | this.lp.tokenIndex++; 93 | var endToken:TokenInfo = this.lp.getTokenByIndex(this.lp.tokenIndex + 1,"table 未完成"); 94 | if(this.lp.consume('}',endToken,TokenTypes.Punctuator)) 95 | { 96 | // luaInfo.endToken = endToken; 97 | this.lp.tokenIndex++; 98 | return 99 | }else 100 | { 101 | continue; 102 | } 103 | }else if(this.lp.consume('}',token,TokenTypes.Punctuator)) 104 | { 105 | // luaInfo.endToken = token; 106 | this.lp.tokenIndex++; 107 | return 108 | }else 109 | { 110 | this.lp.setError(token,"table 定义出现意外字符") 111 | return 112 | } 113 | 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /src/luatool/LuaValidateBracket_G.ts: -------------------------------------------------------------------------------- 1 | import {LuaInfo, LuaInfoTypeValue, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | import {CLog} from './Utils' 4 | export class LuaValidateBracket_G { 5 | private lp: LuaParse; 6 | 7 | constructor(luaparse: LuaParse) { 8 | this.lp = luaparse; 9 | } 10 | /**验证中括号 */ 11 | public check(luaInfo: LuaInfo, isNext: boolean): LuaInfo { 12 | 13 | var exToken = this.lp.getCurrentToken("代码未完成"); 14 | if (exToken == null) return null; 15 | if (this.lp.consume(']', exToken, TokenTypes.Punctuator)) { 16 | this.lp.setError(exToken, "[] 中间不能为空! "); 17 | return null; 18 | } 19 | var luainfos: Array = new Array() 20 | while (true) { 21 | CLog(); 22 | var nextLuaInfo: LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 23 | 24 | luainfos.push(nextLuaInfo) 25 | this.lp.luaSetValue.check(false,false,[nextLuaInfo]) 26 | 27 | 28 | if (this.lp.isError) return null 29 | var nextToken: TokenInfo = this.lp.getNextToken("代码未完成"); 30 | if (this.lp.isError) return 31 | //验证是否为括号 ] 32 | //判断二元 33 | if (this.lp.consume(']', nextToken, TokenTypes.Punctuator)) { 34 | //这里检查表达式的合法性 35 | 36 | this.lp.luaCheckLuaInfos.check(luainfos, luaInfo) 37 | luaInfo.bracket_Gs = luainfos; 38 | luaInfo.valueType = LuaInfoTypeValue.ANY; 39 | if (!isNext) return 40 | nextToken = this.lp.getTokenByIndex(this.lp.tokenIndex + 1, null); 41 | if (nextToken) { 42 | 43 | 44 | if (this.lp.consume('.', nextToken, TokenTypes.Punctuator)) { 45 | this.lp.tokenIndex++; 46 | var newLuaInfo: LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 47 | nextToken = this.lp.getNextToken("代码未完成") 48 | if (this.lp.isError) return; 49 | if (nextToken.type != TokenTypes.Identifier) { 50 | this.lp.setError(nextToken, "意外的字符") 51 | return; 52 | 53 | } else { 54 | 55 | } 56 | 57 | luaInfo.setNextLuaInfo(newLuaInfo); 58 | this.lp.luaChuckInfo.check(newLuaInfo, true) 59 | 60 | if (this.lp.isError) return 61 | return; 62 | } else if (this.lp.consume('[', nextToken, TokenTypes.Punctuator)) { 63 | this.lp.tokenIndex += 2; 64 | this.lp.luaValidateBracket_G.check(luaInfo, isNext) 65 | break; 66 | } 67 | else if (this.lp.consume('(', nextToken, TokenTypes.Punctuator)) { 68 | 69 | this.lp.tokenIndex++; 70 | this.lp.functionCall.check(luaInfo, true, false); 71 | break; 72 | } 73 | else if (this.lp.consume(':', nextToken, TokenTypes.Punctuator)) { 74 | this.lp.tokenIndex += 2; 75 | if (luainfos.length == 1) { 76 | 77 | this.lp.luaChuckInfo.checkModuleFunctionCall(luaInfo, true) 78 | 79 | } else { 80 | this.lp.luaChuckInfo.checkModuleFunctionCall(luaInfo, true) 81 | } 82 | luaInfo.type = LuaInfoType.FunctionCall1; 83 | return; 84 | } else if (this.lp.consume('=', nextToken, TokenTypes.Punctuator)) { 85 | luaInfo.getTopLuaInfo().isNextCheck = true 86 | return 87 | } else return 88 | } else 89 | { 90 | return 91 | } 92 | } 93 | 94 | if (this.lp.luaValidateOperator.check(nextToken)) { 95 | this.lp.tokenIndex++; 96 | nextLuaInfo.operatorToken = nextToken 97 | continue 98 | } else { 99 | this.lp.setError(nextToken, "错误的字符") 100 | return 101 | } 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /src/luatool/LuaValidateBracket_M.ts: -------------------------------------------------------------------------------- 1 | import {LuaInfo, TokenInfo, LuaInfoTypeValue, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | import {CLog} from './Utils' 4 | /**验证 ( */ 5 | export class LuaValidateBracket_M { 6 | private lp: LuaParse; 7 | 8 | constructor(luaparse: LuaParse) { 9 | this.lp = luaparse; 10 | } 11 | 12 | /**验证 小括号( */ 13 | public check(luaInfo: LuaInfo): boolean { 14 | //缓存 一元运算符号 15 | // var unary: string = luaInfo.unary 16 | 17 | // luaInfo.unary = "" 18 | var exToken = this.lp.getCurrentToken( "代码未完成"); 19 | if (exToken == null) return false; 20 | if (this.lp.consume(')', exToken, TokenTypes.Punctuator)) { 21 | this.lp.setError(exToken, "() 中间不能为空! "); 22 | 23 | return false 24 | } 25 | var luainfos:Array = new Array() 26 | while (true) { 27 | CLog(); 28 | var nextLuaInfo: LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 29 | luainfos.push(nextLuaInfo) 30 | this.lp.luaCheckUnary.check(nextLuaInfo); 31 | this.lp.luaChuckInfo.check(nextLuaInfo,false) 32 | 33 | if (this.lp.isError) return null 34 | var nextToken:TokenInfo = this.lp.getNextToken("代码未完成"); 35 | if(this.lp.isError)return 36 | //验证是否为括号 ] 37 | //判断二元 38 | if (this.lp.consume(')', nextToken, TokenTypes.Punctuator)) { 39 | //这里检查表达式的合法性 40 | 41 | this.lp.luaCheckLuaInfos.check(luainfos,luaInfo) 42 | nextLuaInfo.type = LuaInfoType.Field; 43 | nextLuaInfo.setEndToken(this.lp.getCurrentToken(null)) 44 | luaInfo.valueType = LuaInfoTypeValue.ANY; 45 | luaInfo.type = LuaInfoType.Bracket_M 46 | 47 | nextToken = this.lp.getTokenByIndex(this.lp.tokenIndex + 1, null); 48 | if (nextToken) { 49 | if (this.lp.consume('.', nextToken, TokenTypes.Punctuator)) { 50 | this.lp.tokenIndex++; 51 | var newLuaInfo: LuaInfo = new LuaInfo(this.lp.getCurrentToken(null)) 52 | nextToken = this.lp.getNextToken("代码未完成") 53 | if (this.lp.isError) return; 54 | if (nextToken.type != TokenTypes.Identifier) { 55 | this.lp.setError(nextToken, "意外的字符") 56 | return; 57 | 58 | } else { 59 | 60 | } 61 | 62 | luaInfo.setNextLuaInfo(newLuaInfo); 63 | this.lp.luaChuckInfo.check(newLuaInfo, true) 64 | 65 | if (this.lp.isError) return 66 | return; 67 | } else if (this.lp.consume('[', nextToken, TokenTypes.Punctuator)) { 68 | this.lp.tokenIndex += 2; 69 | this.lp.luaValidateBracket_G.check(luaInfo, true) 70 | break; 71 | } 72 | else if (this.lp.consume('(', nextToken, TokenTypes.Punctuator)) { 73 | 74 | this.lp.tokenIndex++; 75 | this.lp.functionCall.check(luaInfo, true, false); 76 | break; 77 | } 78 | else if (this.lp.consume(':', nextToken, TokenTypes.Punctuator)) { 79 | this.lp.tokenIndex += 2; 80 | if (luainfos.length == 1) { 81 | this.lp.luaChuckInfo.checkModuleFunctionCall(luaInfo, true) 82 | } else { 83 | this.lp.luaChuckInfo.checkModuleFunctionCall(luaInfo, true) 84 | } 85 | luaInfo.type = LuaInfoType.FunctionCall1; 86 | return; 87 | } else if (this.lp.consume('=', nextToken, TokenTypes.Punctuator)) { 88 | return 89 | } else return 90 | } 91 | } 92 | if( this.lp.luaValidateOperator.check(nextToken)) 93 | { 94 | nextLuaInfo.setEndToken(this.lp.getUpToken()) 95 | this.lp.tokenIndex++; 96 | nextLuaInfo.operatorToken = nextToken 97 | 98 | continue 99 | }else 100 | { 101 | this.lp.setError(nextToken, "错误的字符") 102 | return 103 | } 104 | } 105 | } 106 | 107 | } -------------------------------------------------------------------------------- /src/luatool/LuaValidateConstValue.ts: -------------------------------------------------------------------------------- 1 | import {LuaInfo, LuaInfoTypeValue,TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | /**验证 是否为一个可以复制的 token */ 4 | export class LuaValidateConstValue { 5 | private lp: LuaParse; 6 | 7 | constructor(luaparse: LuaParse) { 8 | this.lp = luaparse; 9 | } 10 | /** 11 | * 验证是否是一个可以符值的token 12 | */ 13 | public check(token: TokenInfo, luaInfo: LuaInfo): boolean { 14 | 15 | if (token.type == TokenTypes.BooleanLiteral) { 16 | if(luaInfo.isVar== true) 17 | { 18 | this.lp.setError(token,"变量申明不能为 boolean") 19 | return 20 | } 21 | luaInfo.type = LuaInfoType.BOOLEAN 22 | luaInfo.valueType = LuaInfoTypeValue.BOOL 23 | return true 24 | } 25 | else if (token.type == TokenTypes.NilLiteral) { 26 | if(luaInfo.isVar== true) 27 | { 28 | this.lp.setError(token,"变量申明不能为 nil") 29 | return 30 | } 31 | luaInfo.type = LuaInfoType.NIL 32 | luaInfo.valueType = LuaInfoTypeValue.NIL 33 | return true 34 | } 35 | else if (token.type == TokenTypes.NumericLiteral) { 36 | if(luaInfo.isVar== true) 37 | { 38 | this.lp.setError(token,"变量申明不能为 number") 39 | return 40 | } 41 | luaInfo.valueType = LuaInfoTypeValue.NUMBER 42 | luaInfo.type = LuaInfoType.Number 43 | return true 44 | } 45 | else if (token.type == TokenTypes.StringLiteral) { 46 | if(luaInfo.isVar== true) 47 | { 48 | this.lp.setError(token,"变量申明不能为 string") 49 | return 50 | } 51 | luaInfo.valueType = LuaInfoTypeValue.STRING 52 | 53 | luaInfo.type = LuaInfoType.STRING 54 | return true 55 | } 56 | else if (token.type == TokenTypes.VarargLiteral) { 57 | if(luaInfo.isVar== true) 58 | { 59 | this.lp.setError(token,"变量申明不能为 ...") 60 | return 61 | } 62 | luaInfo.valueType = LuaInfoTypeValue.ANY 63 | luaInfo.type = LuaInfoType.Vararg 64 | return true 65 | } 66 | else if(token.type == TokenTypes.Identifier) 67 | { 68 | luaInfo.type = LuaInfoType.Field 69 | luaInfo.valueType = LuaInfoTypeValue.ANY 70 | return true 71 | } 72 | else { 73 | if(!this.lp.consume('(',token,TokenTypes.Punctuator)) 74 | { 75 | this.lp.setError(this.lp.getCurrentToken(null),"意外的字符"); 76 | this.lp.tokenIndex--; 77 | 78 | } 79 | return false 80 | } 81 | 82 | } 83 | } -------------------------------------------------------------------------------- /src/luatool/LuaValidateOperator.ts: -------------------------------------------------------------------------------- 1 | import {LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | /**验证 二元运算符号 */ 4 | export class LuaValidateOperator { 5 | private lp: LuaParse; 6 | 7 | constructor(luaparse: LuaParse) { 8 | this.lp = luaparse; 9 | } 10 | 11 | /** 12 | * 判断一个token 是否是一个运算符号 二元 13 | */ 14 | public check(token: TokenInfo): boolean { 15 | if (token.type === TokenTypes.Punctuator || token.type == TokenTypes.Keyword) { 16 | var value = token.value; 17 | if ( 18 | value == '+' || 19 | value == '-' || 20 | value == '*' || 21 | value == '/' || 22 | value == '>' || 23 | value == '<' || 24 | value == '>=' || 25 | value == '<=' || 26 | value == '%' || 27 | value == '&' || 28 | value == '~' || 29 | value == '|' || 30 | value == '<<' || 31 | value == '>>' || 32 | value == '^') { 33 | return true 34 | } 35 | else if (value == '..') { 36 | return true 37 | } 38 | else if ( 39 | value == '==' || 40 | value == '~=' || 41 | value == 'and' || 42 | value == 'or' 43 | ) { 44 | return true 45 | } else return false 46 | } else return false 47 | } 48 | 49 | 50 | } -------------------------------------------------------------------------------- /src/luatool/LuaWhileLogic.ts: -------------------------------------------------------------------------------- 1 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from './TokenInfo'; 2 | import {LuaParse} from './LuaParse' 3 | import {CLog} from './Utils' 4 | export class LuaWhileLogic { 5 | private lp: LuaParse; 6 | constructor(luaparse: LuaParse) { 7 | this.lp = luaparse; 8 | } 9 | 10 | /** 11 | * 检查if 语句 12 | */ 13 | public check(parent: LuaInfo): boolean { 14 | var token: TokenInfo = this.lp.getCurrentToken("代码未完成") 15 | if (this.lp.consume('while', token, TokenTypes.Keyword)) { 16 | this.lp.tokenIndex++; 17 | var luaInfo:LuaInfo = new LuaInfo(token) 18 | luaInfo.type = LuaInfoType.WHILE 19 | //先判断表达式 再判断 do 20 | this.lp.luaSetValue.check(true,false,null) 21 | if(this.lp.isError)return false 22 | var doToken:TokenInfo = this.lp.getNextToken("代码未完成") 23 | if(this.lp.isError)return false 24 | if(this.lp.consume('do',doToken,TokenTypes.Keyword)) 25 | { 26 | this.lp.tokenIndex++; 27 | var isEnd:boolean = this.lp.setLuaInfo(luaInfo,function(luaParse:LuaParse) 28 | { 29 | var token:TokenInfo = luaParse.getTokenByIndex(luaParse.tokenIndex,"代码未完成") 30 | if(luaParse.isError)return false 31 | if(luaParse.consume('end',token,TokenTypes.Keyword)) 32 | { 33 | luaParse.tokenIndex++; 34 | luaParse.checkSemicolons() 35 | return true 36 | } 37 | return false 38 | },this.lp.luaForLogic.checkBrreak) 39 | if(this.lp.isError)return false 40 | if(isEnd) 41 | { 42 | return true 43 | }else 44 | { 45 | this.lp.setError(this.lp.getLastToken(),"while 没有 结束 缺少 end") 46 | return false 47 | } 48 | 49 | 50 | 51 | }else 52 | { 53 | this.lp.setError(doToken,"应该为 do ") 54 | return false 55 | } 56 | 57 | }else 58 | return false 59 | 60 | } 61 | } -------------------------------------------------------------------------------- /src/luatool/LuacCheck.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | var path = require('path'); 3 | import child_process = require('child_process'); 4 | import { ExtensionManager } from './ex/ExtensionManager' 5 | export class LuacCheck{ 6 | //默认为5.1 7 | private luaPath:string; 8 | constructor() 9 | { 10 | // this.luaPath = this.getLuacPath() 11 | } 12 | 13 | private parseDiagnostics(data) { 14 | const diagnostics = []; 15 | var errorRegex = /.+: .+:([0-9]+): (.+) near.*[<'](.*)['>]/; 16 | // const errorRegex = /^.*:(\d+):(\d+)-(\d+): \(([EW]?)(\d+)\) (.*)$/mg; 17 | const matches = data.match(errorRegex); 18 | if (!matches) { 19 | return []; 20 | } 21 | while (true) { 22 | const m = errorRegex.exec(data); 23 | if (!m) { 24 | break; 25 | } 26 | const [, lineStr, columnStr, endColumnStr, type, codeStr, message] = m; 27 | const line = Number(lineStr) - 1; 28 | const column = Number(columnStr) - 1; 29 | const columnEnd = Number(endColumnStr); 30 | const code = Number(codeStr); 31 | // const mapSeverity = () => { 32 | // switch (type) { 33 | // case 'E': 34 | // return vscode_languageserver_1.DiagnosticSeverity.Error; 35 | // case 'W': 36 | // return vscode_languageserver_1.DiagnosticSeverity.Warning; 37 | // default: 38 | // return vscode_languageserver_1.DiagnosticSeverity.Information; 39 | // } 40 | // }; 41 | var range:vscode.Range = new vscode.Range(new vscode.Position(line,column),new vscode.Position(line,columnEnd)) 42 | 43 | diagnostics.push({ 44 | range: range, 45 | severity: vscode.DiagnosticSeverity.Error, 46 | code, 47 | source: 'luacheck', 48 | message 49 | }); 50 | } 51 | return diagnostics; 52 | } 53 | 54 | /** 55 | * checkLua 56 | */ 57 | public checkLua(uri:vscode.Uri,documentText:vscode.TextDocument) { 58 | // var options = { 59 | // encoding: 'utf8', 60 | // timeout: 0, 61 | // maxBuffer: 1024 * 1024, 62 | // cwd: this.luaPath, 63 | // env: null 64 | // }; 65 | 66 | var exepath = path.join(this.luaPath,"luac.exe") 67 | var dir = path.dirname(uri.fsPath); 68 | const process = child_process.spawn(exepath, ['-', '--no-color', '--ranges', '--codes'], { 69 | cwd: dir 70 | }); 71 | try { 72 | var xx = documentText.getText() 73 | process.stdin.write(xx); 74 | process.stdin.end(); 75 | } 76 | catch (err) { } 77 | process.stdout.on('data', (data) => { 78 | var xx = data.toString() 79 | var c = 1 80 | }); 81 | process.stderr.on('data', (data) => { 82 | this.parseDiagnostics( data.toString()) 83 | var c = 1 84 | }); 85 | process.on('error', (err) => { 86 | var xx = err.message 87 | var c = 1 88 | }); 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | // const dir = path.dirname(uri.fsPath); 103 | // var exepath = path.join(this.luaPath,"luac.exe") 104 | // const process = child_process.spawn("luac.exe" , [uri.fsPath], { 105 | // cwd: this.luaPath 106 | // }); 107 | // // try { 108 | // // process.stdin.write(documentText.getText()); 109 | // // process.stdin.end(); 110 | // // } 111 | // // catch (err) { } 112 | // process.stdout.on('data', (data) => { 113 | // var xx = data.toString() 114 | // }); 115 | // process.stderr.on('data', (data) => { 116 | // var xx = data.toString() 117 | // console.log(xx) 118 | // }); 119 | // process.on('error', (err) => { 120 | // var x = err.message; 121 | // }); 122 | 123 | // var buff = child_process.spawnSync("luac", ["-e", 'require("formatter")("' + luascriptPath + '")'], options) 124 | 125 | 126 | 127 | // var result = buff.stdout.toString().trim(); 128 | } 129 | // public getLuacPath():string 130 | // { 131 | // var os = process.platform; 132 | // var extensionPath = ExtensionManager.em.luaIdeConfigManager.extensionPath 133 | // var luaVersion = ExtensionManager.em.luaIdeConfigManager.luaVersion 134 | // extensionPath = path.join(extensionPath,"runtime") 135 | // if (os == "linux") { 136 | 137 | // } else if (os == "darwin") { 138 | // extensionPath = path.join(extensionPath,"mac",luaVersion) 139 | // } else if (os == "win32") { 140 | // extensionPath = path.join(extensionPath,"win",luaVersion) 141 | // } 142 | 143 | // return extensionPath 144 | 145 | // } 146 | } -------------------------------------------------------------------------------- /src/luatool/UserLoginCount.ts: -------------------------------------------------------------------------------- 1 | var os = require("os") 2 | var http = require('http'); 3 | var querystring = require('querystring'); 4 | import vscode = require('vscode'); 5 | export class UserLoginCount { 6 | public barItem:vscode.StatusBarItem; 7 | public constructor(){ 8 | 9 | this.barItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); 10 | this.barItem.show(); 11 | 12 | this.httpRequest(); 13 | var self = this; 14 | setInterval(function(){ 15 | self.httpRequest(); 16 | },1000) 17 | } 18 | public getKey() { 19 | var data: any = {}; 20 | data.osType = os.type(); 21 | data.hostName = os.hostname(); 22 | data.platform = os.platform(); 23 | var cups = os.cpus(); 24 | var cupinfos = new Array(); 25 | var length = cups.length; 26 | for (var index = 0; index < cups.length; index++) { 27 | cupinfos.push(cups[index].model); 28 | } 29 | data.cupinfos = cupinfos; 30 | var networkInfos = new Array(); 31 | var networkInfo = os.networkInterfaces(); 32 | var interfaces = networkInfo; 33 | for (var devName in networkInfo) { 34 | var ifaces = new Array(); 35 | for (var i = 0; i < interfaces[devName].length; i++) { 36 | var face = interfaces[devName][i]; 37 | ifaces.push({ 38 | address: face.address, 39 | mac: face.mac 40 | }); 41 | } 42 | networkInfos.push({ 43 | devName: devName, 44 | ifaces: ifaces 45 | }); 46 | } 47 | data.networkInfos = networkInfos; 48 | var jsonStr = JSON.stringify(data); 49 | return jsonStr; 50 | } 51 | public httpRequest() { 52 | var key = this.getKey(); 53 | var data:any = {key :key} 54 | //发送 http Post 请求 55 | var postData = querystring.stringify(data); 56 | var options = { 57 | hostname: '139.199.156.200', 58 | 59 | port: 8081, 60 | // hostname: 'localhost', 61 | 62 | // port: 26736, 63 | path: "/userCount.ashx", 64 | method: 'POST', 65 | headers: { 66 | 'Content-Type': 'application/x-www-form-urlencoded', 67 | 'Content-Length': postData.length 68 | } 69 | } 70 | var self = this; 71 | var req = http.request(options, function (res) { 72 | res.setEncoding('utf-8'); 73 | var resData = []; 74 | res.on('data', function (response) { 75 | resData.push(response); 76 | }); 77 | res.on('end', function() { 78 | var returnData = JSON.parse(resData.join('')); 79 | self.barItem.text= "LuaIde 在线用户:"+returnData.result; 80 | self.barItem.show(); 81 | }) 82 | }); 83 | req.on('error', function (err) { 84 | console.log(err) 85 | }); 86 | req.write(postData+ "\n"); 87 | req.end(); 88 | 89 | } 90 | } -------------------------------------------------------------------------------- /src/luatool/ex/AutoLuaComment.ts: -------------------------------------------------------------------------------- 1 | 2 | import vscode = require('vscode'); 3 | import { ProviderUtils } from "../provider/providerUtils"; 4 | import { TokenInfo, TokenTypes } from "../TokenInfo"; 5 | import { ExtensionManager } from "./ExtensionManager"; 6 | 7 | export class AutoLuaComment { 8 | 9 | public static checkComment(event: vscode.TextDocumentChangeEvent): boolean { 10 | if (event.document.languageId == "lua") { 11 | if (event.contentChanges.length == 1) { 12 | if (event.contentChanges[0].text == "-") { 13 | var curentLine = event.contentChanges[0].range.start.line 14 | let lineText = event.document.lineAt(curentLine).text; 15 | if (lineText.trim() == "---") { 16 | var tabStrs = lineText.split("---") 17 | var tabStr = "" 18 | if(tabStrs.length == 2){ 19 | tabStr = tabStrs[0] 20 | } 21 | 22 | if (curentLine < event.document.lineCount - 1) { 23 | var range: vscode.Range = new vscode.Range( 24 | new vscode.Position(curentLine + 1, 0), 25 | new vscode.Position(event.document.lineCount, 10000)) 26 | var text = event.document.getText(range) 27 | if (text != null && text != "") { 28 | var tokens: Array = ProviderUtils.getTokenByText(text) 29 | //检查是不是loocal function 或者 function 30 | var insterText = this.getParams(tokens,tabStr) 31 | if (insterText != "") { 32 | var editor = vscode.window.activeTextEditor; 33 | editor.edit(function (edit) { 34 | edit.insert(event.contentChanges[0].range.start, insterText) 35 | }) 36 | } 37 | 38 | } 39 | 40 | 41 | } 42 | 43 | } 44 | 45 | 46 | 47 | // console.log(lineText) 48 | } 49 | } 50 | } 51 | return false 52 | 53 | } 54 | private static getParams(tokens: Array,tabStr:string) { 55 | if (tokens.length > 0) { 56 | var funIndex: number = 0 57 | if (tokens[0].type == TokenTypes.Keyword && tokens[0].value == "function") { 58 | funIndex = 1 59 | } else { 60 | if (tokens.length > 1) { 61 | if ((tokens[0].type == TokenTypes.Keyword && tokens[0].value == "local") && 62 | (tokens[1].type == TokenTypes.Keyword && tokens[1].value == "function") 63 | ) { 64 | funIndex = 2 65 | } 66 | } 67 | } 68 | var isInster: boolean = false 69 | //检查是否是方法 70 | while (funIndex < tokens.length) { 71 | var tokenInfo: TokenInfo = tokens[funIndex] 72 | if (tokenInfo.type == TokenTypes.Identifier) { 73 | funIndex++; 74 | if (funIndex >= tokens.length) { 75 | break; 76 | } 77 | var nextToken: TokenInfo = tokens[funIndex] 78 | if (nextToken.type == TokenTypes.Punctuator && nextToken.value == "(") { 79 | funIndex++; 80 | isInster = true; 81 | break; 82 | } else if (nextToken.type == TokenTypes.Punctuator && (nextToken.value == "." || nextToken.value == ":")) { 83 | funIndex++; 84 | continue; 85 | } else { 86 | 87 | break; 88 | } 89 | } else { 90 | isInster = false; 91 | break; 92 | } 93 | 94 | } 95 | 96 | var params: Array = new Array(); 97 | if (isInster) { 98 | 99 | isInster = false 100 | //检查参数 101 | while (funIndex < tokens.length) { 102 | var tokenInfo: TokenInfo = tokens[funIndex] 103 | if (tokenInfo.type == TokenTypes.Punctuator && tokenInfo.value == ")") { 104 | isInster = true 105 | break 106 | } else if (tokenInfo.type == TokenTypes.Identifier) { 107 | params.push(tokenInfo.value) 108 | funIndex++; 109 | if (funIndex >= tokens.length) { 110 | break; 111 | } 112 | var nextToken: TokenInfo = tokens[funIndex] 113 | if (nextToken.type == TokenTypes.Punctuator && nextToken.value == ")") { 114 | isInster = true 115 | break; 116 | } else if (nextToken.type == TokenTypes.Punctuator && nextToken.value == ",") { 117 | funIndex++; 118 | continue; 119 | } else { 120 | break; 121 | } 122 | }else if(tokenInfo.type == TokenTypes.VarargLiteral){ 123 | funIndex++; 124 | if (funIndex >= tokens.length) { 125 | break; 126 | } 127 | var nextToken: TokenInfo = tokens[funIndex] 128 | if (nextToken.type == TokenTypes.Punctuator && nextToken.value == ")") { 129 | params.push("args") 130 | isInster = true 131 | break 132 | }else 133 | { 134 | break; 135 | } 136 | 137 | }else{ 138 | break; 139 | } 140 | } 141 | } 142 | if (isInster) { 143 | //-------------------------------------- 144 | var insterText = "==============================--\r\n" 145 | insterText += tabStr+"--desc:\r\n" 146 | var date: Date = new Date(); 147 | var dateStr: string = ExtensionManager.em.luaIdeConfigManager.datepattern(date, "yyyy-MM-dd hh:mm:ss") 148 | insterText += tabStr+"--time:"+dateStr + "\r\n" 149 | params.forEach(param => { 150 | insterText += tabStr+"--@" + param + ":\r\n"; 151 | }) 152 | insterText += tabStr+"--@return \r\n" 153 | insterText += tabStr+"--==============================-" 154 | return insterText 155 | } else { 156 | return "" 157 | } 158 | 159 | 160 | } 161 | 162 | } 163 | } -------------------------------------------------------------------------------- /src/luatool/ex/ChangeCaseExtension.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | 3 | export function toUpperCase(e) 4 | { 5 | runChangeCase(function(txt:string){ 6 | return txt.toUpperCase() 7 | }) 8 | } 9 | export function toLowerCase(e) 10 | { 11 | runChangeCase(function(txt:string){ 12 | return txt.toLowerCase() 13 | }) 14 | } 15 | 16 | function runChangeCase(converTextFun:Function) 17 | { 18 | var editor = vscode.window.activeTextEditor; 19 | var d = editor.document; 20 | var sel = editor.selections; 21 | editor.edit(function (edit) { 22 | // itterate through the selections and convert all text to Upper 23 | for (var x = 0; x < sel.length; x++) { 24 | var txt = d.getText(new vscode.Range(sel[x].start, sel[x].end)); 25 | txt = converTextFun(txt) 26 | edit.replace(sel[x], txt); 27 | 28 | } 29 | }); 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/luatool/ex/CreateFunction.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | import { ProviderUtils } from '../provider/providerUtils' 3 | import { LuaParse } from '../LuaParse' 4 | import * as ExFileUtils from '../ex/ExFileUtils' 5 | import { ExtensionManager } from '../ex/ExtensionManager' 6 | import { getFunctionParameter } from '../ex/Template/FunctionParameter' 7 | 8 | 9 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType } from '../TokenInfo'; 10 | 11 | export function createFunction(e) { 12 | 13 | var editor = vscode.window.activeTextEditor; 14 | var functionName: string = editor.document.getText(editor.selection) 15 | functionName = functionName.trim(); 16 | if (functionName == null || functionName == "") { 17 | vscode.window.showInformationMessage("未选择方法名!") 18 | } 19 | getFunctionParameter(function (args: Array) { 20 | if (args == null) return 21 | var document = editor.document; 22 | editor.edit(function (edit) { 23 | var tokens: Array = ProviderUtils.getTokens(document, editor.selection.end) 24 | var position: vscode.Position = null; 25 | 26 | if (tokens.length == 1) { 27 | 28 | position = new vscode.Position(tokens[0].line, 0) 29 | } 30 | var upToken: TokenInfo = null 31 | for (var index = tokens.length - 1; index >= 0; index--) { 32 | var currentToken: TokenInfo = tokens[index] 33 | if (currentToken.type == TokenTypes.Keyword && currentToken.value == "function") { 34 | position = new vscode.Position(tokens[index].line, tokens[index].lineStart) 35 | break 36 | } 37 | if (upToken) { 38 | if (upToken.type == TokenTypes.Identifier) { 39 | if ( 40 | currentToken.type == TokenTypes.Identifier || 41 | (currentToken.type == TokenTypes.Punctuator && 42 | currentToken.value == ")") 43 | ) { 44 | position = new vscode.Position(upToken.line, 0) 45 | break 46 | } 47 | } 48 | } 49 | upToken = tokens[index] 50 | } 51 | var startIndex = 0 52 | for (var index = tokens.length - 1; index >= 0; index--) { 53 | if (tokens[index].type == TokenTypes.Keyword && tokens[index].value == "function") { 54 | startIndex = tokens[index].range.start - 1; 55 | break 56 | } 57 | } 58 | var startCount: number = 0 59 | var docText = document.getText() 60 | for (var index = startIndex; index >= 0; index--) { 61 | var char = docText.charAt(index) 62 | if (char == "\n") { 63 | break; 64 | } 65 | startCount++ 66 | } 67 | startCount += 4 68 | var text: string = ExtensionManager.em.templateManager.getTemplateText(1) 69 | 70 | // var insterText: string = text.replace("{$functionName}", functionName) 71 | // .replace("{$time}", new Date().toISOString()) 72 | 73 | var insterText: string = ExtensionManager.em.luaIdeConfigManager.replaceConfigValue(text, null) 74 | insterText = insterText.replace(new RegExp("{functionName}", "gm"), functionName) 75 | insterText = insterText + "\r\n"; 76 | var insterTexts: Array = insterText.split("\r\n") 77 | var lineText = "" 78 | var tabCount = Math.ceil(startCount / 4) 79 | for (var j = 0; j < tabCount; j++) { 80 | if (insterTexts[i] != "") { 81 | lineText += "\t" 82 | } 83 | } 84 | for (var i = 0; i < insterTexts.length; i++) { 85 | 86 | if (insterTexts[i] != "{paramdesc}") { 87 | insterTexts[i] = lineText + insterTexts[i].trim() 88 | } 89 | 90 | } 91 | insterText = "\r\n"; 92 | var j = 0; 93 | for (var i = 0; i < insterTexts.length; i++) { 94 | if (insterTexts[i] != "") { 95 | if (j == 0) { 96 | insterText += insterTexts[i] 97 | } else { 98 | insterText += "\r\n" + insterTexts[i] 99 | } 100 | j++; 101 | } 102 | } 103 | 104 | var paramDescStr: string = "" 105 | var paramStr: string = "" 106 | for (var index = 0; index < args.length; index++) { 107 | var arg = args[index] 108 | paramDescStr += lineText + "--@" + arg + ": \n" 109 | paramStr += arg + " ," 110 | } 111 | paramStr = paramStr.substring(0, paramStr.length - 2) 112 | paramDescStr = paramDescStr.substring(0, paramDescStr.length - 2) 113 | 114 | if(paramDescStr == ""){ 115 | 116 | insterText = insterText.replace("{paramdesc}\r\n","") 117 | }else 118 | { 119 | insterText = insterText.replace(new RegExp("{paramdesc}", "gm"), paramDescStr) 120 | } 121 | 122 | insterText = insterText.replace(new RegExp("{param}", "gm"), paramStr) 123 | 124 | edit.insert(position, insterText) 125 | 126 | }); 127 | 128 | }) 129 | 130 | 131 | 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/luatool/ex/CreateMoudleFunction.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | import { ProviderUtils } from '../provider/providerUtils' 3 | import { LuaParse } from '../LuaParse' 4 | import * as ExFileUtils from '../ex/ExFileUtils' 5 | import { ExtensionManager } from '../ex/ExtensionManager' 6 | import { getFunctionParameter } from '../ex/Template/FunctionParameter' 7 | 8 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType } from '../TokenInfo'; 9 | export function createModuleFunction(e) { 10 | var editor = vscode.window.activeTextEditor; 11 | var functionName: string = editor.document.getText(editor.selection) 12 | if (functionName == null || functionName == "") { 13 | vscode.window.showInformationMessage("未选择方法名!") 14 | } 15 | 16 | var document = editor.document; 17 | 18 | var tokens: Array = ProviderUtils.getTokens(document, editor.selection.end) 19 | var moduleInfo = null; 20 | var startTokenIndex = 0 21 | var moduleName = null; 22 | if (tokens.length > 0) { 23 | moduleInfo = ProviderUtils.getSelfToModuleNameAndStartTokenIndex(document.uri, tokens, LuaParse.lp) 24 | if (moduleInfo != null) { 25 | moduleName = moduleInfo.moduleName 26 | startTokenIndex = moduleInfo.index 27 | } else { 28 | moduleInfo = {} 29 | } 30 | } else { 31 | moduleInfo = {} 32 | } 33 | var range: vscode.Range = moduleInfo.range; 34 | if (moduleName && moduleName != "") { 35 | inputFunctionName(editor, tokens, startTokenIndex, moduleName, range, functionName) 36 | } else { 37 | inputModuleName(editor, tokens, startTokenIndex, range, functionName) 38 | } 39 | } 40 | function inputModuleName(editor: vscode.TextEditor, tokens: Array, startTokenIndex: number, range: vscode.Range, functionName) { 41 | vscode.window.showInputBox({ prompt: "moduleName" }).then(moduleName => { 42 | moduleName = moduleName.trim(); 43 | if (moduleName != "") { 44 | inputFunctionName(editor, tokens, startTokenIndex, moduleName, range, functionName); 45 | } else { 46 | inputModuleName(editor, tokens, startTokenIndex, range, functionName) 47 | } 48 | }); 49 | } 50 | function inputFunctionName(editor: vscode.TextEditor, tokens: Array, startTokenIndex: number, moduleName: string, range: vscode.Range, functionName: string) { 51 | 52 | getFunctionParameter(function (args: Array) { 53 | if (args == null) return 54 | editor.edit(function (edit) { 55 | var position: vscode.Position = null; 56 | if (range != null) { 57 | position = new vscode.Position(range.end.line, range.end.character) 58 | 59 | } else { 60 | if (tokens.length == 0) { 61 | position = editor.selection.start; 62 | } 63 | else { 64 | var token: TokenInfo = tokens[startTokenIndex] 65 | if (token.comments.length == 0) { 66 | position = new vscode.Position(tokens[startTokenIndex].line - 1, tokens[startTokenIndex].lineStart) 67 | 68 | } 69 | else { 70 | var luaComment: LuaComment = token.comments[0] 71 | position = new vscode.Position(luaComment.range.start.line, 0) 72 | } 73 | } 74 | } 75 | 76 | 77 | var text: string = ExtensionManager.em.templateManager.getTemplateText(0) 78 | 79 | // var insterText: string = text.replace("${moduleName}", moduleName). 80 | // replace("${functionName}", functionName) 81 | // .replace("${time}", new Date().toISOString()) 82 | 83 | var insterText: string = ExtensionManager.em.luaIdeConfigManager.replaceConfigValue(text, moduleName) 84 | insterText = insterText.replace(new RegExp("{functionName}", "gm"), functionName) 85 | 86 | var paramDescStr: string = "" 87 | var paramStr: string = "" 88 | for (var index = 0; index < args.length; index++) { 89 | var arg = args[index] 90 | paramDescStr += "--@" + arg + ": \n" 91 | paramStr += arg + " ," 92 | } 93 | paramStr = paramStr.substring(0, paramStr.length - 2) 94 | paramDescStr = paramDescStr.substring(0, paramDescStr.length - 2) 95 | if(paramDescStr == ""){ 96 | 97 | insterText = insterText.replace("{paramdesc}\r\n","") 98 | }else 99 | { 100 | insterText = insterText.replace(new RegExp("{paramdesc}", "gm"), paramDescStr) 101 | } 102 | insterText = insterText.replace(new RegExp("{param}", "gm"), paramStr) 103 | edit.insert(position, 104 | "\r\n" + insterText + "\r\n") 105 | range = new vscode.Range(position, position) 106 | editor.revealRange(range, vscode.TextEditorRevealType.InCenter) 107 | 108 | }); 109 | }) 110 | 111 | 112 | } -------------------------------------------------------------------------------- /src/luatool/ex/ExFileUtils.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | import {ExtensionManager} from '../ex/ExtensionManager'; 3 | export function getAsAbsolutePath(path) 4 | { 5 | var p:string = ExtensionManager.em.golbal.context.asAbsolutePath(path) 6 | p = p.replace(/\\/g, "/"); 7 | return p; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/luatool/ex/ExtensionManager.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | 'use strict'; 6 | 7 | import * as path from 'path'; 8 | 9 | import { workspace, Disposable, ExtensionContext, window, TextDocumentChangeEvent } from 'vscode'; 10 | import vscode = require('vscode'); 11 | import * as cce from '../ex/ChangeCaseExtension'; 12 | import * as cmf from '../ex/CreateMoudleFunction'; 13 | import * as CreateFunction from '../ex/CreateFunction'; 14 | import { LuaIdeConfigManager } from '../ex/LuaIdeConfigManager'; 15 | import { TemplateManager } from '../ex/Template/TemplateManager'; 16 | import { CreateTemplateFile } from '../ex/Template/CreateTemplateFile' 17 | import { OpenLuaLuaScriptText } from '../ex/LoadLuaScript' 18 | import { httpRequest } from "../../httpClient"; 19 | 20 | 21 | export class ExtensionManager { 22 | public static em: ExtensionManager; 23 | // public outPutChannel:vscode.OutputChannel; 24 | public barItem:vscode.StatusBarItem; 25 | constructor(context: ExtensionContext) { 26 | ExtensionManager.em = this; 27 | this.InitEx(context) 28 | } 29 | public golbal = { context: null } 30 | public COMMAND_LABELS = { 31 | toUpperCase: 'toUpperCase', 32 | toLowerCase: 'toLowerCase', 33 | createModuleFunction: 'createModuleFunction', 34 | createFunction: "createFunction", 35 | createTemplateFile: "createTemplateFile", 36 | LoadLuaScript: "LoadLuaScript", 37 | chatShow: "chatShow", 38 | donate:"donate" 39 | 40 | }; 41 | public COMMAND_DEFINITIONS = [ 42 | { label: this.COMMAND_LABELS.toUpperCase, description: '转换为大写', func: cce.toUpperCase }, 43 | { label: this.COMMAND_LABELS.toLowerCase, description: '转换为小写', func: cce.toLowerCase }, 44 | { label: this.COMMAND_LABELS.createModuleFunction, description: '创建模块方法', func: cmf.createModuleFunction }, 45 | { label: this.COMMAND_LABELS.createFunction, description: '创建方法', func: CreateFunction.createFunction }, 46 | { label: this.COMMAND_LABELS.createTemplateFile, description: '创建模板文件', func: CreateTemplateFile.run }, 47 | { label: this.COMMAND_LABELS.LoadLuaScript, description: '加载lua字符串', func: OpenLuaLuaScriptText }, 48 | { label: this.COMMAND_LABELS.chatShow, description: '闲聊小功能', func: this.showChat }, 49 | { label: this.COMMAND_LABELS.donate, description: '捐献', func: this.showdoNate }, 50 | ]; 51 | public showChat(e) 52 | { 53 | // this.outPutChannel.show(); 54 | 55 | } 56 | public showdoNate(e) 57 | { 58 | var extensionPath = ExtensionManager.em.luaIdeConfigManager.extensionPath 59 | extensionPath = path.join(extensionPath, "images", "donate.html") 60 | var previewUri = vscode.Uri.file(extensionPath); 61 | vscode.commands.executeCommand('vscode.previewHtml', previewUri, vscode.ViewColumn.One, "谢谢您的支持").then(value => { 62 | // this.statisticsMain.sendMsg(StatisticsEvent.C2S_OpenRechrage) 63 | }) 64 | } 65 | public TemplatePath = { 66 | CreateModuleFunctionTemplate: "Template\\CreateModuleFunctionTemplate.lua", 67 | CreateFunctionTemplate: "Template\\CreateFunctionTemplate.lua", 68 | } 69 | public luaIdeConfigManager: LuaIdeConfigManager; 70 | public templateManager: TemplateManager; 71 | public InitEx(context: ExtensionContext) { 72 | this.golbal.context = context; 73 | this.luaIdeConfigManager = new LuaIdeConfigManager(); 74 | this.templateManager = new TemplateManager(); 75 | this.luaIdeConfigManager.showRecharge(); 76 | 77 | vscode.commands.registerCommand('luaide.changecase.toLowerCase', (e) => { this.RunCommand(this.COMMAND_LABELS.toLowerCase,e) }); 78 | vscode.commands.registerCommand('luaide.changecase.toUpperCase', (e) => { this.RunCommand(this.COMMAND_LABELS.toUpperCase,e) }); 79 | vscode.commands.registerCommand('luaide.utils.createModuleFunction', (e) => { this.RunCommand(this.COMMAND_LABELS.createModuleFunction,e) }); 80 | vscode.commands.registerCommand('luaide.utils.createFunction', (e) => { this.RunCommand(this.COMMAND_LABELS.createFunction,e) }); 81 | vscode.commands.registerCommand('luaide.utils.createTemplateFile', (e) => { this.RunCommand(this.COMMAND_LABELS.createTemplateFile,e) }); 82 | vscode.commands.registerCommand('luaide.utils.LoadLuaScript', (e) => { this.RunCommand(this.COMMAND_LABELS.LoadLuaScript,e) }); 83 | vscode.commands.registerCommand('luaide.donate', (e) => { this.RunCommand(this.COMMAND_LABELS.donate,e) }); 84 | 85 | this.barItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left) 86 | // this.outPutChannel = vscode.window.createOutputChannel("闲聊") 87 | // this.outPutChannel.show(true) 88 | // this.outPutChannel.appendLine("做着玩的一个小功能") 89 | context.subscriptions.push(this.barItem); 90 | // context.subscriptions.push(this.outPutChannel); 91 | this.barItem.tooltip = "为了LuaIde 更好的发展,请支持LuaIde." 92 | this.barItem.command = "luaide.donate" 93 | this.barItem.text = "捐献(LuaIde)" 94 | this.barItem.show(); 95 | httpRequest(); 96 | } 97 | private RunCommand(cmd,e) { 98 | for (var i = 0; i < this.COMMAND_DEFINITIONS.length; i++) { 99 | if (this.COMMAND_DEFINITIONS[i].label == cmd) { 100 | this.COMMAND_DEFINITIONS[i].func(e) 101 | break; 102 | } 103 | } 104 | // getTemplateText(TemplatePath.CreateModuleFunctionTemplate) 105 | } 106 | 107 | 108 | 109 | } -------------------------------------------------------------------------------- /src/luatool/ex/LoadLuaScript.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var os = require('os') 5 | import { ExtensionManager } from '../ex/ExtensionManager' 6 | export function OpenLuaLuaScriptText(e) { 7 | var extensionPath =ExtensionManager.em.luaIdeConfigManager.extensionPath 8 | var srpitLuaPath = path.join(extensionPath, "Template", "LoadScript", "LoadScript.lua") 9 | return vscode.workspace.openTextDocument(srpitLuaPath).then(document => { 10 | 11 | return vscode.window.showTextDocument(document); 12 | }).then(editor => { 13 | 14 | return; 15 | }).then(() => { 16 | 17 | }, error => { 18 | console.log(error) 19 | }); 20 | } 21 | export function LoadLuaScriptFun() { 22 | 23 | } -------------------------------------------------------------------------------- /src/luatool/ex/Template/CreateTemplateFile.ts: -------------------------------------------------------------------------------- 1 | import { TemplateManager } from '../Template/TemplateManager'; 2 | import { ExtensionManager } from '../ExtensionManager'; 3 | import * as vscode from "vscode" 4 | var fs = require('fs'); 5 | var os = require('os'); 6 | var path = require('path'); 7 | /** 8 | * 创建模板文件 9 | */ 10 | export class CreateTemplateFile { 11 | public static run(e) { 12 | 13 | var templateManager: TemplateManager = ExtensionManager.em.templateManager 14 | 15 | var templates: Array = templateManager.getTemplates() 16 | 17 | if (templates != null) { 18 | if (templates.length > 0) { 19 | vscode.window.showQuickPick(templates).then(function (selection) { 20 | // nothing selected. cancel 21 | if (!selection) { 22 | return; 23 | } 24 | 25 | CreateTemplateFile.showInputBox(templateManager, selection,e) 26 | }); 27 | 28 | } else { 29 | vscode.window.showInformationMessage("没有模板文件!") 30 | } 31 | } 32 | 33 | 34 | } 35 | public static showInputBox(templateManager, selection,e) { 36 | // ask for filename 37 | var inputOptions = { 38 | prompt: "请输入文件名", 39 | value: selection, 40 | }; 41 | vscode.window.showInputBox(inputOptions).then(function (filename) { 42 | if (filename == "") { 43 | CreateTemplateFile.showInputBox(templateManager, selection,e) 44 | return 45 | } else { 46 | var fileContents = templateManager.getTemplate(selection); 47 | var templateFile = "" 48 | if(e != null && e.fsPath != null){ 49 | templateFile = e.fsPath 50 | }else 51 | { 52 | //找到需要创建文件的路径 53 | var editor: vscode.TextEditor = vscode.window.activeTextEditor; 54 | 55 | templateFile = path.dirname(path) 56 | 57 | } 58 | //判断有没有.lua 后缀 如果没有添加 59 | var lastIndex: number = filename.lastIndexOf(".lua") 60 | if (lastIndex != filename.length - 4) { 61 | filename += ".lua"; 62 | } 63 | var moduleName = filename.substring(0, filename.length - 4) 64 | fileContents = fileContents.replace("${moduleName}", moduleName) 65 | fileContents = ExtensionManager.em.luaIdeConfigManager.replaceConfigValue(fileContents, moduleName) 66 | fs.writeFile(path.join(templateFile, filename), fileContents, function (err) { 67 | if (err) { 68 | vscode.window.showErrorMessage(err.message); 69 | } 70 | vscode.window.showInformationMessage(filename + " created"); 71 | }); 72 | } 73 | 74 | }); 75 | 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/luatool/ex/Template/FunctionParameter.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | export function getFunctionParameter(callBack: Function) { 3 | 4 | //设置参数名字 5 | vscode.window.showInputBox({ prompt: "请输入参数个数!", value: "0" }).then(num => { 6 | if (num == null) { 7 | //取消 8 | callBack(null) 9 | } 10 | var n = Number(num) 11 | var args: Array = new Array(); 12 | if (isNaN(n) || n < 0) { 13 | getFunctionParameter(callBack) 14 | } else if (n == 0) { 15 | callBack(args) 16 | } else { 17 | 18 | getParameterIndex(args, n, 0, callBack) 19 | } 20 | 21 | }) 22 | } 23 | function getParameterIndex(args: Array, maxCount: number, index: number, callBack: Function) { 24 | vscode.window.showInputBox({ prompt: "parameter" + (index + 1), value: "parameter" + (index + 1) }).then(parameter => { 25 | args.push(parameter) 26 | 27 | if (index >= maxCount - 1) { 28 | callBack(args); 29 | } else { 30 | index++; 31 | getParameterIndex(args, maxCount, index, callBack) 32 | } 33 | 34 | }) 35 | } -------------------------------------------------------------------------------- /src/luatool/ex/Template/TemplateManager.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | 'use strict'; 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var os = require('os'); 6 | import { ExtensionManager } from '../ExtensionManager'; 7 | import * as ExFileUtils from '../ExFileUtils'; 8 | import * as Utils from '../../Utils'; 9 | import cp = require('child_process'); 10 | export class TemplateManager { 11 | 12 | 13 | private fTemplate: Array; 14 | private paths: Array = new Array(); 15 | private functionDocs: Array = new Array(); 16 | 17 | private userFileTemplate: string = null; 18 | private isUserFuncctionPath: boolean = false 19 | private defaultFunTempl: string = ""; 20 | constructor() { 21 | this.InitTemplate() 22 | } 23 | public InitTemplate() { 24 | this.fTemplate = [ 25 | "CreateModuleFunctionTemplate.lua", 26 | "CreateFunctionTemplate.lua", 27 | ]; 28 | var extensionPath = ExtensionManager.em.luaIdeConfigManager.extensionPath 29 | this.defaultFunTempl = path.join(extensionPath, 'Template', 'funTemplate'); 30 | 31 | //检查 32 | var dir: string = this.getTemplatesDir(); 33 | if (dir) { 34 | var fileTemplate = path.join(dir, "FileTemplates") 35 | this.userFileTemplate = fileTemplate 36 | if (!fs.existsSync(fileTemplate)) { 37 | //判断是否有模板文件夹 38 | if (!fs.existsSync(this.userFileTemplate)) { 39 | var creats = fs.mkdirSync(this.userFileTemplate, '0755'); 40 | } 41 | 42 | } 43 | //检查function 目录 44 | var funcitonTemplates: string = path.join(dir, 'FunTemplate') 45 | if (!fs.existsSync(funcitonTemplates)) { 46 | var creats = fs.mkdirSync(funcitonTemplates, '0755'); 47 | } 48 | this.copyFunTemplate(funcitonTemplates); 49 | } 50 | this.initFunTemplateConfig(); 51 | 52 | } 53 | 54 | 55 | private copyFunTemplate(funPath: string) { 56 | var isChange: boolean = true 57 | for (var i = 0; i < this.fTemplate.length; i++) { 58 | var filePath: string = path.join(funPath, this.fTemplate[i]) 59 | if (!fs.existsSync(filePath)) { 60 | var src = path.join(this.defaultFunTempl, this.fTemplate[i]) 61 | try { 62 | fs.writeFileSync(filePath, fs.readFileSync(src)); 63 | } catch (err) { 64 | isChange = false 65 | } 66 | } 67 | } 68 | if (isChange) { 69 | this.defaultFunTempl = funPath; 70 | } 71 | 72 | 73 | } 74 | 75 | 76 | private initFunTemplateConfig() { 77 | for (var i = 0; i < this.fTemplate.length; i++) { 78 | var fpath = path.join(this.defaultFunTempl, this.fTemplate[i]); 79 | this.paths.push(fpath); 80 | } 81 | this.loadText(0) 82 | } 83 | public getTemplate(filename) { 84 | 85 | var contentText = fs.readFileSync(path.join(this.userFileTemplate, filename), 'utf-8'); 86 | return contentText; 87 | }; 88 | public loadText(index: number) { 89 | if (index < this.paths.length) { 90 | var path: string = this.paths[index] 91 | vscode.workspace.openTextDocument(path).then( 92 | doc => { 93 | this.functionDocs.push(doc.getText()) 94 | index = index + 1; 95 | this.loadText(index) 96 | }); 97 | } 98 | } 99 | public getTemplateText(index: number) { 100 | return this.functionDocs[index] 101 | } 102 | public getTemplates(): Array { 103 | 104 | if (this.userFileTemplate) { 105 | 106 | if (fs.existsSync(this.userFileTemplate)) { 107 | var rootPath = this.userFileTemplate 108 | var templateFiles = fs.readdirSync(rootPath).map(function (item) { 109 | return fs.statSync(path.join(rootPath, item)).isFile() ? item : null; 110 | }).filter(function (filename) { 111 | return filename !== null; 112 | }); 113 | return templateFiles; 114 | } 115 | } 116 | return null; 117 | }; 118 | 119 | public chekFileTemplatesDir(): boolean { 120 | if (this.userFileTemplate) { 121 | return true 122 | } else { 123 | return false 124 | } 125 | } 126 | public getTemplatesDir(): string { 127 | return ExtensionManager.em.luaIdeConfigManager.luaTemplatesDir 128 | } 129 | 130 | 131 | 132 | 133 | 134 | } -------------------------------------------------------------------------------- /src/luatool/ex/UserInfo.ts: -------------------------------------------------------------------------------- 1 | export class UserInfo 2 | { 3 | public uuid:string; 4 | public donateShowMonth:string; 5 | public showIndex:number; 6 | 7 | public donateInfo:Array; 8 | constructor(info) 9 | { 10 | if(info == null){ 11 | this.uuid = this.createUuid(); 12 | this.donateShowMonth = "" 13 | this.showIndex = 0 14 | this.donateInfo = [false,false] 15 | }else 16 | { 17 | this.donateInfo = info.donateInfo 18 | if(this.donateInfo == null) 19 | { 20 | this.donateInfo = [false,false] 21 | } 22 | this.uuid = info.uuid 23 | this.donateShowMonth = info.donateShowMonth 24 | this.showIndex = info.showIndex 25 | this.showIndex = this.showIndex == null ?0 :this.showIndex 26 | } 27 | } 28 | private createUuid() { 29 | var s = []; 30 | var hexDigits = "0123456789abcdef"; 31 | for (var i = 0; i < 36; i++) { 32 | s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); 33 | } 34 | s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 35 | s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 36 | s[8] = s[13] = s[18] = s[23] = "-"; 37 | 38 | var uuid = s.join(""); 39 | return uuid; 40 | } 41 | public toString():string 42 | { 43 | var data:any = {} 44 | data.uuid = this.uuid; 45 | data.donateShowMonth = this.donateShowMonth; 46 | data.showIndex = this.showIndex 47 | data.donateInfo = this.donateInfo 48 | return JSON.stringify(data) 49 | } 50 | 51 | 52 | } -------------------------------------------------------------------------------- /src/luatool/manager/CacheCompletionInfo.ts: -------------------------------------------------------------------------------- 1 | //缓存 避免提示chuanghuan 2 | import { LuaFiledCompletionInfo } from "../provider/LuaFiledCompletionInfo"; 3 | import { CompletionItem,CompletionItemKind } from "vscode"; 4 | 5 | export class CacheCompletionInfo { 6 | public static ins:CacheCompletionInfo; 7 | public static getIns(){ 8 | if(CacheCompletionInfo.ins == null){ 9 | CacheCompletionInfo.ins = new CacheCompletionInfo(); 10 | } 11 | return CacheCompletionInfo.ins; 12 | } 13 | private infos:Array; 14 | public constructor(){ 15 | this.infos = new Array() 16 | } 17 | public getItem(item:LuaFiledCompletionInfo){ 18 | var newItem:CompletionItem = null; 19 | if(this.infos.length==0){ 20 | newItem = new CompletionItem(item.funLable,CompletionItemKind.Function); 21 | }else{ 22 | newItem = this.infos.pop(); 23 | } 24 | newItem.label = item.funLable; 25 | newItem.documentation = item.documentation; 26 | newItem.insertText = item.funvSnippetString == null ?item.funLable : item.funvSnippetString; 27 | return newItem; 28 | } 29 | public pushItems(items:Array){ 30 | items.forEach(v=>{ 31 | this.infos.push(v) 32 | }) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/luatool/manager/CommentLuaCompletionManager.ts: -------------------------------------------------------------------------------- 1 | import { CompletionItem, CompletionItemKind,TextDocument} from 'vscode'; 2 | export class CommentLuaCompletionManager{ 3 | public static ins:CommentLuaCompletionManager; 4 | public items:Array; 5 | constructor(){ 6 | this.items = new Array(); 7 | var completions = [ 8 | { 9 | name:"return", 10 | comment:"返回值注释 例:@return [com.app.Model.TestModel]", 11 | insertText:"return " 12 | }, 13 | { 14 | name:"parentClass", 15 | comment:"module继承注释 例:@parentClass [com.app.Model.TestModel]", 16 | insertText:"parentClass " 17 | }, 18 | { 19 | name:"valueReference", 20 | comment:"变量引用注释 例:@valueReference [com.app.Model.TestModel]", 21 | insertText:"valueReference " 22 | }, 23 | { 24 | name:"desc", 25 | comment:"方法描述", 26 | insertText:"desc" 27 | }, 28 | 29 | ] 30 | completions.forEach(v=>{ 31 | var item:CompletionItem = new CompletionItem(v.name,CompletionItemKind.Property) 32 | item.documentation = v.comment; 33 | item.insertText = v.insertText; 34 | 35 | this.items.push(item) 36 | }) 37 | 38 | 39 | } 40 | 41 | 42 | 43 | public static getIns(){ 44 | if(CommentLuaCompletionManager.ins == null){ 45 | CommentLuaCompletionManager.ins = new CommentLuaCompletionManager(); 46 | } 47 | return CommentLuaCompletionManager.ins; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /src/luatool/manager/LuaFileCompletionItems.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | import { LuaFiledCompletionInfo } from "../provider/LuaFiledCompletionInfo" 3 | import { ExtensionManager } from "../ex/ExtensionManager" 4 | var ospath = require("path") 5 | /** 6 | * 存储项目中的路径 7 | */ 8 | export class LuaFileCompletionItems { 9 | private static _ins: LuaFileCompletionItems; 10 | 11 | public static getLuaFileCompletionItems() { 12 | if (LuaFileCompletionItems._ins == null) { 13 | LuaFileCompletionItems._ins = new LuaFileCompletionItems() 14 | } 15 | return LuaFileCompletionItems._ins; 16 | } 17 | public fileExtnames:Array; 18 | public completions: Array; 19 | public modulePaths:Map>; 20 | public constructor() { 21 | this.fileExtnames = new Array(); 22 | this.fileExtnames.push(".lua") 23 | this.completions = new Array() 24 | this.modulePaths = new Map>() 25 | } 26 | public getUriCompletionByModuleName(moduleName:string){ 27 | for (var index = 0; index < this.completions.length; index++) { 28 | var element = this.completions[index]; 29 | if(moduleName == element.label){ 30 | return element.uri 31 | } 32 | } 33 | 34 | 35 | } 36 | /** 37 | * 获取路径集合根据moduleName 38 | */ 39 | public getUrisByModuleName(moduleName:string):Array{ 40 | var lowermoduleName = moduleName.toLowerCase() 41 | if( this.modulePaths.has(lowermoduleName)){ 42 | return this.modulePaths.get(lowermoduleName) 43 | } 44 | return null 45 | } 46 | 47 | 48 | 49 | 50 | public addCompletion(path: vscode.Uri, isCheck: boolean) { 51 | if (isCheck) { 52 | for (var index = 0; index < this.completions.length; index++) { 53 | var element = this.completions[index]; 54 | if (element.uri.path == path.path) { 55 | return 56 | } 57 | } 58 | } 59 | var position: vscode.Position = new vscode.Position(1, 1) 60 | var str:string = path.fsPath 61 | 62 | for (var index = 0; index < this.fileExtnames.length; index++) { 63 | 64 | var extname = this.fileExtnames[index]; 65 | var extname1 = ospath.extname(str) 66 | if(extname == extname1){ 67 | str = str.substring(0,str.length-extname1.length) 68 | break; 69 | } 70 | 71 | } 72 | 73 | str = str.replace(/\\/g, "/"); 74 | str = str.replace(new RegExp("/", "gm"), ".") 75 | var str_1 = str.toLowerCase() 76 | 77 | ExtensionManager.em.luaIdeConfigManager.scriptRoots.forEach(scriptPath=>{ 78 | var scriptPath_1 =scriptPath; 79 | 80 | var index = str_1.indexOf(scriptPath_1) 81 | if (index > -1) { 82 | var length = scriptPath_1.length; 83 | str = str.substring(index+length) 84 | if(str.charAt(0) == "."){ 85 | str = str.substring(1) 86 | } 87 | var names:Array =str.split(".") 88 | var moduleName:string = names[names.length-1] 89 | var moduleNameLower = moduleName.toLowerCase() 90 | if(!this.modulePaths.has(moduleNameLower)){ 91 | this.modulePaths.set(moduleNameLower,new Array()); 92 | } 93 | var paths:Array = this.modulePaths.get(moduleNameLower) 94 | if(paths.indexOf(path.path) == -1){ 95 | paths.push(path.path) 96 | var completion: LuaFiledCompletionInfo = new LuaFiledCompletionInfo( 97 | str, vscode.CompletionItemKind.Class, path, position,false) 98 | this.completions.push(completion) 99 | } 100 | 101 | } 102 | 103 | }) 104 | 105 | 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/luatool/manager/LuaGolbalCompletionManager.ts: -------------------------------------------------------------------------------- 1 | import { LuaFiledCompletionInfo } from "../provider/LuaFiledCompletionInfo"; 2 | import { CompletionItemKind } from "vscode"; 3 | 4 | export class LuaGolbalCompletionManager { 5 | public static rootCompletion: LuaFiledCompletionInfo = new LuaFiledCompletionInfo("", CompletionItemKind.Field, null, null, false); 6 | public static setGolbalCompletion(completion: LuaFiledCompletionInfo) { 7 | completion.getItems().forEach((v, k) => { 8 | this.rootCompletion.addItemToGolbal(v) 9 | }) 10 | // console.log(this.rootCompletion.items) 11 | } 12 | public static clearGolbalCompletion(completion: LuaFiledCompletionInfo) { 13 | completion.getItems().forEach((v, k) => { 14 | this.rootCompletion.delItemToGolbal(v) 15 | }) 16 | } 17 | 18 | public static getCompletionByKeys(keys:Array) 19 | { 20 | var item = this.rootCompletion; 21 | for (var index = 0; index < keys.length; index++) { 22 | var key = keys[index]; 23 | item = item.getItemByKey(key,true) 24 | if(item == null){ 25 | break; 26 | } 27 | index++; 28 | } 29 | return item; 30 | 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/luatool/manager/LuaSymbolInformation.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | import {LuaFiledCompletionInfo} from "../provider/LuaFiledCompletionInfo" 3 | import {CLog,getParamComment,getTokens,getFirstComments} from '../Utils' 4 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType} from '../TokenInfo'; 5 | export class LuaSymbolInformation extends vscode.SymbolInformation 6 | { 7 | public isLocal:boolean = false; 8 | public argLuaFiledCompleteInfos:Array; 9 | private uri_:vscode.Uri; 10 | private range_:vscode.Range; 11 | public parent:LuaSymbolInformation; 12 | constructor(name: string, kind: vscode.SymbolKind, range: vscode.Range, uri?: vscode.Uri, containerName?: string) 13 | { 14 | 15 | super(name,kind,range,uri,containerName); 16 | this.uri_ = uri; 17 | this.range_ = range; 18 | 19 | } 20 | 21 | 22 | public initArgs(args:Array,comments: Array) 23 | { 24 | if(args != null ) 25 | { 26 | this.argLuaFiledCompleteInfos = new Array(); 27 | for (var i = 0; i < args.length; i++) { 28 | var element = args[i]; 29 | var completion:LuaFiledCompletionInfo = new LuaFiledCompletionInfo(element, 30 | vscode.CompletionItemKind.Variable,this.uri_,this.range_.start,false) 31 | if(comments) { 32 | for (var index = 0; index < comments.length; index++) { 33 | var comment:LuaComment = comments[index]; 34 | 35 | var argComment = "@"+element+":"; 36 | var cindex:number = comment.content.indexOf(argComment) 37 | if(cindex > -1){ 38 | completion.documentation = comment.content.substring(cindex+argComment.length).trim() 39 | break 40 | } 41 | } 42 | } 43 | this.argLuaFiledCompleteInfos.push(completion) 44 | } 45 | 46 | } 47 | 48 | } 49 | } -------------------------------------------------------------------------------- /src/luatool/provider/LuaCompletionItemFunControler.ts: -------------------------------------------------------------------------------- 1 | import { LuaFiledCompletionInfo } from "../provider/LuaFiledCompletionInfo" 2 | import vscode = require('vscode'); 3 | import { LuaParse } from "../LuaParse"; 4 | import { FileCompletionItemManager } from "../manager/FileCompletionItemManager"; 5 | import { LuaGolbalCompletionManager } from "../manager/LuaGolbalCompletionManager"; 6 | import { LuaFileCompletionItems } from "../manager/LuaFileCompletionItems"; 7 | import { CompletionItemKind } from "vscode"; 8 | import { LuaInfoManager } from "../LuaInfoManager"; 9 | import { LuaCompletionItemControler } from "./LuaCompletionItemControler"; 10 | import { LuaCompletionItemProviderUtils } from "./LuaCompletionItemProviderUtils"; 11 | export class LuaCompletionItemFunControler { 12 | private static _LuaCompletionItemFunControler: LuaCompletionItemFunControler; 13 | private luaInfoManager: LuaInfoManager; 14 | private luaCompletionItemControler: LuaCompletionItemControler; 15 | private luaCompletionItemProviderUtils: LuaCompletionItemProviderUtils; 16 | constructor(luaCompletionItemControler: LuaCompletionItemControler) { 17 | this.luaInfoManager = LuaParse.lp.luaInfoManager 18 | this.luaCompletionItemControler = luaCompletionItemControler; 19 | this.luaCompletionItemProviderUtils = LuaCompletionItemProviderUtils.getIns(); 20 | } 21 | public static getIns(luaCompletionItemControler: LuaCompletionItemControler) { 22 | if (LuaCompletionItemFunControler._LuaCompletionItemFunControler == null) { 23 | LuaCompletionItemFunControler._LuaCompletionItemFunControler = new LuaCompletionItemFunControler(luaCompletionItemControler) 24 | } 25 | return LuaCompletionItemFunControler._LuaCompletionItemFunControler 26 | } 27 | /** 28 | * local data = model:getInfo() 29 | * 获取一个变量是一个方法的返回值 30 | */ 31 | public getReferenceCompletionFunValue(item: LuaFiledCompletionInfo): Array { 32 | if (item.referenceCompletionFunKeys) { 33 | var requireReferenceItems: Array = new Array(); 34 | item.referenceCompletionFunKeys.forEach((v, k) => { 35 | var keys: Array = new Array(); 36 | for (var index = 0; index < v.length - 1; index++) { 37 | var key = v[index]; 38 | keys.push(key) 39 | } 40 | var valueFunName: string = v[v.length - 1] 41 | var funNames: Array = this.luaCompletionItemControler.getFunNames(k) 42 | var citems: Array = new Array(); 43 | if (keys.length > 0) { 44 | 45 | 46 | // if (funNames.length == 0 && funNames[0] == "__g__") { 47 | // //全局方法 48 | 49 | // } else { 50 | this.luaCompletionItemControler.getLuaCompletionsByKeysAndFunNames(item.uri, keys.reverse(), funNames, citems, false) 51 | // } 52 | 53 | 54 | if (valueFunName == "new") { 55 | if (citems.length > 0) { 56 | var newRootCompletionInfo = new LuaFiledCompletionInfo("", vscode.CompletionItemKind.Class, citems[0].uri, citems[0].position, false) 57 | citems.forEach(element => { 58 | newRootCompletionInfo.addItem(element) 59 | }); 60 | requireReferenceItems.push(newRootCompletionInfo) 61 | } 62 | 63 | 64 | } else { 65 | citems.forEach(v1 => { 66 | if (v1.label == valueFunName) { 67 | // if(v1.kind == CompletionItemKind.Function){ 68 | this.getFunctionReturnCompletionKeys(v1, requireReferenceItems) 69 | // } 70 | } 71 | }) 72 | } 73 | } else { 74 | var funItem = this.getFunByfunName(valueFunName,item,funNames) 75 | if(funItem != null){ 76 | this.getFunctionReturnCompletionKeys(funItem, requireReferenceItems) 77 | } 78 | } 79 | 80 | 81 | 82 | }) 83 | 84 | return requireReferenceItems 85 | 86 | 87 | } 88 | return null 89 | 90 | } 91 | public getFunctionReturnCompletionGolbalByKey(key: string, item: LuaFiledCompletionInfo) { 92 | //现在本文件中找 如果本文件中没有找到那么就全局找 93 | var fcim: FileCompletionItemManager = this.luaInfoManager.getFcimByPathStr(item.uri.path) 94 | if (fcim == null) return 95 | //如果找到多个 那么就直接忽略 96 | 97 | } 98 | 99 | /** 100 | * 获取方法的返回值 101 | */ 102 | public getFunctionReturnCompletionKeys(item: LuaFiledCompletionInfo, items: Array): Array { 103 | if (item.funAnnotationReturnValue) { 104 | var fitems: Array = this.luaCompletionItemProviderUtils.getCompletionByModulePath(item.funAnnotationReturnValue) 105 | this.luaCompletionItemProviderUtils.mergeItems(items, fitems) 106 | } 107 | else if (item.functionReturnCompletionKeys) { 108 | var citems: Array = new Array(); 109 | item.functionReturnCompletionKeys.forEach((v, k) => { 110 | var funNames: Array = this.luaCompletionItemControler.getFunNames(k) 111 | var keys: Array = new Array() 112 | if (v.length == 1) { 113 | keys.push(v[0]) 114 | } else { 115 | for (var index = 0; index < v.length - 1; index++) { 116 | keys.push(v[index]) 117 | } 118 | } 119 | 120 | var keyName = v[v.length - 1] 121 | // keys.push(".") 122 | this.luaCompletionItemControler.getLuaCompletionsByKeysAndFunNames(item.uri, keys.reverse(), funNames, citems, false) 123 | citems.forEach(element => { 124 | if (element.label == keyName) { 125 | 126 | var reItems = this.luaCompletionItemControler.checkReferenceValue(element) 127 | this.luaCompletionItemProviderUtils.mergeItems(items, reItems) 128 | items.push(element) 129 | } 130 | 131 | }); 132 | 133 | }) 134 | 135 | } 136 | return items 137 | } 138 | 139 | 140 | public getFunByfunName(functionName: string, item: LuaFiledCompletionInfo, functionNames: Array):LuaFiledCompletionInfo { 141 | var fcim: FileCompletionItemManager = this.luaInfoManager.getFcimByPathStr(item.uri.path) 142 | if (fcim == null) return 143 | functionNames = functionNames.reverse(); 144 | for (var index = 0; index < functionNames.length; index++) { 145 | var fname = functionNames[index]; 146 | var fitem = fcim.luaFunFiledCompletions.get(fname) 147 | if(fitem != null){ 148 | var targetItem =fitem.getItemByKey(functionName) 149 | if(targetItem != null){ 150 | return targetItem 151 | } 152 | 153 | } 154 | } 155 | 156 | //全局查找 157 | this.luaInfoManager.fileCompletionItemManagers.forEach((v,k)=>{ 158 | var targetItem = v.luaFunCompletionInfo.getItemByKey(functionName) 159 | if(targetItem != null){ 160 | return targetItem 161 | } 162 | }) 163 | 164 | 165 | } 166 | 167 | } -------------------------------------------------------------------------------- /src/luatool/provider/LuaCompletionItemGolbalControler.ts: -------------------------------------------------------------------------------- 1 | import { LuaFiledCompletionInfo } from "../provider/LuaFiledCompletionInfo" 2 | import vscode = require('vscode'); 3 | import { LuaParse } from "../LuaParse"; 4 | import { FileCompletionItemManager } from "../manager/FileCompletionItemManager"; 5 | import { LuaGolbalCompletionManager } from "../manager/LuaGolbalCompletionManager"; 6 | import { LuaFileCompletionItems } from "../manager/LuaFileCompletionItems"; 7 | import { CompletionItemKind } from "vscode"; 8 | import { LuaInfoManager } from "../LuaInfoManager"; 9 | export class LuaCompletionItemGolbalControler { 10 | private static _LuaCompletionItemGolbalControler: LuaCompletionItemGolbalControler; 11 | private luaInfoManager: LuaInfoManager; 12 | constructor() { 13 | this.luaInfoManager = LuaParse.lp.luaInfoManager 14 | } 15 | public static getIns() { 16 | if (LuaCompletionItemGolbalControler._LuaCompletionItemGolbalControler == null) { 17 | LuaCompletionItemGolbalControler._LuaCompletionItemGolbalControler = new LuaCompletionItemGolbalControler() 18 | } 19 | return LuaCompletionItemGolbalControler._LuaCompletionItemGolbalControler 20 | } 21 | 22 | public getItemByKeys(keys:Array){ 23 | var items = this.getFirstItem(keys[0]) 24 | for (var index = 2; index < keys.length; index++) { 25 | var key = keys[index]; 26 | items = this.getFindItemByKey(items,key); 27 | if(items.length == 0){ 28 | break; 29 | } 30 | index++; 31 | } 32 | return items 33 | } 34 | public getFindItemByKey(items:Array,key:string){ 35 | var newitems:Array = new Array(); 36 | for (var index = 0; index < items.length; index++) { 37 | var item = items[index]; 38 | var fitem =item.getItemByKey(key) 39 | if(fitem){ 40 | newitems.push(fitem) 41 | } 42 | } 43 | return newitems 44 | } 45 | public getFirstItem(key){ 46 | var items:Array = new Array(); 47 | this.luaInfoManager.fileCompletionItemManagers.forEach((v,k)=>{ 48 | var item = v.luaGolbalCompletionInfo.getItemByKey(key) 49 | if(item != null && item.isNewVar == true){ 50 | items.push(item) 51 | var funItem = v.luaFunCompletionInfo.getItemByKey(key,false) 52 | if(funItem != null){ 53 | items.push(funItem) 54 | } 55 | } 56 | 57 | }) 58 | return items; 59 | } 60 | 61 | 62 | } -------------------------------------------------------------------------------- /src/luatool/provider/LuaCompletionItemProviderUtils.ts: -------------------------------------------------------------------------------- 1 | import { LuaFiledCompletionInfo } from "./LuaFiledCompletionInfo"; 2 | import { LuaFileCompletionItems } from "../manager/LuaFileCompletionItems" 3 | import vscode = require('vscode'); 4 | import { FileCompletionItemManager } from "../manager/FileCompletionItemManager"; 5 | import { LuaParse } from "../LuaParse"; 6 | export class LuaCompletionItemProviderUtils { 7 | public static _LuaCompletionItemProviderUtils:LuaCompletionItemProviderUtils; 8 | public static getIns(){ 9 | if(LuaCompletionItemProviderUtils._LuaCompletionItemProviderUtils == null){ 10 | LuaCompletionItemProviderUtils._LuaCompletionItemProviderUtils = new LuaCompletionItemProviderUtils(); 11 | } 12 | return LuaCompletionItemProviderUtils._LuaCompletionItemProviderUtils 13 | } 14 | private luaFileCompletionItems: LuaFileCompletionItems; 15 | constructor(){ 16 | this.luaFileCompletionItems = LuaFileCompletionItems.getLuaFileCompletionItems() 17 | 18 | } 19 | /** 20 | * 根据路径获取completions 21 | */ 22 | public getCompletionByModulePath(modulePath: string): Array { 23 | var ritems: Array = new Array(); 24 | 25 | var uri: vscode.Uri = this.luaFileCompletionItems.getUriCompletionByModuleName(modulePath) 26 | if (uri) { 27 | var referenceCompletionManager: FileCompletionItemManager = LuaParse.lp.luaInfoManager.getFcimByPathStr(uri.path) 28 | var items: Array = new Array(); 29 | if (referenceCompletionManager.rootCompletionInfo != null) items.push(referenceCompletionManager.rootCompletionInfo) 30 | if (referenceCompletionManager.rootFunCompletionInfo != null) items.push(referenceCompletionManager.rootFunCompletionInfo) 31 | return items 32 | 33 | }else{ 34 | var moduleInfos = modulePath.split('.'); 35 | if(moduleInfos.length > 0){ 36 | return this.getItemsByModuleName(moduleInfos[0]) 37 | } 38 | 39 | } 40 | return null 41 | } 42 | public getItemsByModuleName(moduleName){ 43 | var reItems:Array = new Array(); 44 | var lfcis: LuaFileCompletionItems = LuaFileCompletionItems.getLuaFileCompletionItems() 45 | var paths: Array = lfcis.getUrisByModuleName(moduleName) 46 | if (paths) { 47 | for (var index = 0; index < paths.length; index++) { 48 | var fcim: FileCompletionItemManager = LuaParse.lp.luaInfoManager.getFcimByPathStr(paths[index]) 49 | if(fcim.rootCompletionInfo){ 50 | reItems.push(fcim.rootCompletionInfo) 51 | }else{ 52 | var item :LuaFiledCompletionInfo = fcim.luaGolbalCompletionInfo.getItemByKey(moduleName,true) 53 | if(item){ 54 | reItems.push(item) 55 | }else{ 56 | LuaParse.lp.luaInfoManager.fileCompletionItemManagers.forEach((v,k)=>{ 57 | var gitem = v.luaGolbalCompletionInfo.getItemByKey(moduleName,true) 58 | if(gitem){ 59 | if(reItems.indexOf(gitem) == -1){ 60 | reItems.push(gitem) 61 | } 62 | } 63 | 64 | }) 65 | } 66 | 67 | } 68 | if(fcim.rootFunCompletionInfo){ 69 | reItems.push(fcim.rootFunCompletionInfo) 70 | }else{ 71 | LuaParse.lp.luaInfoManager.fileCompletionItemManagers.forEach((v,k)=>{ 72 | var gitem = v.luaFunCompletionInfo.getItemByKey(moduleName,true) 73 | if(gitem){ 74 | if(reItems.indexOf(gitem) == -1){ 75 | reItems.push(gitem) 76 | } 77 | } 78 | 79 | }) 80 | } 81 | 82 | 83 | } 84 | } 85 | return reItems; 86 | 87 | } 88 | public getParentItems(completion:LuaFiledCompletionInfo,parentCompletion:Array>){ 89 | if(completion.parentModulePath != null){ 90 | var uri: vscode.Uri = this.luaFileCompletionItems.getUriCompletionByModuleName(completion.parentModulePath) 91 | if (uri) { 92 | var referenceCompletionManager: FileCompletionItemManager = LuaParse.lp.luaInfoManager.getFcimByPathStr(uri.path) 93 | 94 | if(referenceCompletionManager.rootCompletionInfo){ 95 | parentCompletion.push(referenceCompletionManager.rootCompletionInfo.getItems()) 96 | parentCompletion.push(referenceCompletionManager.rootFunCompletionInfo.getItems()) 97 | if(referenceCompletionManager.rootCompletionInfo.parentModulePath != null){ 98 | this.getParentItems(referenceCompletionManager.rootCompletionInfo,parentCompletion) 99 | 100 | } 101 | } 102 | 103 | } 104 | } 105 | } 106 | public getParentItemByKey(completion:LuaFiledCompletionInfo,key:string):LuaFiledCompletionInfo{ 107 | var uri: vscode.Uri = this.luaFileCompletionItems.getUriCompletionByModuleName(completion.parentModulePath) 108 | if (uri) { 109 | var referenceCompletionManager: FileCompletionItemManager = LuaParse.lp.luaInfoManager.getFcimByPathStr(uri.path) 110 | 111 | if(referenceCompletionManager.rootCompletionInfo){ 112 | var item =referenceCompletionManager.rootCompletionInfo.getItemByKey(key) 113 | if(item){ 114 | return item 115 | }else{ 116 | if(referenceCompletionManager.rootCompletionInfo.parentModulePath != null){ 117 | return this.getParentItemByKey(referenceCompletionManager.rootCompletionInfo,key) 118 | } 119 | } 120 | 121 | } 122 | 123 | } 124 | return null; 125 | } 126 | /** 127 | * 合并两个list 128 | */ 129 | public mergeItems(items1: Array, items2: Array) { 130 | if (items2) { 131 | items2.forEach(item => { 132 | if (items1.indexOf(item) == -1) { 133 | items1.push(item) 134 | } 135 | 136 | }) 137 | } 138 | 139 | return items1 140 | } 141 | } -------------------------------------------------------------------------------- /src/luatool/provider/LuaDocumentSymbolProvider.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | 3 | import {LuaParse} from '../LuaParse' 4 | export class LuaDocumentSymbolProvider implements vscode.DocumentSymbolProvider { 5 | 6 | private goKindToCodeKind: { [key: string]: vscode.SymbolKind } = { 7 | 'package': vscode.SymbolKind.Package, 8 | 'import': vscode.SymbolKind.Namespace, 9 | 'variable': vscode.SymbolKind.Variable, 10 | 'type': vscode.SymbolKind.Interface, 11 | 'function': vscode.SymbolKind.Function 12 | }; 13 | 14 | 15 | /** 16 | * 17 | */ 18 | public provideDocumentSymbols(document: vscode.TextDocument, 19 | token: vscode.CancellationToken): 20 | Thenable { 21 | let options = { fileName: document.fileName }; 22 | 23 | return new Promise((resolve, reject) => { 24 | 25 | return resolve(LuaParse.lp.luaInfoManager.getFcimByPathStr(document.uri.path).symbols); 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/luatool/provider/LuaFormattingEditProvider.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | import child_process = require('child_process'); 3 | import { LuaParse } from '../LuaParse' 4 | import { LuaFormatParseTool } from "./format/LuaFormatParseTool" 5 | import { LuaFormat } from "./format/LuaFormatChildProcess" 6 | 7 | var path = require('path'); 8 | var fs = require('fs'); 9 | var os = require('os'); 10 | export class LuaFormattingEditProvider implements vscode.DocumentFormattingEditProvider, vscode.DocumentRangeFormattingEditProvider { 11 | 12 | 13 | public provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): Thenable { 14 | 15 | return this.provideDocumentRangeFormattingEdits(document, null, options, token); 16 | } 17 | 18 | public provideDocumentRangeFormattingEdits(document: vscode.TextDocument, range: vscode.Range, options: vscode.FormattingOptions, token: vscode.CancellationToken): Thenable { 19 | if (range === null) { 20 | var start = new vscode.Position(0, 0); 21 | var end = new vscode.Position(document.lineCount - 1, document.lineAt(document.lineCount - 1).text.length); 22 | range = new vscode.Range(start, end); 23 | } 24 | var content = document.getText(range); 25 | var result = []; 26 | 27 | content = this.format(content) 28 | result.push(new vscode.TextEdit(range, content)) 29 | return Promise.resolve(result) 30 | } 31 | 32 | 33 | private format(content: string): string { 34 | // return LuaFormat(content) 35 | var luaFormatParseTool: LuaFormatParseTool = new LuaFormatParseTool(content) 36 | return luaFormatParseTool.formatComent 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/luatool/provider/LuaMode.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------- 2 | * Copyright (C) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import vscode = require('vscode'); 9 | 10 | export const LUA_MODE: vscode.DocumentFilter = { language: 'lua', scheme: 'file' }; 11 | -------------------------------------------------------------------------------- /src/luatool/provider/LuaReferenceProvider.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | import cp = require('child_process'); 3 | import path = require('path'); 4 | 5 | 6 | 7 | 8 | export class LuaReferenceProvider implements vscode.ReferenceProvider { 9 | 10 | public provideReferences(document: vscode.TextDocument, position: vscode.Position, options: { includeDeclaration: boolean }, token: vscode.CancellationToken): Thenable { 11 | return vscode.workspace.saveAll(false).then(() => { 12 | return this.doFindReferences(document, position, options, token); 13 | }); 14 | } 15 | 16 | private doFindReferences(document: vscode.TextDocument, position: vscode.Position, options: { includeDeclaration: boolean }, token: vscode.CancellationToken): Thenable { 17 | return new Promise((resolve, reject) => { 18 | return resolve([]); 19 | // let filename = canonicalizeGOPATHPrefix(document.fileName); 20 | // let cwd = path.dirname(filename); 21 | 22 | // // get current word 23 | // let wordRange = document.getWordRangeAtPosition(position); 24 | // if (!wordRange) { 25 | // return resolve([]); 26 | // } 27 | 28 | // let offset = byteOffsetAt(document, position); 29 | 30 | // let goGuru = getBinPath('guru'); 31 | // let buildTags = '"' + vscode.workspace.getConfiguration('go')['buildTags'] + '"'; 32 | 33 | // let process = cp.execFile(goGuru, ['-tags', buildTags, 'referrers', `${filename}:#${offset.toString()}`], {}, (err, stdout, stderr) => { 34 | // try { 35 | // if (err && (err).code === 'ENOENT') { 36 | // promptForMissingTool('guru'); 37 | // return resolve(null); 38 | // } 39 | 40 | // let lines = stdout.toString().split('\n'); 41 | // let results: vscode.Location[] = []; 42 | // for (let i = 0; i < lines.length; i++) { 43 | // let line = lines[i]; 44 | // let match = /^(.*):(\d+)\.(\d+)-(\d+)\.(\d+):/.exec(lines[i]); 45 | // if (!match) continue; 46 | // let [_, file, lineStartStr, colStartStr, lineEndStr, colEndStr] = match; 47 | // let referenceResource = vscode.Uri.file(path.resolve(cwd, file)); 48 | // let range = new vscode.Range( 49 | // +lineStartStr - 1, +colStartStr - 1, +lineEndStr - 1, +colEndStr 50 | // ); 51 | // results.push(new vscode.Location(referenceResource, range)); 52 | // } 53 | // resolve(results); 54 | // } catch (e) { 55 | // reject(e); 56 | // } 57 | // }); 58 | 59 | // token.onCancellationRequested(() => 60 | // process.kill() 61 | // ); 62 | }); 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /src/luatool/provider/LuaSignatureHelpProvider.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | import { LuaParse } from '../LuaParse' 8 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType } from '../TokenInfo'; 9 | import { languages, window, commands, SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, TextDocument, Position, Range, CancellationToken } from 'vscode'; 10 | 11 | import { FileCompletionItemManager } from "../manager/FileCompletionItemManager" 12 | import { LuaFiledCompletionInfo } from './LuaFiledCompletionInfo' 13 | import { CLog, getParamComment, getSelfToModuleName, getTokens, getFirstComments } from '../Utils' 14 | import { LuaSymbolInformation } from "../manager/LuaSymbolInformation"; 15 | export class LuaSignatureHelpProvider implements SignatureHelpProvider { 16 | 17 | public provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Promise { 18 | 19 | let result: SignatureHelp = this.walkBackwardsToBeginningOfCall(document, position); 20 | 21 | return Promise.resolve(result) 22 | 23 | } 24 | private createSignatureInformation(symbol:LuaSymbolInformation,cIdex:number,funName:string) 25 | { 26 | let result = new SignatureHelp(); 27 | //拼接方法名字 28 | let si = new SignatureInformation(funName, symbol.containerName); 29 | si.parameters = [] 30 | var pstr = "(" 31 | symbol.argLuaFiledCompleteInfos.forEach(arg => { 32 | si.parameters.push(new ParameterInformation(arg.label, arg.documentation)) 33 | pstr += arg.label + ","; 34 | }) 35 | if(pstr != "(") { 36 | pstr = pstr.substr(0, pstr.length - 1); 37 | } 38 | 39 | pstr += ")" 40 | si.label = si.label + pstr 41 | // console.log("si.label:" + si.label) 42 | result.signatures = [si]; 43 | result.activeSignature = 0; 44 | result.activeParameter = cIdex 45 | return result 46 | 47 | } 48 | 49 | 50 | private walkBackwardsToBeginningOfCall(document: TextDocument, position: Position): SignatureHelp { 51 | var lp: LuaParse = LuaParse.lp; 52 | var tokens: Array = getTokens(document, position) 53 | var index: number = tokens.length - 1; 54 | var count: number = 0; 55 | var cIdex: number = 0; 56 | let signature: SignatureHelp = null; 57 | while (true) { 58 | CLog(); 59 | if (index < 0) { 60 | break; 61 | } 62 | 63 | var token: TokenInfo = tokens[index] 64 | if (lp.consume(')', token, TokenTypes.Punctuator)) { 65 | count++; 66 | } else if (lp.consume('(', token, TokenTypes.Punctuator)) { 67 | count--; 68 | if (count < 0) { 69 | index--; 70 | break; 71 | } 72 | } 73 | else if (lp.consume('end', token, TokenTypes.Keyword)) { 74 | count++; 75 | index--; 76 | while (true) { 77 | CLog(); 78 | var ktoken: TokenInfo = tokens[index] 79 | if (lp.consume('then', ktoken, TokenTypes.Keyword) || 80 | lp.consume('do', ktoken, TokenTypes.Keyword) 81 | 82 | ) { 83 | break; 84 | } 85 | index--; 86 | if (index < 0) break; 87 | } 88 | continue; 89 | } 90 | else if (lp.consume(',', token, TokenTypes.Punctuator)) { 91 | if (count == 0) { 92 | cIdex++; 93 | } 94 | } 95 | index--; 96 | } 97 | 98 | 99 | if (index >= 0) { 100 | var keys: Array = new Array(); 101 | while (true) { 102 | CLog(); 103 | var token: TokenInfo = tokens[index]; 104 | if (token.type == TokenTypes.Identifier) { 105 | keys.push(token.value) 106 | index--; 107 | if (index < 0) { 108 | break; 109 | } 110 | var ptoken: TokenInfo = tokens[index]; 111 | if ( 112 | lp.consume(':', ptoken, TokenTypes.Punctuator) || 113 | lp.consume('.', ptoken, TokenTypes.Punctuator) 114 | ) { 115 | index--; 116 | keys.push(ptoken.value) 117 | } 118 | else if (lp.consume('function', ptoken, TokenTypes.Keyword)) { 119 | keys = new Array(); 120 | break; 121 | } 122 | else { 123 | break; 124 | } 125 | } else { 126 | break; 127 | } 128 | } 129 | if(keys.length == 1){ 130 | //检查是不是内部方法 131 | var fcim: FileCompletionItemManager = lp.luaInfoManager.getFcimByPathStr(document.uri.path) 132 | var curFunFcim:LuaSymbolInformation = null 133 | for (var kindex = 0; kindex < fcim.symbols.length; kindex++) { 134 | var element = fcim.symbols[kindex]; 135 | //找到当前所在方法 136 | if(element.location.range.start.line <= position.line && 137 | element.location.range.end.line >= position.line){ 138 | curFunFcim = element 139 | } 140 | } 141 | if(curFunFcim != null){ 142 | for (var index = 0; index < fcim.symbols.length; index++) { 143 | var element = fcim.symbols[index]; 144 | if(element.name.indexOf(curFunFcim.name+"->"+keys[0]) > -1){ 145 | signature = this.createSignatureInformation(element,cIdex,keys[0]) 146 | break 147 | } 148 | } 149 | } 150 | } 151 | if(signature != null){ 152 | return signature 153 | } 154 | var key: string = keys[keys.length - 1] 155 | if (key == "self") { 156 | var data = getSelfToModuleName(tokens, lp) 157 | if (data == null) { 158 | return 159 | } else { 160 | var moduleName = data.moduleName 161 | keys[keys.length - 1] = moduleName 162 | key = moduleName; 163 | } 164 | } 165 | var funName: string = "" 166 | for (var kindex = keys.length - 1; kindex >= 0; kindex--) { 167 | 168 | funName += keys[kindex] 169 | } 170 | lp.luaInfoManager.fileCompletionItemManagers.forEach((v, k) => { 171 | for (var index = 0; index < v.symbols.length; index++) { 172 | var element = v.symbols[index]; 173 | if (element.name == funName) { 174 | signature = this.createSignatureInformation(element,cIdex,element.name) 175 | return 176 | } 177 | 178 | } 179 | }) 180 | } 181 | return signature 182 | 183 | 184 | 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/luatool/provider/ProviderUtils.ts: -------------------------------------------------------------------------------- 1 | 2 | import vscode = require('vscode'); 3 | import { LuaParse } from '../LuaParse' 4 | import { LuaInfo, TokenInfo, TokenTypes, LuaComment, LuaRange, LuaErrorEnum, LuaError, LuaInfoType } from '../TokenInfo'; 5 | import { LuaParseTool } from '../LuaParseTool' 6 | import { CLog } from '../Utils' 7 | export class ProviderUtils { 8 | public static getTokens(document: vscode.TextDocument, position: vscode.Position): Array { 9 | 10 | var lp: LuaParse = LuaParse.lp; 11 | var start: vscode.Position = new vscode.Position(0, 0) 12 | var lpt: LuaParseTool = LuaParse.lp.lpt; 13 | var tokens: Array = new Array(); 14 | lpt.Reset(document.getText(new vscode.Range(start, position))) 15 | while (true) { 16 | CLog(); 17 | var token: TokenInfo = lpt.lex(); 18 | if (token.error != null) { 19 | return; 20 | } 21 | if (token.type == TokenTypes.EOF) { 22 | break; 23 | } 24 | token.index = tokens.length; 25 | tokens.push(token); 26 | } 27 | return tokens; 28 | } 29 | public static getTokenByText(text:string){ 30 | var lpt: LuaParseTool = LuaParse.lp.lpt; 31 | var tokens: Array = new Array(); 32 | lpt.Reset(text) 33 | while (true) { 34 | CLog(); 35 | var token: TokenInfo = lpt.lex(); 36 | if (token.error != null) { 37 | return; 38 | } 39 | if (token.type == TokenTypes.EOF) { 40 | break; 41 | } 42 | token.index = tokens.length; 43 | tokens.push(token); 44 | } 45 | return tokens; 46 | } 47 | public static getComments(comments: Array): string { 48 | if (comments == null) return ""; 49 | var commentStr: string = ""; 50 | if (comments.length == 1) { 51 | return comments[0].content; 52 | } 53 | for (var i: number = 0; i < comments.length; i++) { 54 | var comment = comments[i].content 55 | var index = comment.trim().indexOf("=="); 56 | if (index == 0) { continue } 57 | commentStr = commentStr + comment; 58 | 59 | } 60 | return commentStr; 61 | } 62 | 63 | public static getFirstComments(comments: Array): string { 64 | if (comments == null) return ""; 65 | var commentStr: string = null; 66 | if (comments.length == 1) { 67 | return comments[0].content; 68 | } 69 | var descStr: string = null; 70 | for (var i: number = 0; i < comments.length; i++) { 71 | var comment = comments[i].content 72 | var index = comment.trim().indexOf("=="); 73 | if (index == 0) { continue } 74 | if (comment.indexOf("@desc:") > -1) { 75 | commentStr = comment; 76 | break; 77 | } else if (commentStr == null) { 78 | commentStr = comment; 79 | } 80 | } 81 | return commentStr; 82 | } 83 | public static getSelfToModuleNameAndStartTokenIndex(uri: vscode.Uri, tokens: Array, lp: LuaParse): any { 84 | var index: number = tokens.length - 1; 85 | while (true) { 86 | 87 | if (index < 0) break; 88 | var token: TokenInfo = tokens[index] 89 | if (lp.consume('function', token, TokenTypes.Keyword)) { 90 | var nextToken: TokenInfo = tokens[index + 1] 91 | if (nextToken.type == TokenTypes.Identifier) { 92 | var nextToken1: TokenInfo = tokens[index + 2] 93 | if (lp.consume(':', nextToken1, TokenTypes.Punctuator) || 94 | lp.consume('.', nextToken1, TokenTypes.Punctuator) 95 | ) { 96 | var range: vscode.Range = null 97 | var functionNameToken: TokenInfo = null 98 | //方法名 99 | if (tokens.length > index + 3) { 100 | functionNameToken = tokens[index + 3] 101 | } 102 | if (functionNameToken) { 103 | if (lp.luaInfoManager.getFcimByPathStr(uri.path)) { 104 | var name = nextToken.value + nextToken1.value + functionNameToken.value 105 | range = lp.luaInfoManager.getFcimByPathStr(uri.path).getSymbolEndRange(name) 106 | } else { 107 | return {} 108 | } 109 | 110 | } 111 | var moduleName: string = nextToken.value; 112 | return { moduleName: moduleName, index: index, range: range }; 113 | } 114 | else index-- 115 | } else { 116 | index--; 117 | 118 | } 119 | } else { 120 | index--; 121 | } 122 | } 123 | return null 124 | } 125 | 126 | 127 | public static getParamComment(param: string, comments: Array) { 128 | var paramName: string = "@" + param; 129 | for (var i: number = 0; i < comments.length; i++) { 130 | var comment = comments[i].content 131 | if (comment.indexOf(paramName) > -1) { 132 | comment = comment.replace(paramName, "") 133 | return comment; 134 | } 135 | } 136 | return ""; 137 | 138 | } 139 | 140 | } 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /src/luatool/provider/format/LuaFormatChildProcess.ts: -------------------------------------------------------------------------------- 1 | import child_process = require('child_process'); 2 | import vscode = require('vscode'); 3 | import { ExtensionManager } from '../../ex/ExtensionManager' 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | var os = require('os'); 7 | export function LuaFormat(str): string { 8 | var extensionPath = ExtensionManager.em.luaIdeConfigManager.extensionPath 9 | var rootPath = path.join(extensionPath, "runtime", "win"); 10 | var exePath = path.join(rootPath, "lua.exe"); 11 | var scriptPath = path.join(rootPath, "temp.lua"); 12 | var cmd: string = rootPath + " " + scriptPath; 13 | var options = { 14 | encoding: 'utf8', 15 | timeout: 0, 16 | maxBuffer: 1024 * 1024, 17 | 18 | cwd: rootPath, 19 | env: null 20 | }; 21 | 22 | 23 | try { 24 | fs.writeFileSync(scriptPath, str); 25 | } catch (err) { 26 | return str 27 | } 28 | 29 | var luascriptPath = scriptPath.replace(/\\/g, "\\\\"); 30 | var buff = child_process.spawnSync("lua.exe", ["-e", 'require("formatter")("' + luascriptPath + '")'], options) 31 | var result = buff.stdout.toString().trim(); 32 | if(result == "complete") { 33 | //读取 34 | var contentText = fs.readFileSync(path.join(scriptPath), 'utf-8'); 35 | return contentText 36 | } 37 | return str 38 | } -------------------------------------------------------------------------------- /src/luatool/statistics/StatisticsMain.ts: -------------------------------------------------------------------------------- 1 | import * as net from 'net'; 2 | import {UserInfo} from "../ex/UserInfo" 3 | export class StatisticsEvent{ 4 | public static C2S_UserInfo:number = 1; 5 | public static C2S_OpenRechrage:number = 2; 6 | } 7 | export class StatisticsMain { 8 | 9 | private port: number = 8888 10 | private socket: net.Socket ; 11 | 12 | constructor(userInfo:UserInfo) { 13 | // this.socket = net.connect(this.port, "localhost") 14 | this.socket = net.connect(this.port, "119.29.165.43") 15 | this.socket.on("data", function (data: Buffer) { 16 | 17 | }); 18 | var sm = this; 19 | this.socket.on("connect", function () { 20 | //发送id 21 | sm.sendMsg(StatisticsEvent.C2S_UserInfo,userInfo.toString()) 22 | }) 23 | } 24 | 25 | public sendMsg(event: number, data?: any) { 26 | var sendMsg = { 27 | event: event, 28 | data: data 29 | } 30 | try { 31 | var msg = JSON.stringify(sendMsg) 32 | if(this.socket){ 33 | this.socket.write(msg + "\n"); 34 | } 35 | 36 | } catch (erro) { 37 | console.log("发送消息到客户端错误:" + erro + "\n") 38 | } 39 | } 40 | 41 | 42 | 43 | 44 | } -------------------------------------------------------------------------------- /test/extension.test.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Note: This example test is leveraging the Mocha test framework. 3 | // Please refer to their documentation on https://mochajs.org/ for help. 4 | // 5 | 6 | // The module 'assert' provides assertion methods from node 7 | import * as assert from 'assert'; 8 | 9 | // You can import and use all API from the 'vscode' module 10 | // as well as import your extension to test it 11 | import * as vscode from 'vscode'; 12 | import * as myExtension from '../src/extension'; 13 | 14 | // Defines a Mocha test suite to group tests of similar kind together 15 | suite("Extension Tests", () => { 16 | 17 | // Defines a Mocha unit test 18 | test("Something 1", () => { 19 | assert.equal(-1, [1, 2, 3].indexOf(5)); 20 | assert.equal(-1, [1, 2, 3].indexOf(0)); 21 | }); 22 | }); -------------------------------------------------------------------------------- /test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | var testRunner = require('vscode/lib/testrunner'); 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "." 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | ".vscode-test" 15 | ] 16 | } -------------------------------------------------------------------------------- /version/kangping.luaide-0.1.8.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/version/kangping.luaide-0.1.8.zip -------------------------------------------------------------------------------- /version/lua-0.3.0.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/version/lua-0.3.0.vsix -------------------------------------------------------------------------------- /version/luaide-0.2.1.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/version/luaide-0.2.1.vsix -------------------------------------------------------------------------------- /version/luaide-0.2.2.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k0204/LuaIde/c366aa3ca6e1e4f025739df413c0734b18c4b605/version/luaide-0.2.2.vsix -------------------------------------------------------------------------------- /vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your first VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * press `F5` to open a new window with your extension loaded 16 | * run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World` 17 | * set breakpoints in your code inside `src/extension.ts` to debug your extension 18 | * find output from your extension in the debug console 19 | 20 | ## Make changes 21 | * you can relaunch the extension from the debug toolbar after changing code in `src/extension.ts` 22 | * you can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes 23 | 24 | ## Explore the API 25 | * you can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts` 26 | 27 | ## Run tests 28 | * open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests` 29 | * press `F5` to run the tests in a new window with your extension loaded 30 | * see the output of the test result in the debug console 31 | * make changes to `test/extension.test.ts` or create new test files inside the `test` folder 32 | * by convention, the test runner will only consider files matching the name pattern `**.test.ts` 33 | * you can create folders inside the `test` folder to structure your tests any way you want -------------------------------------------------------------------------------- /注释规则.txt: -------------------------------------------------------------------------------- 1 | 注释返回值类型注释方法: 2 | 1.如果整个项目唯一 直接写文件名 3 | 2.如果不唯一 写全路径 4 | 3.如果一个lua文件中没有return 一个table 那么 即使写了方法返回注释也是无效的 5 | --------------------------------------------------------------------------------