use of org.eclipse.jdt.ls.core.internal.contentassist.SnippetCompletionProposal in project eclipse.jdt.ls by eclipse.
the class CompletionResolveHandler method resolve.
public CompletionItem resolve(CompletionItem param, IProgressMonitor monitor) {
@SuppressWarnings("unchecked") Map<String, String> data = JSONUtility.toModel(param.getData(), Map.class);
// clean resolve data
param.setData(null);
if (!CompletionProposalRequestor.SUPPORTED_KINDS.contains(param.getKind()) || data == null || !data.containsKey(DATA_FIELD_URI) || !data.containsKey(DATA_FIELD_REQUEST_ID) || !data.containsKey(DATA_FIELD_PROPOSAL_ID)) {
return param;
}
int proposalId = Integer.parseInt(data.get(DATA_FIELD_PROPOSAL_ID));
long requestId = Long.parseLong(data.get(DATA_FIELD_REQUEST_ID));
CompletionResponse completionResponse = CompletionResponses.get(requestId);
if (completionResponse == null || completionResponse.getProposals().size() <= proposalId) {
throw new IllegalStateException("Invalid completion proposal");
}
String uri = data.get(DATA_FIELD_URI);
ICompilationUnit unit = JDTUtils.resolveCompilationUnit(uri);
if (unit == null) {
throw new IllegalStateException(NLS.bind("Unable to match Compilation Unit from {0} ", uri));
}
if (monitor.isCanceled()) {
param.setData(null);
return param;
}
// generic snippets
if (param.getKind() == CompletionItemKind.Snippet) {
try {
CompletionContext ctx = completionResponse.getContext();
CompletionProposal proposal = completionResponse.getProposals().get(proposalId);
Template template = ((SnippetCompletionProposal) proposal).getTemplate();
String content = SnippetCompletionProposal.evaluateGenericTemplate(unit, ctx, template);
Range range = JDTUtils.toRange(unit, ctx.getOffset(), 0);
TextEdit textEdit = new TextEdit(range, content);
param.setTextEdit(Either.forLeft(textEdit));
param.setDocumentation(SnippetUtils.beautifyDocument(content));
param.setData(null);
} catch (JavaModelException e) {
JavaLanguageServerPlugin.logException(e.getMessage(), e);
}
return param;
}
if (manager.getClientPreferences().isResolveAdditionalTextEditsSupport()) {
CompletionProposalReplacementProvider proposalProvider = new CompletionProposalReplacementProvider(unit, completionResponse.getContext(), completionResponse.getOffset(), manager.getPreferences(), manager.getClientPreferences());
proposalProvider.updateAdditionalTextEdits(completionResponse.getProposals().get(proposalId), param, '\0');
}
if (data.containsKey(DATA_FIELD_DECLARATION_SIGNATURE)) {
String typeName = stripSignatureToFQN(String.valueOf(data.get(DATA_FIELD_DECLARATION_SIGNATURE)));
try {
IMember member = null;
IType type = unit.getJavaProject().findType(typeName);
CompletionProposal proposal = completionResponse.getProposals().get(proposalId);
if (type != null && data.containsKey(DATA_FIELD_NAME)) {
String name = data.get(DATA_FIELD_NAME);
String[] paramSigs = CharOperation.NO_STRINGS;
if (data.containsKey(DATA_FIELD_SIGNATURE)) {
if (proposal instanceof InternalCompletionProposal) {
Binding binding = ((InternalCompletionProposal) proposal).getBinding();
if (binding instanceof MethodBinding) {
MethodBinding methodBinding = (MethodBinding) binding;
MethodBinding original = methodBinding.original();
char[] signature;
if (original != binding) {
signature = Engine.getSignature(original);
} else {
signature = Engine.getSignature(methodBinding);
}
String[] parameters = Signature.getParameterTypes(String.valueOf(fix83600(signature)));
for (int i = 0; i < parameters.length; i++) {
parameters[i] = getLowerBound(parameters[i]);
}
paramSigs = parameters;
}
}
}
IMethod method = type.getMethod(name, paramSigs);
IMethod[] methods = type.findMethods(method);
if (methods != null && methods.length > 0) {
method = methods[0];
}
if (method.exists()) {
member = method;
} else {
IField field = type.getField(name);
if (field.exists()) {
member = field;
}
}
} else {
member = type;
}
if (member != null && member.exists() && !monitor.isCanceled()) {
String javadoc = null;
try {
final IMember curMember = member;
javadoc = SimpleTimeLimiter.create(Executors.newCachedThreadPool()).callWithTimeout(() -> {
Reader reader;
if (manager.getClientPreferences().isSupportsCompletionDocumentationMarkdown()) {
reader = JavadocContentAccess2.getMarkdownContentReader(curMember);
} else {
reader = JavadocContentAccess.getPlainTextContentReader(curMember);
}
return reader == null ? null : CharStreams.toString(reader);
}, 500, TimeUnit.MILLISECONDS);
} catch (UncheckedTimeoutException | TimeoutException tooSlow) {
// Ignore error for now as it's spamming clients on content assist.
// TODO cache javadoc resolution results?
// JavaLanguageServerPlugin.logError("Unable to get documentation under 500ms");
monitor.setCanceled(true);
} catch (Exception e) {
JavaLanguageServerPlugin.logException("Unable to read documentation", e);
monitor.setCanceled(true);
}
String constantValue = null;
if (proposal.getKind() == CompletionProposal.FIELD_REF) {
try {
IField field = JDTUtils.resolveField(proposal, unit.getJavaProject());
Region nameRegion = null;
if (field != null) {
ITypeRoot typeRoot = field.getTypeRoot();
ISourceRange nameRange = ((ISourceReference) field).getNameRange();
if (SourceRange.isAvailable(nameRange)) {
nameRegion = new Region(nameRange.getOffset(), nameRange.getLength());
}
constantValue = JDTUtils.getConstantValue(field, typeRoot, nameRegion);
}
} catch (JavaModelException e) {
JavaLanguageServerPlugin.log(e);
}
}
if (constantValue != null) {
if (manager.getClientPreferences().isSupportsCompletionDocumentationMarkdown()) {
javadoc = (javadoc == null ? EMPTY_STRING : javadoc) + "\n\n" + VALUE + constantValue;
} else {
javadoc = (javadoc == null ? EMPTY_STRING : javadoc) + VALUE + constantValue;
}
}
String defaultValue = null;
if (proposal.getKind() == CompletionProposal.METHOD_REF || proposal.getKind() == CompletionProposal.ANNOTATION_ATTRIBUTE_REF) {
try {
IMethod method = JDTUtils.resolveMethod(proposal, unit.getJavaProject());
Region nameRegion = null;
if (method != null) {
ITypeRoot typeRoot = method.getTypeRoot();
ISourceRange nameRange = ((ISourceReference) method).getNameRange();
if (SourceRange.isAvailable(nameRange)) {
nameRegion = new Region(nameRange.getOffset(), nameRange.getLength());
}
defaultValue = JDTUtils.getAnnotationMemberDefaultValue(method, typeRoot, nameRegion);
}
} catch (JavaModelException e) {
JavaLanguageServerPlugin.log(e);
}
}
if (defaultValue != null) {
if (manager.getClientPreferences().isSupportsCompletionDocumentationMarkdown()) {
javadoc = (javadoc == null ? EMPTY_STRING : javadoc) + "\n\n" + DEFAULT + defaultValue;
} else {
javadoc = (javadoc == null ? EMPTY_STRING : javadoc) + DEFAULT + defaultValue;
}
}
if (javadoc != null) {
if (manager.getClientPreferences().isSupportsCompletionDocumentationMarkdown()) {
MarkupContent markupContent = new MarkupContent();
markupContent.setKind(MarkupKind.MARKDOWN);
markupContent.setValue(javadoc);
param.setDocumentation(markupContent);
} else {
param.setDocumentation(javadoc);
}
}
}
} catch (JavaModelException e) {
JavaLanguageServerPlugin.logException("Unable to resolve compilation", e);
monitor.setCanceled(true);
}
}
if (monitor.isCanceled()) {
param.setData(null);
}
return param;
}
Aggregations