private DocumentHighlight convertToHighlight(ITypeRoot unit, OccurrenceLocation occurrence) throws JavaModelException { DocumentHighlight h = new DocumentHighlight(); if ((occurrence.getFlags() | IOccurrencesFinder.F_WRITE_OCCURRENCE) == IOccurrencesFinder.F_WRITE_OCCURRENCE) { h.setKind(DocumentHighlightKind.Write); } else if ((occurrence.getFlags() | IOccurrencesFinder.F_READ_OCCURRENCE) == IOccurrencesFinder.F_READ_OCCURRENCE) { h.setKind(DocumentHighlightKind.Read); } int[] loc = JsonRpcHelpers.toLine(unit.getBuffer(), occurrence.getOffset()); int[] endLoc = JsonRpcHelpers.toLine(unit.getBuffer(), occurrence.getOffset() + occurrence.getLength()); h.setRange(new Range( new Position(loc[0], loc[1]), new Position(endLoc[0],endLoc[1]) )); return h; }
@Test public void withNull() { final List<? extends DocumentHighlight> input = this.sort(CollectionLiterals.<DocumentHighlight>newArrayList(null, this.newHighlight(DocumentHighlightKind.Text, this.newRange(1, 1, 1, 1)), this.newHighlight(DocumentHighlightKind.Write, this.newRange(1, 1, 1, 1)), this.newHighlight(DocumentHighlightKind.Read, this.newRange(1, 1, 1, 1)))); Assert.assertEquals(1, input.get(0).getRange().getStart().getLine()); Assert.assertEquals(1, input.get(0).getRange().getStart().getCharacter()); Assert.assertEquals(1, input.get(0).getRange().getEnd().getLine()); Assert.assertEquals(1, input.get(0).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Text, input.get(0).getKind()); Assert.assertEquals(1, input.get(1).getRange().getStart().getLine()); Assert.assertEquals(1, input.get(1).getRange().getStart().getCharacter()); Assert.assertEquals(1, input.get(1).getRange().getEnd().getLine()); Assert.assertEquals(1, input.get(1).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Read, input.get(1).getKind()); Assert.assertEquals(1, input.get(2).getRange().getStart().getLine()); Assert.assertEquals(1, input.get(2).getRange().getStart().getCharacter()); Assert.assertEquals(1, input.get(2).getRange().getEnd().getLine()); Assert.assertEquals(1, input.get(2).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Write, input.get(2).getKind()); Assert.assertNull(IterableExtensions.last(input)); }
@Override public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(final TextDocumentPositionParams params) { final Function1<CancelIndicator, List<? extends DocumentHighlight>> _function = (CancelIndicator cancelIndicator) -> { final URI uri = this._uriExtensions.toUri(params.getTextDocument().getUri()); final IResourceServiceProvider serviceProvider = this.languagesRegistry.getResourceServiceProvider(uri); IDocumentHighlightService _get = null; if (serviceProvider!=null) { _get=serviceProvider.<IDocumentHighlightService>get(IDocumentHighlightService.class); } final IDocumentHighlightService service = _get; if ((service == null)) { return CollectionLiterals.<DocumentHighlight>emptyList(); } final Function2<Document, XtextResource, List<? extends DocumentHighlight>> _function_1 = (Document doc, XtextResource resource) -> { return service.getDocumentHighlights(doc, resource, params, cancelIndicator); }; return this.workspaceManager.<List<? extends DocumentHighlight>>doRead(uri, _function_1); }; return this.requestManager.<List<? extends DocumentHighlight>>runRead(_function); }
@Override public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight( final TextDocumentPositionParams position) { // TODO: this is wrong, it should be something entirely different. // this feature is about marking the occurrences of a selected element // like a variable, where it is used. // so, this should actually return multiple results. // The spec is currently broken for that. DocumentHighlight result = som.getHighlight(position.getTextDocument().getUri(), position.getPosition().getLine() + 1, position.getPosition().getCharacter() + 1); ArrayList<DocumentHighlight> list = new ArrayList<>(1); list.add(result); return CompletableFuture.completedFuture(list); }
private List<DocumentHighlight> computeOccurrences(ITypeRoot unit, int line, int column, IProgressMonitor monitor) { if (unit != null) { try { int offset = JsonRpcHelpers.toOffset(unit.getBuffer(), line, column); OccurrencesFinder finder = new OccurrencesFinder(); CompilationUnit ast = SharedASTProvider.getInstance().getAST(unit, monitor); if (ast != null) { String error = finder.initialize(ast, offset, 0); if (error == null){ List<DocumentHighlight> result = new ArrayList<>(); OccurrenceLocation[] occurrences = finder.getOccurrences(); if (occurrences != null) { for (OccurrenceLocation loc : occurrences) { if (monitor.isCanceled()) { return Collections.emptyList(); } result.add(convertToHighlight(unit, loc)); } } return result; } } } catch (JavaModelException e) { JavaLanguageServerPlugin.logException("Problem with compute occurrences for" + unit.getElementName(), e); } } return Collections.emptyList(); }
@Test public void testDocumentHighlightHandler() throws Exception { String uri = ClassFileUtil.getURI(project, "org.sample.Highlight"); TextDocumentIdentifier identifier = new TextDocumentIdentifier(uri); TextDocumentPositionParams params = new TextDocumentPositionParams(identifier, new Position(5, 10)); List<? extends DocumentHighlight> highlights = handler.documentHighlight(params, monitor); assertEquals(4, highlights.size()); assertHighlight(highlights.get(0), 5, 9, 15, DocumentHighlightKind.Write); assertHighlight(highlights.get(1), 6, 2, 8, DocumentHighlightKind.Read); assertHighlight(highlights.get(2), 7, 2, 8, DocumentHighlightKind.Write); assertHighlight(highlights.get(3), 8, 2, 8, DocumentHighlightKind.Read); }
@Test public void withoutNull() { final List<? extends DocumentHighlight> input = this.sort(CollectionLiterals.<DocumentHighlight>newArrayList(this.newHighlight(DocumentHighlightKind.Text, this.newRange(2, 2, 2, 2)), this.newHighlight(DocumentHighlightKind.Text, this.newRange(1, 1, 1, 1)), this.newHighlight(DocumentHighlightKind.Write, this.newRange(2, 2, 2, 2)), this.newHighlight(DocumentHighlightKind.Write, this.newRange(1, 1, 1, 1)), this.newHighlight(DocumentHighlightKind.Read, this.newRange(2, 2, 2, 2)), this.newHighlight(DocumentHighlightKind.Read, this.newRange(1, 1, 1, 1)))); Assert.assertEquals(1, input.get(0).getRange().getStart().getLine()); Assert.assertEquals(1, input.get(0).getRange().getStart().getCharacter()); Assert.assertEquals(1, input.get(0).getRange().getEnd().getLine()); Assert.assertEquals(1, input.get(0).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Text, input.get(0).getKind()); Assert.assertEquals(1, input.get(1).getRange().getStart().getLine()); Assert.assertEquals(1, input.get(1).getRange().getStart().getCharacter()); Assert.assertEquals(1, input.get(1).getRange().getEnd().getLine()); Assert.assertEquals(1, input.get(1).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Read, input.get(1).getKind()); Assert.assertEquals(1, input.get(2).getRange().getStart().getLine()); Assert.assertEquals(1, input.get(2).getRange().getStart().getCharacter()); Assert.assertEquals(1, input.get(2).getRange().getEnd().getLine()); Assert.assertEquals(1, input.get(2).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Write, input.get(2).getKind()); Assert.assertEquals(2, input.get(3).getRange().getStart().getLine()); Assert.assertEquals(2, input.get(3).getRange().getStart().getCharacter()); Assert.assertEquals(2, input.get(3).getRange().getEnd().getLine()); Assert.assertEquals(2, input.get(3).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Text, input.get(3).getKind()); Assert.assertEquals(2, input.get(4).getRange().getStart().getLine()); Assert.assertEquals(2, input.get(4).getRange().getStart().getCharacter()); Assert.assertEquals(2, input.get(4).getRange().getEnd().getLine()); Assert.assertEquals(2, input.get(4).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Read, input.get(4).getKind()); Assert.assertEquals(2, input.get(5).getRange().getStart().getLine()); Assert.assertEquals(2, input.get(5).getRange().getStart().getCharacter()); Assert.assertEquals(2, input.get(5).getRange().getEnd().getLine()); Assert.assertEquals(2, input.get(5).getRange().getEnd().getCharacter()); Assert.assertEquals(DocumentHighlightKind.Write, input.get(5).getKind()); }
protected String _toExpectation(final DocumentHighlight it) { String _xblockexpression = null; { StringConcatenation _builder = new StringConcatenation(); { Range _range = it.getRange(); boolean _tripleEquals = (_range == null); if (_tripleEquals) { _builder.append("[NaN, NaN]:[NaN, NaN]"); } else { String _expectation = this.toExpectation(it.getRange()); _builder.append(_expectation); } } final String rangeString = _builder.toString(); StringConcatenation _builder_1 = new StringConcatenation(); { DocumentHighlightKind _kind = it.getKind(); boolean _tripleEquals_1 = (_kind == null); if (_tripleEquals_1) { _builder_1.append("NaN"); } else { String _expectation_1 = this.toExpectation(it.getKind()); _builder_1.append(_expectation_1); } } _builder_1.append(" "); _builder_1.append(rangeString); _xblockexpression = _builder_1.toString(); } return _xblockexpression; }
@Override public DocumentHighlight apply(final Document document, final ITextRegion region, final DocumentHighlightKind kind) { Preconditions.checkNotNull(document, "document"); Preconditions.checkNotNull(region, "region"); Preconditions.checkNotNull(kind, "kind"); final int offset = region.getOffset(); final Position start = document.getPosition(offset); final Position end = document.getPosition(offset + region.getLength()); return new DocumentHighlight(new Range(start, end), kind); }
@Override public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(TextDocumentPositionParams position) { LOGGER.info("documentHighlight: " + position.getTextDocument()); return CompletableFuture.completedFuture(Collections.emptyList()); }
public DocumentHighlight getHighlight(final String documentUri, final int line, final int character) { // TODO: this is wrong, it should be something entierly different. // this feature is about marking the occurrences of a selected element // like a variable, where it is used. // so, this should actually return multiple results. // The spec is currently broken for that. // XXX: the code here doesn't make any sense for what it is supposed to do // Map<SourceSection, Set<Class<? extends Tags>>> sections = Highlight. // getSourceSections(); // SourceSection[] all = sections.entrySet().stream().map(e -> e.getKey()).toArray(size -> // new SourceSection[size]); // // Stream<Entry<SourceSection, Set<Class<? extends Tags>>>> filtered = sections. // entrySet().stream().filter( // (final Entry<SourceSection, Set<Class<? extends Tags>>> e) -> in(e.getKey(), line, // character)); // // @SuppressWarnings("rawtypes") // Entry[] matching = filtered.toArray(size -> new Entry[size]); // // for (Entry<SourceSection, Set<Class<? extends Tags>>> e : matching) { // int kind; // if (e.getValue().contains(LiteralTag.class)) { // kind = DocumentHighlight.KIND_READ; // } else { // kind = DocumentHighlight.KIND_TEXT; // } // DocumentHighlightImpl highlight = new DocumentHighlightImpl(); // highlight.setKind(kind); // highlight.setRange(getRange(e.getKey())); // return highlight; // } // // DocumentHighlightImpl highlight = new DocumentHighlightImpl(); // highlight.setKind(DocumentHighlight.KIND_TEXT); // RangeImpl range = new RangeImpl(); // range.setStart(pos(line, character)); // range.setEnd(pos(line, character + 1)); // highlight.setRange(range); // return highlight; return null; }
public List<? extends DocumentHighlight> documentHighlight(TextDocumentPositionParams position, IProgressMonitor monitor) { ITypeRoot type = JDTUtils.resolveTypeRoot(position.getTextDocument().getUri()); return computeOccurrences(type, position.getPosition().getLine(), position.getPosition().getCharacter(), monitor); }
@Override public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(TextDocumentPositionParams position) { logInfo(">> document/documentHighlight"); DocumentHighlightHandler handler = new DocumentHighlightHandler(); return computeAsync((cc) -> handler.documentHighlight(position, toMonitor(cc))); }
private void assertHighlight(DocumentHighlight highlight, int expectedLine, int expectedStart, int expectedEnd, DocumentHighlightKind expectedKind) { Lsp4jAssertions.assertRange(expectedLine, expectedStart, expectedEnd, highlight.getRange()); assertEquals(expectedKind, highlight.getKind()); }
private DocumentHighlight newHighlight(final DocumentHighlightKind kind, final Range range) { return new DocumentHighlight(range, kind); }
private List<? extends DocumentHighlight> sort(final List<? extends DocumentHighlight> toSort) { toSort.sort(this.comparator); return toSort; }
@Override public List<? extends DocumentHighlight> getDocumentHighlights(Document document, XtextResource resource, TextDocumentPositionParams params, CancelIndicator cancelIndicator) { int offset = document.getOffSet(params.getPosition()); return getDocumentHighlights(resource, offset); }
@Override public int compare(final DocumentHighlight left, final DocumentHighlight right) { return Ordering.from(delegate).nullsLast().compare(left, right); }
@Override public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(TextDocumentPositionParams position) { throw new UnsupportedOperationException(); }
@Override public JsPromise<OrionOccurrenceOverlay[]> computeOccurrences( OrionOccurrenceContextOverlay context) { final EditorPartPresenter activeEditor = editorAgent.getActiveEditor(); if (activeEditor == null || !(activeEditor instanceof TextEditor)) { return null; } final TextEditor editor = ((TextEditor) activeEditor); if (!(editor.getConfiguration() instanceof LanguageServerEditorConfiguration)) { return null; } final LanguageServerEditorConfiguration configuration = (LanguageServerEditorConfiguration) editor.getConfiguration(); if (configuration.getServerCapabilities().getDocumentHighlightProvider() == null || !configuration.getServerCapabilities().getDocumentHighlightProvider()) { return null; } final Document document = editor.getDocument(); final TextDocumentPositionParams paramsDTO = helper.createTDPP(document, context.getStart()); Promise<List<DocumentHighlight>> promise = client.documentHighlight(paramsDTO); Promise<OrionOccurrenceOverlay[]> then = promise.then( new Function<List<DocumentHighlight>, OrionOccurrenceOverlay[]>() { @Override public OrionOccurrenceOverlay[] apply(List<DocumentHighlight> highlights) throws FunctionException { final OrionOccurrenceOverlay[] occurrences = new OrionOccurrenceOverlay[highlights.size()]; for (int i = 0; i < occurrences.length; i++) { DocumentHighlight highlight = highlights.get(i); final OrionOccurrenceOverlay occurrence = OrionOccurrenceOverlay.create(); Position start = highlight.getRange().getStart(); Position end = highlight.getRange().getEnd(); int startIndex = document.getIndexFromPosition( new TextPosition(start.getLine(), start.getCharacter())); int endIndex = document.getIndexFromPosition( new TextPosition(end.getLine(), end.getCharacter())); occurrence.setStart(startIndex); occurrence.setEnd(endIndex + 1); occurrences[i] = occurrence; } return occurrences; } }); return (JsPromise<OrionOccurrenceOverlay[]>) then; }
@Override public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight( TextDocumentPositionParams position) { return null; }
protected String toExpectation(final Object it) { if (it instanceof Integer) { return _toExpectation((Integer)it); } else if (it instanceof List) { return _toExpectation((List<?>)it); } else if (it instanceof DocumentHighlightKind) { return _toExpectation((DocumentHighlightKind)it); } else if (it instanceof String) { return _toExpectation((String)it); } else if (it == null) { return _toExpectation((Void)null); } else if (it instanceof Map) { return _toExpectation((Map<Object, Object>)it); } else if (it instanceof CodeLens) { return _toExpectation((CodeLens)it); } else if (it instanceof ColoringInformation) { return _toExpectation((ColoringInformation)it); } else if (it instanceof Command) { return _toExpectation((Command)it); } else if (it instanceof CompletionItem) { return _toExpectation((CompletionItem)it); } else if (it instanceof DocumentHighlight) { return _toExpectation((DocumentHighlight)it); } else if (it instanceof Hover) { return _toExpectation((Hover)it); } else if (it instanceof Location) { return _toExpectation((Location)it); } else if (it instanceof Position) { return _toExpectation((Position)it); } else if (it instanceof Range) { return _toExpectation((Range)it); } else if (it instanceof SignatureHelp) { return _toExpectation((SignatureHelp)it); } else if (it instanceof SymbolInformation) { return _toExpectation((SymbolInformation)it); } else if (it instanceof TextEdit) { return _toExpectation((TextEdit)it); } else if (it instanceof WorkspaceEdit) { return _toExpectation((WorkspaceEdit)it); } else if (it instanceof Either) { return _toExpectation((Either<?, ?>)it); } else { throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object>asList(it).toString()); } }
@PostConstruct public void configureMethods() { dtoToDtoList( "definition", TextDocumentPositionParams.class, LocationDto.class, this::definition); dtoToDtoList("codeAction", CodeActionParams.class, CommandDto.class, this::codeAction); dtoToDtoList( "documentSymbol", DocumentSymbolParams.class, SymbolInformationDto.class, this::documentSymbol); dtoToDtoList("formatting", DocumentFormattingParams.class, TextEditDto.class, this::formatting); dtoToDtoList( "rangeFormatting", DocumentRangeFormattingParams.class, TextEditDto.class, this::rangeFormatting); dtoToDtoList("references", ReferenceParams.class, LocationDto.class, this::references); dtoToDtoList( "onTypeFormatting", DocumentOnTypeFormattingParams.class, TextEditDto.class, this::onTypeFormatting); dtoToDto( "completionItem/resolve", ExtendedCompletionItem.class, ExtendedCompletionItemDto.class, this::completionItemResolve); dtoToDto( "documentHighlight", TextDocumentPositionParams.class, DocumentHighlight.class, this::documentHighlight); dtoToDto( "completion", TextDocumentPositionParams.class, ExtendedCompletionListDto.class, this::completion); dtoToDto("hover", TextDocumentPositionParams.class, HoverDto.class, this::hover); dtoToDto( "signatureHelp", TextDocumentPositionParams.class, SignatureHelpDto.class, this::signatureHelp); dtoToDto("rename", RenameParams.class, RenameResultDto.class, this::rename); dtoToNothing("didChange", DidChangeTextDocumentParams.class, this::didChange); dtoToNothing("didClose", DidCloseTextDocumentParams.class, this::didClose); dtoToNothing("didOpen", DidOpenTextDocumentParams.class, this::didOpen); dtoToNothing("didSave", DidSaveTextDocumentParams.class, this::didSave); }
/** * The document highlight request is sent from the client to the server to * to resolve a document highlights for a given text document position. * * Registration Options: TextDocumentRegistrationOptions */ @JsonRequest CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(TextDocumentPositionParams position);
/** * Returns with a list of {@link DocumentHighlight document highlight} * instances that matches with the given text from the resource at the given * offset. * * @param resource * the resource that represents the document where matching * highlights have to be collected. * @param offset * the offset used to identify the selected text from the * resource. * * @return a list of document highlight instances that matches with the * selected text based on an arbitrary logic. Might return with an * empty list but never returns with {@code null}. */ @Deprecated List<? extends DocumentHighlight> getDocumentHighlights(final XtextResource resource, final int offset);
/** * Transforms the {@link ITextRegion text region} argument into a * {@link DocumentHighlight document highlight} instance by calculating the * proper position from the document. The given kind will be used to * distinguish between {@link DocumentHighlightKind#Read read}, * {@link DocumentHighlightKind#Write write} and ordinary * {@link DocumentHighlightKind#Text text} occurrences. * * <p> * This conversion is required to transform the Xtext specific document * relative offsets into language server specific line relative offsets. * * @param document * the document that contains the text content. Cannot be * {@code null}. * @param region * the text region that has to be converted. Cannot be * {@code null}. * @param kind * the document highlight kind. Cannot be {@code null}. * * @return * with a new transformed {@link DocumentHighlight document * highlight} instance. */ DocumentHighlight apply(final Document document, final ITextRegion region, final DocumentHighlightKind kind);
/** * GWT client implementation of {@link * TextDocumentService#documentHighlight(TextDocumentPositionParams position)} * * @param params * @return a {@link Promise} of an array of {@link DocumentHighlight} which will be computed by * the language server. */ public Promise<List<DocumentHighlight>> documentHighlight(TextDocumentPositionParams params) { return transmitDtoAndReceiveDtoList( params, "textDocument/documentHighlight", DocumentHighlight.class); }
List<? extends DocumentHighlight> getDocumentHighlights(Document document, XtextResource resource, TextDocumentPositionParams params, CancelIndicator cancelIndicator);