|
@@ -93,6 +93,67 @@ const completionFunction = (suggestions, input) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+const completionMethod = async (className, suggestions) => {
|
|
|
+ let clazz = await JavaClass.loadClass(className)
|
|
|
+ let index = className.lastIndexOf('.')
|
|
|
+ let simpleName = index > 0 ? className.substring(index + 1) : className
|
|
|
+ let enums = JavaClass.findEnums(clazz);
|
|
|
+ if (enums) {
|
|
|
+ for (let j = 0; j < enums.length; j++) {
|
|
|
+ let value = enums[j];
|
|
|
+ suggestions.push({
|
|
|
+ label: value,
|
|
|
+ kind: monaco.languages.CompletionItemKind.Enum,
|
|
|
+ detail: value + ":" + value,
|
|
|
+ insertText: value,
|
|
|
+ sortText: ' ~~~' + value
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let attributes = JavaClass.findAttributes(clazz);
|
|
|
+ if (attributes) {
|
|
|
+ for (let j = 0; j < attributes.length; j++) {
|
|
|
+ let attribute = attributes[j];
|
|
|
+ suggestions.push({
|
|
|
+ label: attribute.name,
|
|
|
+ kind: monaco.languages.CompletionItemKind.Field,
|
|
|
+ detail: attribute.comment || (attribute.type + ":" + attribute.name),
|
|
|
+ insertText: attribute.name,
|
|
|
+ sortText: ' ~~' + attribute.name
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let methods = JavaClass.findMethods(clazz);
|
|
|
+ if (methods) {
|
|
|
+ let mmap = {};
|
|
|
+ for (let j = 0; j < methods.length; j++) {
|
|
|
+ let method = methods[j];
|
|
|
+ if (mmap[method.signature]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ mmap[method.signature] = true;
|
|
|
+ let document = [];
|
|
|
+ for (let j = (method.extension ? 1 : 0); j < method.parameters.length; j++) {
|
|
|
+ let param = method.parameters[j];
|
|
|
+ document.push('`' + param.name + '` ' + (param.comment || param.type));
|
|
|
+ document.push('\r\n')
|
|
|
+ }
|
|
|
+ method.comment && document.push('\r\n') && document.push(method.comment)
|
|
|
+ suggestions.push({
|
|
|
+ sortText: method.sortText || method.fullName,
|
|
|
+ label: method.fullName,
|
|
|
+ kind: monaco.languages.CompletionItemKind.Method,
|
|
|
+ detail: `${simpleName}.${method.fullName}: ${method.returnType}`,
|
|
|
+ documentation: {
|
|
|
+ value: document.join('\r\n')
|
|
|
+ },
|
|
|
+ insertText: method.insertText,
|
|
|
+ insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
async function completionScript(suggestions, input) {
|
|
|
try {
|
|
|
let tokens = tokenizer(input);
|
|
@@ -100,82 +161,19 @@ async function completionScript(suggestions, input) {
|
|
|
if (tokenLen === 0) {
|
|
|
return;
|
|
|
}
|
|
|
- let tokenType = tokens[tokenLen - 1].getTokenType();
|
|
|
- if (tokenType === TokenType.Identifier) {
|
|
|
- if (tokenLen === 1) {
|
|
|
- completionFunction(suggestions, input);
|
|
|
- return;
|
|
|
- }
|
|
|
- tokenType = tokens[tokenLen - 2].getTokenType();
|
|
|
- tokens.pop();
|
|
|
- }
|
|
|
- if (tokenType === TokenType.Period) {
|
|
|
- tokens.pop();
|
|
|
- } else {
|
|
|
- completionFunction(suggestions, input);
|
|
|
- return;
|
|
|
- }
|
|
|
let parser = new Parser(new TokenStream(tokens));
|
|
|
- let clazz = await parser.completion(RequestParameter.environmentFunction());
|
|
|
- if (clazz) {
|
|
|
- let enums = JavaClass.findEnums(clazz);
|
|
|
- if (enums) {
|
|
|
- for (let j = 0; j < enums.length; j++) {
|
|
|
- let value = enums[j];
|
|
|
- suggestions.push({
|
|
|
- label: value,
|
|
|
- kind: monaco.languages.CompletionItemKind.Enum,
|
|
|
- detail: value + ":" + value,
|
|
|
- insertText: value,
|
|
|
- sortText: ' ~~~' + value
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- let attributes = JavaClass.findAttributes(clazz);
|
|
|
- if (attributes) {
|
|
|
- for (let j = 0; j < attributes.length; j++) {
|
|
|
- let attribute = attributes[j];
|
|
|
- suggestions.push({
|
|
|
- label: attribute.name,
|
|
|
- kind: monaco.languages.CompletionItemKind.Field,
|
|
|
- detail: attribute.comment || (attribute.type + ":" + attribute.name),
|
|
|
- insertText: attribute.name,
|
|
|
- sortText: ' ~~' + attribute.name
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- let methods = JavaClass.findMethods(clazz);
|
|
|
- if (methods) {
|
|
|
- let mmap = {};
|
|
|
- for (let j = 0; j < methods.length; j++) {
|
|
|
- let method = methods[j];
|
|
|
- if (mmap[method.signature]) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- mmap[method.signature] = true;
|
|
|
- let document = [];
|
|
|
- for (let j = (method.extension ? 1 : 0); j < method.parameters.length; j++) {
|
|
|
- let param = method.parameters[j];
|
|
|
- document.push('- ' + param.name + ':' + (param.comment || param.type));
|
|
|
- document.push('---')
|
|
|
- }
|
|
|
- document.push(`- 返回值:\`${method.returnType}\``)
|
|
|
- suggestions.push({
|
|
|
- sortText: method.sortText || method.fullName,
|
|
|
- label: method.fullName,
|
|
|
- kind: monaco.languages.CompletionItemKind.Method,
|
|
|
- detail: method.comment,
|
|
|
- documentation: {
|
|
|
- value: document.join('\r\n')
|
|
|
- },
|
|
|
- insertText: method.insertText,
|
|
|
- insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
|
|
- })
|
|
|
- }
|
|
|
+ const { best, env } = await parser.parseBest(input.length - 1, env);
|
|
|
+ if(input.endsWith(".")){
|
|
|
+ await completionMethod(await best.getJavaType(env), suggestions)
|
|
|
+ } else {
|
|
|
+ let astName = best.constructor.name;
|
|
|
+ if (astName === 'MemberAccess' || astName === 'MethodCall') {
|
|
|
+ await completionMethod(await best.target.getJavaType(env), suggestions)
|
|
|
}
|
|
|
}
|
|
|
+ return suggestions;
|
|
|
} catch (e) {
|
|
|
- // console.log(e);
|
|
|
+ console.error(e);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -197,18 +195,16 @@ const CompletionItemProvider = {
|
|
|
let importIndex;
|
|
|
if (line.length > 1 && (importIndex = line.trim().indexOf('import')) === 0) {
|
|
|
completionImport(suggestions, position, line, importIndex)
|
|
|
- } else if (line.endsWith(":")) {
|
|
|
- if (line.endsWith("::")) {
|
|
|
- suggestions = ['int', 'long', 'date', 'string', 'short', 'byte', 'float', 'double', 'json','stringify', 'sql'].map(it => {
|
|
|
- return {
|
|
|
- label: it,
|
|
|
- detail: `转换为${it === 'stringify' ? 'json字符串': it === 'sql' ? 'sql参数类型': it}`,
|
|
|
- insertText: it,
|
|
|
- kind: monaco.languages.CompletionItemKind.TypeParameter,
|
|
|
- insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
+ } else if (line.endsWith("::")) {
|
|
|
+ suggestions = ['int', 'long', 'date', 'string', 'short', 'byte', 'float', 'double', 'json','stringify', 'sql'].map(it => {
|
|
|
+ return {
|
|
|
+ label: it,
|
|
|
+ detail: `转换为${it === 'stringify' ? 'json字符串': it === 'sql' ? 'sql参数类型': it}`,
|
|
|
+ insertText: it,
|
|
|
+ kind: monaco.languages.CompletionItemKind.TypeParameter,
|
|
|
+ insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
|
|
+ }
|
|
|
+ })
|
|
|
} else if (value.length > 1) {
|
|
|
await completionScript(suggestions, value)
|
|
|
}
|