mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-23 01:48:18 +00:00
add support for displaying method signatures
This commit is contained in:
@@ -853,7 +853,7 @@ function enumValueList(type, tokens, imports, typemap) {
|
|||||||
let ctr_args = [];
|
let ctr_args = [];
|
||||||
if (tokens.isValue('(')) {
|
if (tokens.isValue('(')) {
|
||||||
if (!tokens.isValue(')')) {
|
if (!tokens.isValue(')')) {
|
||||||
ctr_args = expressionList(tokens, new MethodDeclarations(), type, imports, typemap);
|
({ expressions: ctr_args } = expressionList(tokens, new MethodDeclarations(), type, imports, typemap));
|
||||||
tokens.expectValue(')');
|
tokens.expectValue(')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1073,7 +1073,7 @@ function forStatement(s, tokens, mdecls, method, imports, typemap) {
|
|||||||
}
|
}
|
||||||
// for-updated
|
// for-updated
|
||||||
if (!tokens.isValue(')')) {
|
if (!tokens.isValue(')')) {
|
||||||
s.update = expressionList(tokens, mdecls, method, imports, typemap);
|
({ expressions: s.update } = expressionList(tokens, mdecls, method, imports, typemap));
|
||||||
tokens.expectValue(')');
|
tokens.expectValue(')');
|
||||||
}
|
}
|
||||||
s.statement = statement(tokens, mdecls, method, imports, typemap);
|
s.statement = statement(tokens, mdecls, method, imports, typemap);
|
||||||
@@ -1574,7 +1574,7 @@ function rootTerm(tokens, mdecls, scope, imports, typemap) {
|
|||||||
let elements = [], open = tokens.current;
|
let elements = [], open = tokens.current;
|
||||||
tokens.expectValue('{');
|
tokens.expectValue('{');
|
||||||
if (!tokens.isValue('}')) {
|
if (!tokens.isValue('}')) {
|
||||||
elements = expressionList(tokens, mdecls, scope, imports, typemap, { isArrayLiteral:true });
|
({ expressions: elements } = expressionList(tokens, mdecls, scope, imports, typemap, { isArrayLiteral:true }));
|
||||||
tokens.expectValue('}');
|
tokens.expectValue('}');
|
||||||
}
|
}
|
||||||
const ident = `{${elements.map(e => e.source).join(',')}}`;
|
const ident = `{${elements.map(e => e.source).join(',')}}`;
|
||||||
@@ -1614,7 +1614,7 @@ function newTerm(tokens, mdecls, scope, imports, typemap) {
|
|||||||
case '(':
|
case '(':
|
||||||
tokens.inc();
|
tokens.inc();
|
||||||
if (!tokens.isValue(')')) {
|
if (!tokens.isValue(')')) {
|
||||||
ctr_args = expressionList(tokens, mdecls, scope, imports, typemap);
|
({ expressions: ctr_args } = expressionList(tokens, mdecls, scope, imports, typemap));
|
||||||
tokens.expectValue(')');
|
tokens.expectValue(')');
|
||||||
}
|
}
|
||||||
newtokens = tokens.markEnd();
|
newtokens = tokens.markEnd();
|
||||||
@@ -1643,9 +1643,12 @@ function newTerm(tokens, mdecls, scope, imports, typemap) {
|
|||||||
function expressionList(tokens, mdecls, scope, imports, typemap, opts) {
|
function expressionList(tokens, mdecls, scope, imports, typemap, opts) {
|
||||||
let e = expression(tokens, mdecls, scope, imports, typemap);
|
let e = expression(tokens, mdecls, scope, imports, typemap);
|
||||||
const expressions = [e];
|
const expressions = [e];
|
||||||
while (tokens.isValue(',')) {
|
const commas = [];
|
||||||
|
while (tokens.current.value === ',') {
|
||||||
|
commas.push(tokens.consume());
|
||||||
if (opts && opts.isArrayLiteral) {
|
if (opts && opts.isArrayLiteral) {
|
||||||
// array literals are allowed a single trailing comma
|
// array literals are allowed a single trailing comma
|
||||||
|
// @ts-ignore
|
||||||
if (tokens.current.value === '}') {
|
if (tokens.current.value === '}') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1653,7 +1656,7 @@ function expressionList(tokens, mdecls, scope, imports, typemap, opts) {
|
|||||||
e = expression(tokens, mdecls, scope, imports, typemap);
|
e = expression(tokens, mdecls, scope, imports, typemap);
|
||||||
expressions.push(e);
|
expressions.push(e);
|
||||||
}
|
}
|
||||||
return expressions;
|
return { expressions, commas };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1771,14 +1774,14 @@ function arrayQualifiers(matches, tokens, mdecls, scope, imports, typemap) {
|
|||||||
* @param {Map<string,CEIType>} typemap
|
* @param {Map<string,CEIType>} typemap
|
||||||
*/
|
*/
|
||||||
function methodCallQualifier(matches, tokens, mdecls, scope, imports, typemap) {
|
function methodCallQualifier(matches, tokens, mdecls, scope, imports, typemap) {
|
||||||
let args = [];
|
let args = [], commas = [];
|
||||||
tokens.mark();
|
tokens.mark();
|
||||||
tokens.expectValue('(');
|
const open_bracket = tokens.consume();
|
||||||
if (!tokens.isValue(')')) {
|
if (!tokens.isValue(')')) {
|
||||||
args = expressionList(tokens, mdecls, scope, imports, typemap);
|
({ expressions: args, commas } = expressionList(tokens, mdecls, scope, imports, typemap));
|
||||||
tokens.expectValue(')');
|
tokens.expectValue(')');
|
||||||
}
|
}
|
||||||
return new ResolvedIdent(`${matches.source}(${args.map(a => a.source).join(', ')})`, [new MethodCallExpression(matches, args)], [], [], '', [...matches.tokens, ...tokens.markEnd()]);
|
return new ResolvedIdent(`${matches.source}(${args.map(a => a.source).join(', ')})`, [new MethodCallExpression(matches, open_bracket, args, commas)], [], [], '', [...matches.tokens, ...tokens.markEnd()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,12 +16,16 @@ const { SourceConstructor } = require('../source-types');
|
|||||||
class MethodCallExpression extends Expression {
|
class MethodCallExpression extends Expression {
|
||||||
/**
|
/**
|
||||||
* @param {ResolvedIdent} instance
|
* @param {ResolvedIdent} instance
|
||||||
|
* @param {Token} open_bracket
|
||||||
* @param {ResolvedIdent[]} args
|
* @param {ResolvedIdent[]} args
|
||||||
|
* @param {Token[]} commas
|
||||||
*/
|
*/
|
||||||
constructor(instance, args) {
|
constructor(instance, open_bracket, args, commas) {
|
||||||
super();
|
super();
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
|
this.open_bracket = open_bracket;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
this.commas = commas;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,14 +48,14 @@ class MethodCallExpression extends Expression {
|
|||||||
is_ctr = ri.method instanceof SourceConstructor;
|
is_ctr = ri.method instanceof SourceConstructor;
|
||||||
}
|
}
|
||||||
if (is_ctr) {
|
if (is_ctr) {
|
||||||
resolveConstructorCall(ri, type.constructors, this.args, () => this.instance.tokens);
|
resolveConstructorCall(ri, type.constructors, this.open_bracket, this.args, this.commas, () => this.instance.tokens);
|
||||||
} else {
|
} else {
|
||||||
ri.problems.push(ParseProblem.Error(this.instance.tokens, `'this'/'super' constructor calls can only be used as the first statement of a constructor`));
|
ri.problems.push(ParseProblem.Error(this.instance.tokens, `'this'/'super' constructor calls can only be used as the first statement of a constructor`));
|
||||||
}
|
}
|
||||||
return PrimitiveType.map.V;
|
return PrimitiveType.map.V;
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolveMethodCall(ri, type.methods, this.args, () => this.instance.tokens);
|
return resolveMethodCall(ri, type.methods, this.open_bracket, this.args, this.commas, () => this.instance.tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens() {
|
tokens() {
|
||||||
@@ -62,11 +66,13 @@ class MethodCallExpression extends Expression {
|
|||||||
/**
|
/**
|
||||||
* @param {ResolveInfo} ri
|
* @param {ResolveInfo} ri
|
||||||
* @param {Method[]} methods
|
* @param {Method[]} methods
|
||||||
|
* @param {Token} open_bracket
|
||||||
* @param {ResolvedIdent[]} args
|
* @param {ResolvedIdent[]} args
|
||||||
|
* @param {Token[]} commas
|
||||||
* @param {() => Token[]} tokens
|
* @param {() => Token[]} tokens
|
||||||
*/
|
*/
|
||||||
function resolveMethodCall(ri, methods, args, tokens) {
|
function resolveMethodCall(ri, methods, open_bracket, args, commas, tokens) {
|
||||||
const resolved_args = args.map(arg => arg.resolveExpression(ri));
|
const resolved_args = args.map((arg,idx) => arg.resolveExpression(ri));
|
||||||
|
|
||||||
// all the arguments must be typed expressions, number literals or lambdas
|
// all the arguments must be typed expressions, number literals or lambdas
|
||||||
/** @type {(JavaType|NumberLiteral|LambdaType|MultiValueType)[]} */
|
/** @type {(JavaType|NumberLiteral|LambdaType|MultiValueType)[]} */
|
||||||
@@ -100,6 +106,32 @@ function resolveMethodCall(ri, methods, args, tokens) {
|
|||||||
const compatible_methods = reified_methods.filter(m => isCallCompatible(m, arg_types));
|
const compatible_methods = reified_methods.filter(m => isCallCompatible(m, arg_types));
|
||||||
const return_types = new Set(compatible_methods.map(m => m.returnType));
|
const return_types = new Set(compatible_methods.map(m => m.returnType));
|
||||||
|
|
||||||
|
// store the methods and argument position for signature help
|
||||||
|
const methodIdx = Math.max(reified_methods.indexOf(compatible_methods[0]), 0);
|
||||||
|
open_bracket.methodCallInfo = {
|
||||||
|
methods: reified_methods,
|
||||||
|
methodIdx,
|
||||||
|
argIdx: 0,
|
||||||
|
}
|
||||||
|
args.forEach((arg, idx) => {
|
||||||
|
const methodCallInfo = {
|
||||||
|
methods: reified_methods,
|
||||||
|
methodIdx,
|
||||||
|
argIdx: idx,
|
||||||
|
}
|
||||||
|
// add the info to the previous comma
|
||||||
|
const c = commas[idx-1];
|
||||||
|
if (c) {
|
||||||
|
c.methodCallInfo = methodCallInfo;
|
||||||
|
}
|
||||||
|
// set the info on all the tokens used in the argument
|
||||||
|
arg.tokens.forEach(tok => {
|
||||||
|
if (tok.methodCallInfo === null) {
|
||||||
|
tok.methodCallInfo = methodCallInfo;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
if (!compatible_methods[0]) {
|
if (!compatible_methods[0]) {
|
||||||
// if any of the arguments is AnyType, just return AnyType
|
// if any of the arguments is AnyType, just return AnyType
|
||||||
if (arg_java_types.find(t => t instanceof AnyType)) {
|
if (arg_java_types.find(t => t instanceof AnyType)) {
|
||||||
@@ -142,10 +174,12 @@ function resolveMethodCall(ri, methods, args, tokens) {
|
|||||||
/**
|
/**
|
||||||
* @param {ResolveInfo} ri
|
* @param {ResolveInfo} ri
|
||||||
* @param {Constructor[]} constructors
|
* @param {Constructor[]} constructors
|
||||||
|
* @param {Token} open_bracket
|
||||||
* @param {ResolvedIdent[]} args
|
* @param {ResolvedIdent[]} args
|
||||||
|
* @param {Token[]} commas
|
||||||
* @param {() => Token[]} tokens
|
* @param {() => Token[]} tokens
|
||||||
*/
|
*/
|
||||||
function resolveConstructorCall(ri, constructors, args, tokens) {
|
function resolveConstructorCall(ri, constructors, open_bracket, args, commas, tokens) {
|
||||||
const resolved_args = args.map(arg => arg.resolveExpression(ri));
|
const resolved_args = args.map(arg => arg.resolveExpression(ri));
|
||||||
|
|
||||||
// all the arguments must be typed expressions, number literals or lambdas
|
// all the arguments must be typed expressions, number literals or lambdas
|
||||||
@@ -177,6 +211,32 @@ function resolveConstructorCall(ri, constructors, args, tokens) {
|
|||||||
// work out which methods are compatible with the call arguments
|
// work out which methods are compatible with the call arguments
|
||||||
const compatible_ctrs = reifed_ctrs.filter(m => isCallCompatible(m, arg_types));
|
const compatible_ctrs = reifed_ctrs.filter(m => isCallCompatible(m, arg_types));
|
||||||
|
|
||||||
|
// store the methods and argument position for signature help
|
||||||
|
const methodIdx = reifed_ctrs.indexOf(compatible_ctrs[0]);
|
||||||
|
open_bracket.methodCallInfo = {
|
||||||
|
methods: reifed_ctrs,
|
||||||
|
methodIdx,
|
||||||
|
argIdx: 0,
|
||||||
|
}
|
||||||
|
args.forEach((arg, idx) => {
|
||||||
|
const methodCallInfo = {
|
||||||
|
methods: reifed_ctrs,
|
||||||
|
methodIdx,
|
||||||
|
argIdx: idx,
|
||||||
|
}
|
||||||
|
// add the info to the previous comma
|
||||||
|
const c = commas[idx-1];
|
||||||
|
if (c) {
|
||||||
|
c.methodCallInfo = methodCallInfo;
|
||||||
|
}
|
||||||
|
// set the info on all the tokens used in the argument
|
||||||
|
arg.tokens.forEach(tok => {
|
||||||
|
if (tok.methodCallInfo === null) {
|
||||||
|
tok.methodCallInfo = methodCallInfo;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
if (!compatible_ctrs[0]) {
|
if (!compatible_ctrs[0]) {
|
||||||
// if any of the arguments is AnyType, just ignore the call
|
// if any of the arguments is AnyType, just ignore the call
|
||||||
if (arg_java_types.find(t => t instanceof AnyType)) {
|
if (arg_java_types.find(t => t instanceof AnyType)) {
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @typedef {import('java-mti').Method} Method
|
||||||
|
* @typedef {import('java-mti').Constructor} Constructor
|
||||||
|
*/
|
||||||
const { TextBlock, BlockRange } = require('./parsetypes/textblock');
|
const { TextBlock, BlockRange } = require('./parsetypes/textblock');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,6 +55,13 @@ class Token extends TextBlock {
|
|||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
/** @type {{key:string}} */
|
/** @type {{key:string}} */
|
||||||
this.loc = null;
|
this.loc = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores information about the resolved methods/constructors this token is an argument for.
|
||||||
|
* This is used to provide method signature info to vscode
|
||||||
|
* @type {{methods:(Method|Constructor)[], methodIdx:number, argIdx:number}}
|
||||||
|
*/
|
||||||
|
this.methodCallInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get value() {
|
get value() {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const {
|
|||||||
|
|
||||||
const { TextDocument } = require('vscode-languageserver-textdocument');
|
const { TextDocument } = require('vscode-languageserver-textdocument');
|
||||||
|
|
||||||
const { loadAndroidLibrary, JavaType, CEIType, ArrayType, PrimitiveType } = require('java-mti');
|
const { loadAndroidLibrary, JavaType, CEIType, ArrayType, PrimitiveType, Method } = require('java-mti');
|
||||||
|
|
||||||
const { ParseProblem } = require('./java/parser');
|
const { ParseProblem } = require('./java/parser');
|
||||||
const { parse } = require('./java/body-parser3');
|
const { parse } = require('./java/body-parser3');
|
||||||
@@ -231,6 +231,10 @@ connection.onInitialize((params) => {
|
|||||||
completionProvider: {
|
completionProvider: {
|
||||||
resolveProvider: true,
|
resolveProvider: true,
|
||||||
},
|
},
|
||||||
|
// Tell the client that the server supports method signature information
|
||||||
|
signatureHelpProvider : {
|
||||||
|
triggerCharacters: [ '(' ]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -758,15 +762,15 @@ connection.onCompletion(
|
|||||||
return getPackageCompletion(parsed.typemap, options.loc.key.split(':').pop());
|
return getPackageCompletion(parsed.typemap, options.loc.key.split(':').pop());
|
||||||
}
|
}
|
||||||
if (/^fqdi:/.test(options.loc.key)) {
|
if (/^fqdi:/.test(options.loc.key)) {
|
||||||
// fully-qualified type/field name
|
// fully-qualified dotted identifier
|
||||||
return getFullyQualifiedDottedIdentCompletion(parsed.typemap, options.loc.key.split(':').pop(), { statics: true });
|
return getFullyQualifiedDottedIdentCompletion(parsed.typemap, options.loc.key.split(':').pop(), { statics: true });
|
||||||
}
|
}
|
||||||
if (/^fqs:/.test(options.loc.key)) {
|
if (/^fqs:/.test(options.loc.key)) {
|
||||||
// fully-qualified expression
|
// fully-qualified static expression
|
||||||
return getTypedNameCompletion(parsed.typemap, options.loc.key.split(':').pop(), { statics: true });
|
return getTypedNameCompletion(parsed.typemap, options.loc.key.split(':').pop(), { statics: true });
|
||||||
}
|
}
|
||||||
if (/^fqi:/.test(options.loc.key)) {
|
if (/^fqi:/.test(options.loc.key)) {
|
||||||
// fully-qualified expression
|
// fully-qualified instance expression
|
||||||
return getTypedNameCompletion(parsed.typemap, options.loc.key.split(':').pop(), { statics: false });
|
return getTypedNameCompletion(parsed.typemap, options.loc.key.split(':').pop(), { statics: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -851,9 +855,23 @@ connection.onCompletionResolve(
|
|||||||
header = `${t.typeKind} **${t.dottedTypeName}**`;
|
header = `${t.typeKind} **${t.dottedTypeName}**`;
|
||||||
}
|
}
|
||||||
item.detail = detail || '';
|
item.detail = detail || '';
|
||||||
item.documentation = documentation && {
|
item.documentation = formatDoc(header, documentation);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} header
|
||||||
|
* @param {string} documentation
|
||||||
|
* @returns {import('vscode-languageserver').MarkupContent}
|
||||||
|
*/
|
||||||
|
function formatDoc(header, documentation) {
|
||||||
|
if (!documentation) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
kind: 'markdown',
|
kind: 'markdown',
|
||||||
value: `${header}\n\n${
|
value: `${header ? header + '\n\n' : ''}${
|
||||||
documentation
|
documentation
|
||||||
.replace(/(^\/\*+|(?<=\n)[ \t]*\*+\/?|\*+\/)/gm, '')
|
.replace(/(^\/\*+|(?<=\n)[ \t]*\*+\/?|\*+\/)/gm, '')
|
||||||
.replace(/(\n[ \t]*@[a-z]+)|(<p(?: .*)?>)|(<\/?i>|<\/?em>)|(<\/?b>|<\/?strong>|<\/?dt>)|(<\/?tt>)|(<\/?code>|<\/?pre>|<\/?blockquote>)|(\{@link.+?\}|\{@code.+?\})|(<li>)|(<a href="\{@docRoot\}.*?">.+?<\/a>)|(<h\d>)|<\/?dd ?.*?>|<\/p ?.*?>|<\/h\d ?.*?>|<\/?div ?.*?>|<\/?[uo]l ?.*?>/gim, (_,prm,p,i,b,tt,c,lc,li,a,h) => {
|
.replace(/(\n[ \t]*@[a-z]+)|(<p(?: .*)?>)|(<\/?i>|<\/?em>)|(<\/?b>|<\/?strong>|<\/?dt>)|(<\/?tt>)|(<\/?code>|<\/?pre>|<\/?blockquote>)|(\{@link.+?\}|\{@code.+?\})|(<li>)|(<a href="\{@docRoot\}.*?">.+?<\/a>)|(<h\d>)|<\/?dd ?.*?>|<\/p ?.*?>|<\/h\d ?.*?>|<\/?div ?.*?>|<\/?[uo]l ?.*?>/gim, (_,prm,p,i,b,tt,c,lc,li,a,h) => {
|
||||||
@@ -871,9 +889,64 @@ connection.onCompletionResolve(
|
|||||||
})
|
})
|
||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
/**
|
||||||
|
* @param {import('vscode-languageserver').SignatureHelpParams} request the reeust
|
||||||
|
*/
|
||||||
|
async function onSignatureHelp(request) {
|
||||||
|
/** @type {import('vscode-languageserver').SignatureHelp} */
|
||||||
|
let sighelp = {
|
||||||
|
signatures: [],
|
||||||
|
activeSignature: 0,
|
||||||
|
activeParameter: 0,
|
||||||
|
}
|
||||||
|
const docinfo = liveParsers.get(request.textDocument.uri);
|
||||||
|
if (!docinfo || !docinfo.parsed) {
|
||||||
|
return sighelp;
|
||||||
|
}
|
||||||
|
const index = indexAt(request.position, docinfo.content);
|
||||||
|
const token = docinfo.parsed.unit.getTokenAt(index);
|
||||||
|
if (!token || !token.methodCallInfo) {
|
||||||
|
return sighelp;
|
||||||
|
}
|
||||||
|
sighelp = {
|
||||||
|
signatures: token.methodCallInfo.methods.map(m => {
|
||||||
|
/** @type {import('vscode-languageserver').SignatureInformation} */
|
||||||
|
let si = {
|
||||||
|
label: m.label,
|
||||||
|
documentation: formatDoc(`#### ${m.owner.simpleTypeName}${m instanceof Method ? `.${m.name}` : ''}()`, m.docs),
|
||||||
|
parameters: m.parameters.map(p => {
|
||||||
|
/** @type {import('vscode-languageserver').MarkupContent} */
|
||||||
|
let param_documentation = null;
|
||||||
|
// include a space at the end of the search string so we don't inadvertently match substring parameters, eg: method(type, typeName)
|
||||||
|
const param_doc_offset = m.docs.indexOf(`@param ${p.name} `);
|
||||||
|
if (param_doc_offset > 0) {
|
||||||
|
const doc_match = m.docs.slice(param_doc_offset).match(/@param (\S+)([\d\D]+?)(\n\n|\n[ \t*]*@\w+|$)/);
|
||||||
|
if (doc_match) {
|
||||||
|
param_documentation = {
|
||||||
|
kind:'markdown',
|
||||||
|
value: `**${doc_match[1]}**: ${formatDoc('', doc_match[2].trim()).value}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** @type {import('vscode-languageserver').ParameterInformation} */
|
||||||
|
let pi = {
|
||||||
|
documentation: param_documentation,
|
||||||
|
label: p.label
|
||||||
|
}
|
||||||
|
return pi;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return si;
|
||||||
|
}),
|
||||||
|
activeSignature: token.methodCallInfo.methodIdx,
|
||||||
|
activeParameter: token.methodCallInfo.argIdx,
|
||||||
|
}
|
||||||
|
return sighelp;
|
||||||
|
|
||||||
|
}
|
||||||
|
connection.onSignatureHelp(onSignatureHelp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
connection.onDidOpenTextDocument((params) => {
|
connection.onDidOpenTextDocument((params) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user