use of org.eclipse.lsp4j.MarkupContent 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;
}
use of org.eclipse.lsp4j.MarkupContent in project eclipse.jdt.ls by eclipse.
the class SnippetUtils method beautifyDocument.
public static Either<String, MarkupContent> beautifyDocument(String raw) {
// remove the placeholder for the plain cursor like: ${0}, ${1:variable}
String escapedString = raw.replaceAll("\\$\\{\\d:?(.*?)\\}", "$1");
// Replace the reserved variable with empty string.
// See: https://github.com/eclipse/eclipse.jdt.ls/issues/1220
escapedString = escapedString.replaceAll(TM_SELECTED_TEXT, "");
if (JavaLanguageServerPlugin.getPreferencesManager() != null && JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences() != null && JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences().isSupportsCompletionDocumentationMarkdown()) {
MarkupContent markupContent = new MarkupContent();
markupContent.setKind(MarkupKind.MARKDOWN);
markupContent.setValue(String.format("```%s\n%s\n```", MARKDOWN_LANGUAGE, escapedString));
return Either.forRight(markupContent);
} else {
return Either.forLeft(escapedString);
}
}
use of org.eclipse.lsp4j.MarkupContent in project eclipse.jdt.ls by eclipse.
the class SnippetUtilsTest method testComplicatedInput.
@Test
public void testComplicatedInput() {
ClientPreferences mockCapabilies = mock(ClientPreferences.class);
when(mockCapabilies.isSupportsCompletionDocumentationMarkdown()).thenReturn(Boolean.FALSE);
when(preferenceManager.getClientPreferences()).thenReturn(mockCapabilies);
// @formatter:off
String raw = "/**\n" + " * ${1:A}\n" + " */\n" + "public class ${1:A} {\n" + "\n" + "\t${0}\n" + "}";
// @formatter:on
Either<String, MarkupContent> result = SnippetUtils.beautifyDocument(raw);
// @formatter:off
String expected = "/**\n" + " * A\n" + " */\n" + "public class A {\n" + "\n" + "\t\n" + "}";
// @formatter:on
assertEquals(result.getLeft(), expected);
}
use of org.eclipse.lsp4j.MarkupContent in project eclipse.jdt.ls by eclipse.
the class CompletionHandlerTest method testCompletion_javadocMarkdown.
@Test
public void testCompletion_javadocMarkdown() throws Exception {
IJavaProject javaProject = JavaCore.create(project);
ClientPreferences mockCapabilies = Mockito.mock(ClientPreferences.class);
Mockito.when(preferenceManager.getClientPreferences()).thenReturn(mockCapabilies);
Mockito.when(mockCapabilies.isSupportsCompletionDocumentationMarkdown()).thenReturn(true);
ICompilationUnit unit = (ICompilationUnit) javaProject.findElement(new Path("org/sample/TestJavadoc.java"));
unit.becomeWorkingCopy(null);
String joinOnCompletion = System.getProperty(JDTLanguageServer.JAVA_LSP_JOIN_ON_COMPLETION);
try {
System.setProperty(JDTLanguageServer.JAVA_LSP_JOIN_ON_COMPLETION, "true");
int[] loc = findCompletionLocation(unit, "inner.");
CompletionParams position = JsonMessageHelper.getParams(createCompletionRequest(unit, loc[0], loc[1]));
String source = unit.getSource();
changeDocument(unit, source, 3);
Job.getJobManager().join(DocumentLifeCycleHandler.DOCUMENT_LIFE_CYCLE_JOBS, new NullProgressMonitor());
changeDocument(unit, source, 4);
CompletionList list = server.completion(position).join().getRight();
CompletionItem resolved = server.resolveCompletionItem(list.getItems().get(0)).join();
MarkupContent markup = resolved.getDocumentation().getRight();
assertNotNull(markup);
assertEquals(MarkupKind.MARKDOWN, markup.getKind());
assertEquals("Test", markup.getValue());
} finally {
unit.discardWorkingCopy();
if (joinOnCompletion == null) {
System.clearProperty(JDTLanguageServer.JAVA_LSP_JOIN_ON_COMPLETION);
} else {
System.setProperty(JDTLanguageServer.JAVA_LSP_JOIN_ON_COMPLETION, joinOnCompletion);
}
}
}
use of org.eclipse.lsp4j.MarkupContent in project xtext-core by eclipse.
the class HoverService method hover.
protected Hover hover(HoverContext context) {
if (context == null) {
return IHoverService.EMPTY_HOVER;
}
MarkupContent contents = getMarkupContent(context);
if (contents == null) {
return IHoverService.EMPTY_HOVER;
}
Range range = getRange(context);
if (range == null) {
return IHoverService.EMPTY_HOVER;
}
return new Hover(contents, range);
}
Aggregations