Skip to content

Commit 84c2dd0

Browse files
committed
支持更全面的代码补全;更加全面的符号hover信息;修复一些bug
1 parent 5eb30df commit 84c2dd0

File tree

11 files changed

+201
-133
lines changed

11 files changed

+201
-133
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "LuaCoderAssist",
44
"description": "lua coder assistant in javascript for vscode",
55
"icon": "images/icon.png",
6-
"version": "2.0.5",
6+
"version": "2.0.6",
77
"publisher": "liwangqian",
88
"engines": {
99
"vscode": "^1.25.0"

server/lib/engine/completion.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
const { LoadedPackages } = require('./luaenv');
1919
const { object2Array } = require('./utils');
20-
const { typeOf, searchInnerStackIndex } = require('./typeof');
20+
const { typeOf, findDef, searchInnerStackIndex } = require('./typeof');
2121
const { ScopeEnd } = require('./linear-stack');
2222
const Is = require('./is');
2323

@@ -83,6 +83,9 @@ function completionProvider(context) {
8383
//TODO: support abc().xx
8484
const name = context.names[0];
8585
let value = completionMapCache.get(name);
86+
if (!value) {
87+
value = findDef(name, context.uri, context.range);
88+
}
8689
if (!Is.luaTable(typeOf(value)) && !Is.luaModule(value)) {
8790
return [];
8891
}
@@ -92,7 +95,21 @@ function completionProvider(context) {
9295
for (let i = 1; i < size; ++i) {
9396
let name = context.names[i];
9497
def = def.type.get(name);
95-
if (!def || !Is.luaTable(typeOf(def))) {
98+
if (!def) {
99+
return [];
100+
}
101+
102+
let type = typeOf(def);
103+
104+
// func().abc
105+
if (Is.luaFunction(type)) {
106+
def = type.returns[0];
107+
type = typeOf(def);
108+
}
109+
110+
if (Is.luaTable(type)) {
111+
continue;
112+
} else {
96113
return [];
97114
}
98115
}

server/lib/engine/definition.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,21 @@ function definitionProvider(context) {
6161
for (let i = 1; i < (length - 1); i++) {
6262
const name = names[i];
6363
def = def.type.search(name, context.range).value;
64-
if (!def || !Is.luaTable(typeOf(def))) {
64+
if (!def) {
65+
return [];
66+
}
67+
68+
let type = typeOf(def);
69+
70+
// func().abc
71+
if (Is.luaFunction(type)) {
72+
def = type.returns[0];
73+
type = typeOf(def);
74+
}
75+
76+
if (Is.luaTable(type)) {
77+
continue;
78+
} else {
6579
return [];
6680
}
6781
}

server/lib/engine/extend.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ function parseNamedTypes(json) {
5656
for (const name in types) {
5757
const value = types[name];
5858
const symbol = parseJsonObject(value, name);
59+
symbol.type.typeName = name;
5960
symbol && namedTypes.set(name, symbol);
6061
}
6162
}
@@ -82,6 +83,13 @@ function parseModule(json) {
8283
}
8384
}
8485

86+
/**
87+
* Parse the json format interface desc data.
88+
* @param {*} node JSON object
89+
* @param {String} name Name of the node
90+
*
91+
* @returns {LuaSymbol}
92+
*/
8593
function parseJsonObject(node, name) {
8694
if (!node) {
8795
return undefined;
@@ -164,7 +172,7 @@ function parseArgumentsObject(args) {
164172

165173
function parseReturnsObject(returns) {
166174
if (!returns) {
167-
return [];
175+
return undefined;
168176
}
169177
return returns.map((rt, index) => {
170178
return parseJsonObject(rt, rt.name || `R${index}`);
@@ -187,4 +195,3 @@ function parseRefJsonObject(node, name) {
187195

188196

189197
loadExtentLib('./stdlibs/5_1.json');
190-
console.log(namedTypes);

server/lib/engine/typeof.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ function typeOf(symbol) {
5353
return type;
5454
}
5555

56-
symbol.type = type;
56+
if (type !== LuaBasicTypes.any) {
57+
symbol.type = type
58+
};
59+
5760
return type;
5861
}
5962

@@ -158,8 +161,9 @@ function parseCallExpression(node, type) {
158161

159162
const fname = node.base.name;
160163
if (fname === 'require') {
161-
let moduleName = node.arguments[0].value;
162-
let shortPath = moduleName.replace('.', '/');
164+
let modulePath = (node.argument || node.arguments[0]).value;
165+
let moduleName = modulePath.match(/\w+$/)[0];
166+
let shortPath = modulePath.replace('.', '/');
163167
let mdls = LoadedPackages[moduleName]
164168
// TODO:增加配置项,用来配置搜索路径,然后模拟lua的搜索方法搜索最优匹配模块
165169
for (const uri in mdls) {

server/providers/completion-provider.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class CompletionProvider {
1414
provideCompletions(params) {
1515
let uri = params.textDocument.uri;
1616
let position = params.position;
17+
position.character--;
1718
let document = this.coder.document(uri);
1819
let ref = utils.symbolAtPosition(position, document, { backward: true });
1920
if (ref === undefined) {

server/providers/definition-provider.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const { DefinitionContext, definitionProvider } = require('../lib/engine/definition');
4-
const utils_2 = require('./lib/utils');
4+
const utils_1 = require('./lib/utils');
55
const langserver_1 = require('vscode-languageserver');
66

77
class DefinitionProvider {
@@ -13,7 +13,7 @@ class DefinitionProvider {
1313
let uri = params.textDocument.uri;
1414
let position = params.position;
1515
let document = this.coder.document(uri);
16-
let ref = utils_2.symbolAtPosition(position, document, { backward: true, forward: true });
16+
let ref = utils_1.symbolAtPosition(position, document, { backward: true, forward: true });
1717
if (ref === undefined) {
1818
return [];
1919
}

server/providers/lib/utils.js

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,31 +109,96 @@ function symbolKindDesc(kind) {
109109

110110
exports.symbolKindDesc = symbolKindDesc;
111111

112-
const backwardRegex = /[a-zA-Z0-9_.:]/; // parse all the bases
113-
const forwardRegex = /[a-zA-Z0-9_]/; // parse only the name
114-
function extendTextRange(content, from, options) {
115-
let range = { start: from, end: from };
112+
function isalpha(c) {
113+
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
114+
}
116115

117-
let offset = from;
118-
if (options.backward) {
119-
while (offset-- >= 0) {
120-
if (!backwardRegex.test(content.charAt(offset))) {
121-
range.start = offset + 1;
116+
function isdigit(c) {
117+
return c >= '0' && c <= '9';
118+
}
119+
120+
function skip(pattern, content, offset, step) {
121+
while (pattern.test(content.charAt(offset))) {
122+
offset += step;
123+
}
124+
return offset;
125+
}
126+
127+
function backward(content, offset, collection) {
128+
let bracketDepth = 0;
129+
while (true) {
130+
let c = content.charAt(offset);
131+
if (c === '.' || c === ':') {
132+
if (bracketDepth === 0) {
133+
collection.push(c);
134+
}
135+
offset--;
136+
offset = skip(/\s/, content, offset, -1);
137+
continue;
138+
}
139+
140+
if (c === ')') {
141+
bracketDepth++;
142+
offset--;
143+
continue;
144+
}
145+
146+
if (c === '(') {
147+
bracketDepth--;
148+
if (bracketDepth < 0) {
149+
break;
150+
}
151+
offset--;
152+
continue;
153+
}
154+
155+
if (isalpha(c) || isdigit(c) || c === '_') {
156+
offset--;
157+
if (bracketDepth === 0) {
158+
collection.push(c);
159+
}
160+
continue;
161+
}
162+
163+
if (c === ' ' || c === ',') {
164+
if (bracketDepth === 0) {
122165
break;
123166
}
167+
offset--;
168+
continue;
124169
}
170+
171+
break;
172+
}
173+
174+
collection.reverse();
175+
return offset + 1;
176+
}
177+
178+
const forwardRegex = /[a-zA-Z0-9_]/; // parse only the name
179+
function extendTextRange(content, from, options) {
180+
let range = { start: from, end: from, text: '' };
181+
let offset = from;
182+
let collection = [];
183+
if (options.backward) {
184+
offset = backward(content, offset, collection);
185+
range.start = offset;
125186
}
126187

127188
if (options.forward) {
128189
offset = from;
129190
while (offset++ <= content.length) {
130-
if (!forwardRegex.test(content.charAt(offset))) {
191+
let c = content.charAt(offset);
192+
if (!forwardRegex.test(c)) {
131193
range.end = offset;
132194
break;
133195
}
196+
collection.push(c);
134197
}
135198
}
136199

200+
range.text = collection.join('');
201+
137202
return range;
138203
}
139204

@@ -168,10 +233,7 @@ function symbolAtPosition(position, doc, options) {
168233
return undefined;
169234
}
170235

171-
// let ref = parseContext(text.substring(range.start, range.end));
172-
let ref = { name: text.substring(range.start, range.end), range: [range.start, range.end] };
173-
// ref.location = { start: position, end: position }; // used for scope filter
174-
236+
let ref = { name: range.text, range: [range.start, range.end] };
175237
return ref;
176238
}
177239

@@ -190,7 +252,11 @@ function symbolSignature(symbol, override) {
190252
return details.join('');
191253
}
192254

193-
let returns = (override !== undefined) ? type.variants[override].returns : type.returns;
255+
let returns = type.returns;
256+
if (!returns && override !== undefined) {
257+
returns = type.variants[override].returns;
258+
}
259+
returns = returns || [];
194260
let ret = returns.map(item => {
195261
let typeName = engine.typeOf(item).typeName;
196262
typeName = typeName.startsWith('@') ? 'any' : typeName;

server/providers/symbol-provider.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ class SymbolProvider {
3131
}
3232

3333
let depth = 0, maxDepth = 5; //防止循环引用导致死循环
34-
let walker, forall;
34+
let walker, collectAllChildren;
3535
walker = (def, collection) => {
3636
if (!(def instanceof LuaSymbol)) {
3737
return;
3838
}
3939

40-
if (def.uri === null) {
40+
if (def.uri !== uri) {
4141
return;
4242
}
4343

@@ -53,25 +53,25 @@ class SymbolProvider {
5353
def.name, utils_2.symbolSignature(def), mapSymbolKind(def.kind),
5454
RangeOf(def.range), RangeOf(def.location),
5555
def.children
56-
? forall(def.children)
56+
? collectAllChildren(def.children)
5757
: (is.luaTable(typeOf(def))
58-
? forall(utils_1.object2Array(def.type.fields))
58+
? collectAllChildren(utils_1.object2Array(def.type.fields))
5959
: void 0)
6060
);
6161

6262
collection.push(symbol);
6363
depth--;
6464
}
6565

66-
forall = (children) => {
66+
collectAllChildren = (children) => {
6767
const collection = [];
6868
children.forEach(child => {
6969
walker(child, collection);
7070
});
7171
return collection;
7272
}
7373

74-
let symbols = forall(mdl.children);
74+
let symbols = collectAllChildren(mdl.children);
7575
return symbols;
7676
}
7777
};

stdlibs/5_1.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,11 @@
549549
"type": "table",
550550
"displayName": "metatable: table"
551551
}
552+
],
553+
"returnTypes": [
554+
{
555+
"type": "table"
556+
}
552557
]
553558
},
554559
"tonumber": {

0 commit comments

Comments
 (0)