Search in sources :

Example 1 with LinkedEditingRanges

use of org.eclipse.lsp4j.LinkedEditingRanges in project lsp4e by eclipse.

the class LinkedEditingTest method testLinkedEditing.

@Test
public void testLinkedEditing() throws CoreException, InvocationTargetException {
    List<Range> ranges = new ArrayList<>();
    ranges.add(new Range(new Position(1, 3), new Position(1, 7)));
    ranges.add(new Range(new Position(3, 4), new Position(3, 8)));
    LinkedEditingRanges linkkedEditingRanges = new LinkedEditingRanges(ranges);
    MockLanguageServer.INSTANCE.setLinkedEditingRanges(linkkedEditingRanges);
    IFile testFile = TestUtils.createUniqueTestFile(project, "<html>\n  <body>\n    a body text\n  </body>\n</html>");
    ITextViewer viewer = TestUtils.openTextViewer(testFile);
    viewer.getTextWidget().setCaretOffset(11);
    if (!(viewer instanceof ISourceViewer)) {
        Assert.fail();
    }
    ISourceViewer sourceViewer = (ISourceViewer) viewer;
    // 10-14 <body|>
    viewer.getTextWidget().setSelection(11);
    Map<org.eclipse.jface.text.Position, Annotation> annotations = new HashMap<>();
    new DisplayHelper() {

        @Override
        protected boolean condition() {
            Iterator<Annotation> iterator = sourceViewer.getAnnotationModel().getAnnotationIterator();
            while (iterator.hasNext()) {
                Annotation annotation = iterator.next();
                if (annotation.getType().startsWith("org.eclipse.ui.internal.workbench.texteditor.link")) {
                    return true;
                }
            }
            return false;
        }
    }.waitForCondition(Display.getCurrent(), 3000);
    IAnnotationModel model = sourceViewer.getAnnotationModel();
    final Iterator<Annotation> iterator = model.getAnnotationIterator();
    while (iterator.hasNext()) {
        Annotation annotation = iterator.next();
        annotations.put(model.getPosition(annotation), annotation);
    }
    Annotation annotation = annotations.get(new LinkedPosition(sourceViewer.getDocument(), 10, 4, 0));
    Assert.assertNotNull(annotation);
    assertTrue(annotation.getType().startsWith("org.eclipse.ui.internal.workbench.texteditor.link"));
}
Also used : LinkedPosition(org.eclipse.jface.text.link.LinkedPosition) IFile(org.eclipse.core.resources.IFile) LinkedPosition(org.eclipse.jface.text.link.LinkedPosition) Position(org.eclipse.lsp4j.Position) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) IAnnotationModel(org.eclipse.jface.text.source.IAnnotationModel) Range(org.eclipse.lsp4j.Range) Annotation(org.eclipse.jface.text.source.Annotation) ITextViewer(org.eclipse.jface.text.ITextViewer) Iterator(java.util.Iterator) DisplayHelper(org.eclipse.ui.tests.harness.util.DisplayHelper) ISourceViewer(org.eclipse.jface.text.source.ISourceViewer) LinkedEditingRanges(org.eclipse.lsp4j.LinkedEditingRanges) Test(org.junit.Test)

Example 2 with LinkedEditingRanges

use of org.eclipse.lsp4j.LinkedEditingRanges in project lxtk by lxtk-org.

the class RenameLinkedModeStarter method getLinkedEditingRanges.

/**
 * Returns the linked editing ranges for the given {@link LinkedEditingRangeParams}.
 *
 * @param params never <code>null</code>
 * @return the corresponding {@link LinkedEditingRanges}, or <code>null</code> if none
 */
protected LinkedEditingRanges getLinkedEditingRanges(LinkedEditingRangeParams params) {
    LinkedEditingRanges[] ranges = new LinkedEditingRanges[1];
    TaskExecutor.sequentialExecute(getLinkedEditingRangeProviders(target), (provider, timeout) -> {
        LinkedEditingRangeRequest request = newLinkedEditingRangeRequest();
        request.setProvider(provider);
        request.setParams(JsonUtil.deepCopy(params));
        request.setTimeout(timeout);
        request.setMayThrow(false);
        LinkedEditingRanges result = request.sendAndReceive();
        if (result == null || result.getRanges().isEmpty())
            return false;
        ranges[0] = result;
        return true;
    }, getLinkedEditingRangeTimeout());
    return ranges[0];
}
Also used : LinkedEditingRangeRequest(org.lxtk.lx4e.requests.LinkedEditingRangeRequest) LinkedEditingRanges(org.eclipse.lsp4j.LinkedEditingRanges)

Example 3 with LinkedEditingRanges

use of org.eclipse.lsp4j.LinkedEditingRanges in project OberonEmulator by schierlm.

the class Server method getTextDocumentService.

@Override
public TextDocumentService getTextDocumentService() {
    return new TextDocumentService() {

        @Override
        public void didSave(DidSaveTextDocumentParams params) {
        }

        @Override
        public void didOpen(DidOpenTextDocumentParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            if (of == null) {
                of = new OberonFile(params.getTextDocument().getUri(), params.getTextDocument().getText());
            } else {
                of.setContent(params.getTextDocument().getText());
            }
            openFiles.put(params.getTextDocument().getUri(), of);
            fileChanged(of);
        }

        @Override
        public void didClose(DidCloseTextDocumentParams params) {
            fileClosed(openFiles.remove(params.getTextDocument().getUri()));
        }

        @Override
        public void didChange(DidChangeTextDocumentParams params) {
            OberonFile of = openFiles.get(params.getTextDocument().getUri());
            if (params.getContentChanges().size() != 1)
                throw new IllegalArgumentException("Incremental changes not supported)");
            of.setContent(params.getContentChanges().get(0).getText());
            fileChanged(of);
        }

        @Override
        public CompletableFuture<List<Either<SymbolInformation, DocumentSymbol>>> documentSymbol(DocumentSymbolParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            if (of == null)
                return CompletableFuture.completedFuture(new ArrayList<>());
            return of.waitWhenDirty(backgroundExecutor, f -> new ArrayList<>(f.getOutline()));
        }

        @Override
        public CompletableFuture<SemanticTokens> semanticTokensFull(SemanticTokensParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            return of.waitWhenDirty(backgroundExecutor, f -> new SemanticTokens(IntStream.of(f.getSemanticTokens()).mapToObj(i -> i).collect(Collectors.toList())));
        }

        @Override
        public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(CompletionParams position) {
            OberonFile of = fileForURI(position.getTextDocument().getUri());
            int pos = of.getRawPos(position.getPosition());
            if (pos == -1)
                return CompletableFuture.completedFuture(Either.forLeft(new ArrayList<>()));
            String prefix = of.getContent().substring(0, pos);
            CompletableFuture<Either<List<CompletionItem>, CompletionList>> result = new CompletableFuture<>();
            backgroundExecutor.submit(() -> {
                try {
                    List<CompletionItem> completions = bridge.complete(prefix);
                    result.complete(Either.forLeft(completions));
                } catch (Throwable ex) {
                    ex.printStackTrace();
                    result.completeExceptionally(ex);
                }
            });
            return result;
        }

        @Override
        public CompletableFuture<Either<List<? extends Location>, List<? extends LocationLink>>> definition(DefinitionParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            return of.waitWhenDirty(backgroundExecutor, ar -> {
                if (debug && params.getPosition().getLine() == 0 && params.getPosition().getCharacter() == 0) {
                    // validate all references in this file!
                    int[] errors = { 0 };
                    for (Identifier id : ar.getIdDefinitions().values()) {
                        if (id.getKind() == SymbolKind.Module) {
                            continue;
                        }
                        try {
                            findRangeToDelete(id, ar, new HashSet<Integer>(Arrays.asList(id.getEndPos())));
                        } catch (RuntimeException ex) {
                            System.err.println("Unable to find delete range for pos " + id.getEndPos());
                            errors[0]++;
                        }
                    }
                    for (Identifier id : ar.getIdReferences().values()) {
                        String desc_ = id.getDefinition().toString();
                        IdentifierReference definition = lookupSymbolRef(id.getDefinition());
                        if (definition == null) {
                            System.err.println(desc_ + ": symbol reference lookup failed");
                            continue;
                        } else if (!definition.equals(id.getDefinition())) {
                            desc_ += "->" + definition;
                        }
                        desc_ += " '" + of.getContent().substring(id.getStartPos(), id.getEndPos()) + "'";
                        String desc = desc_;
                        final boolean[] found = { false };
                        for (OberonFile dof : allFiles(definition.getModule(), false)) {
                            try {
                                dof.waitWhenDirty(backgroundExecutor, dar -> {
                                    if (dar.getModuleName().equals(definition.getModule())) {
                                        found[0] = true;
                                        if (!dar.getIdDefinitions().containsKey(definition.getEndPos())) {
                                            System.err.println(desc + ": identifier not found");
                                            errors[0]++;
                                        }
                                    }
                                    return null;
                                }).get();
                            } catch (InterruptedException | ExecutionException ex) {
                            }
                        }
                        if (!found[0]) {
                            System.err.println(desc + ": module not loaded");
                            errors[0]++;
                        }
                    }
                    System.err.println("Reference validation finished, " + errors[0] + " errors detected.");
                }
                int pos = of.getRawPos(params.getPosition());
                Identifier id = findAt(ar.getIdReferences(), pos);
                return id != null ? id.getDefinition() : null;
            }).thenApply((IdentifierReference sref) -> {
                List<Location> result = new ArrayList<>();
                if (sref != null) {
                    IdentifierReference definition = lookupSymbolRef(sref);
                    if (definition != null) {
                        Location loc = buildLocation(of, of.getCachedModuleName(), definition);
                        if (loc != null) {
                            result.add(loc);
                        }
                    }
                }
                return Either.forLeft(result);
            });
        }

        private CallHierarchyItem buildCallHierarchyItem(OberonFile of, AnalysisResult ar, Identifier id) {
            CallHierarchyItem chi = new CallHierarchyItem();
            chi.setName(of.getContent().substring(id.getStartPos(), id.getEndPos()));
            chi.setKind(id.getKind());
            chi.setData(new Two<>(ar.getModuleName(), id.getEndPos()));
            Range r = new Range(of.getPos(id.getStartPos()), of.getPos(id.getEndPos()));
            chi.setSelectionRange(r);
            if (id.getKind() == SymbolKind.Function) {
                int[] func = findFunction(ar.getFunctionRanges(), id.getEndPos());
                if (func != null && func[1] == id.getEndPos()) {
                    r = new Range(of.getPos(func[0]), of.getPos(func[1]));
                }
            }
            chi.setRange(r);
            return chi;
        }

        private Location buildLocation(OberonFile baseFile, String baseModule, IdentifierReference definition) {
            String uri = null;
            for (OberonFile of : allFiles(definition.getModule(), false)) {
                try {
                    Either<Location, String> loc = of.<Either<Location, String>>waitWhenDirty(backgroundExecutor, ar -> {
                        if (ar.getModuleName().equals(definition.getModule())) {
                            Identifier id = ar.getIdDefinitions().get(definition.getEndPos());
                            if (id != null) {
                                return Either.forLeft(new Location(of.getUri(), new Range(of.getPos(id.getStartPos()), of.getPos(id.getEndPos()))));
                            }
                            return Either.forRight(of.getUri());
                        }
                        return null;
                    }).get();
                    if (loc != null && loc.isLeft())
                        return loc.getLeft();
                    else if (loc != null && loc.isRight())
                        uri = loc.getRight();
                } catch (InterruptedException | ExecutionException ex) {
                }
            }
            if (uri == null) {
                String baseUri = baseFile.getUri();
                int pos = baseUri.lastIndexOf("/" + baseModule + ".");
                if (pos != -1) {
                    uri = baseUri.substring(0, pos + 1) + definition.getModule() + baseUri.substring(pos + baseModule.length() + 1);
                }
            }
            Location location = uri == null ? null : new Location(uri, new Range(new Position(0, 0), new Position(0, 0)));
            return location;
        }

        @Override
        public CompletableFuture<List<? extends Location>> references(ReferenceParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            return of.waitWhenDirty(backgroundExecutor, ar -> {
                int pos = of.getRawPos(params.getPosition());
                Identifier def = findAt(ar.getIdDefinitions(), pos);
                if (def != null) {
                    return new IdentifierReference(def.isExported() ? ar.getModuleName() : "<local>", def.getEndPos());
                }
                Identifier ref = findAt(ar.getIdReferences(), pos);
                if (ref != null) {
                    if (ref.getDefinition().getModule().equals(ar.getModuleName())) {
                        if (!ar.getIdDefinitions().get(ref.getDefinition().getEndPos()).isExported() && ref.getDefinition().getEndPos() >= 0) {
                            return new IdentifierReference("<local>", ref.getDefinition().getEndPos());
                        }
                    }
                    return ref.getDefinition();
                }
                return (IdentifierReference) null;
            }).thenApply(ref -> {
                List<Location> result = new ArrayList<>();
                if (ref == null)
                    return result;
                IdentifierReference pendingRef = lookupSymbolRef(ref);
                if (pendingRef == null)
                    return result;
                List<IdentifierReference> pendingRefs = new ArrayList<>();
                pendingRefs.add(ref);
                while (!pendingRefs.isEmpty()) {
                    IdentifierReference reference = pendingRefs.remove(0);
                    if (reference == null)
                        continue;
                    Collection<OberonFile> files;
                    String defModuleLocal = reference.getModule();
                    if (defModuleLocal.equals("<local>")) {
                        defModuleLocal = of.getCachedModuleName();
                        files = Arrays.asList(of);
                    } else {
                        files = allFiles(defModuleLocal, true);
                    }
                    final String defModule = defModuleLocal;
                    for (OberonFile of2 : files) {
                        of2.waitToAddWhenDirty(result, backgroundExecutor, ar2 -> {
                            List<Location> locations = new ArrayList<>();
                            if (ar2.getModuleName().equals(defModule)) {
                                Identifier rid = findAt(ar2.getIdDefinitions(), reference.getEndPos());
                                if (rid != null) {
                                    locations.add(new Location(of2.getUri(), new Range(of2.getPos(rid.getStartPos()), of2.getPos(rid.getEndPos()))));
                                }
                            }
                            Map<Integer, List<Integer>> modRefs = ar2.getModuleDeps().get(defModule);
                            if (modRefs != null) {
                                List<Integer> refs = modRefs.get(reference.getEndPos());
                                if (refs != null) {
                                    for (Integer rend : refs) {
                                        if (rend < 0) {
                                            pendingRefs.add(new IdentifierReference(ar2.getModuleName(), rend));
                                        } else {
                                            Identifier rid = ar2.getIdReferences().get(rend);
                                            if (rid != null) {
                                                locations.add(new Location(of2.getUri(), new Range(of2.getPos(rid.getStartPos()), of2.getPos(rid.getEndPos()))));
                                            }
                                        }
                                    }
                                }
                            }
                            return locations;
                        });
                    }
                }
                return result;
            });
        }

        @Override
        public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(DocumentHighlightParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            if (of == null)
                return CompletableFuture.completedFuture(new ArrayList<>());
            return of.waitWhenDirty(backgroundExecutor, ar -> {
                int pos = of.getRawPos(params.getPosition());
                IdentifierReference defReference;
                Identifier def = findAt(ar.getIdDefinitions(), pos);
                if (def != null) {
                    defReference = new IdentifierReference(ar.getModuleName(), def.getEndPos());
                } else {
                    Identifier ref = findAt(ar.getIdReferences(), pos);
                    if (ref != null) {
                        defReference = ref.getDefinition();
                    } else {
                        defReference = null;
                    }
                }
                List<DocumentHighlight> result = new ArrayList<>();
                if (defReference == null)
                    return result;
                if (ar.getModuleName().equals(defReference.getModule())) {
                    Identifier rid = findAt(ar.getIdDefinitions(), defReference.getEndPos());
                    if (rid != null) {
                        result.add(new DocumentHighlight(new Range(of.getPos(rid.getStartPos()), of.getPos(rid.getEndPos())), DocumentHighlightKind.Read));
                    }
                }
                Map<Integer, List<Integer>> modRefs = ar.getModuleDeps().get(defReference.getModule());
                if (modRefs != null) {
                    List<Integer> refs = modRefs.get(defReference.getEndPos());
                    if (refs != null) {
                        for (Integer rend : refs) {
                            if (rend < 0) {
                                continue;
                            }
                            Identifier rid = ar.getIdReferences().get(rend);
                            if (rid != null)
                                result.add(new DocumentHighlight(new Range(of.getPos(rid.getStartPos()), of.getPos(rid.getEndPos())), rid.isWrittenTo() ? DocumentHighlightKind.Write : DocumentHighlightKind.Read));
                        }
                    }
                }
                return result;
            });
        }

        private CompletableFuture<List<Range>> editingRanges(String uri, Position position) {
            OberonFile of = fileForURI(uri);
            return of.waitWhenDirty(backgroundExecutor, ar -> {
                final List<Range> ranges = new ArrayList<>();
                int pos = of.getRawPos(position);
                IdentifierReference defReference = null;
                Identifier definition = findAt(ar.getIdDefinitions(), pos);
                if (definition != null) {
                    defReference = new IdentifierReference(ar.getModuleName(), definition.getEndPos());
                } else {
                    Identifier ref = findAt(ar.getIdReferences(), pos);
                    if (ref != null) {
                        defReference = ref.getDefinition();
                    }
                }
                if (defReference != null && defReference.getModule().equals(ar.getModuleName())) {
                    if (ar.getIdReferences().containsKey(defReference.getEndPos())) {
                        // do not allow to rename unaliased IMPORTs!
                        return ranges;
                    }
                    Identifier id = ar.getIdDefinitions().get(defReference.getEndPos());
                    if (id.isExported()) {
                        // do not allow to rename exported definitions
                        return ranges;
                    }
                    ranges.add(new Range(of.getPos(id.getStartPos()), of.getPos(id.getEndPos())));
                    Map<Integer, List<Integer>> modRefs = ar.getModuleDeps().get(defReference.getModule());
                    if (modRefs != null) {
                        List<Integer> refs = modRefs.get(defReference.getEndPos());
                        if (refs != null) {
                            for (Integer rend : refs) {
                                if (rend < 0)
                                    continue;
                                Identifier ref = ar.getIdReferences().get(rend);
                                ranges.add(new Range(of.getPos(ref.getStartPos()), of.getPos(ref.getEndPos())));
                            }
                        }
                    }
                }
                return ranges;
            });
        }

        @Override
        public CompletableFuture<LinkedEditingRanges> linkedEditingRange(LinkedEditingRangeParams params) {
            return editingRanges(params.getTextDocument().getUri(), params.getPosition()).thenApply(LinkedEditingRanges::new);
        }

        private boolean positionBefore(Position p1, Position p2) {
            return p1.getLine() < p2.getLine() || (p1.getLine() == p2.getLine() && p1.getCharacter() <= p2.getCharacter());
        }

        @Override
        public CompletableFuture<Either<Range, PrepareRenameResult>> prepareRename(PrepareRenameParams params) {
            return editingRanges(params.getTextDocument().getUri(), params.getPosition()).thenApply(rs -> {
                for (Range r : rs) {
                    if (positionBefore(r.getStart(), params.getPosition()) && positionBefore(params.getPosition(), r.getEnd()))
                        return Either.forLeft(r);
                }
                return null;
            });
        }

        @Override
        public CompletableFuture<WorkspaceEdit> rename(RenameParams params) {
            return editingRanges(params.getTextDocument().getUri(), params.getPosition()).thenApply(rs -> {
                List<TextEdit> edits = new ArrayList<>();
                for (Range r : rs) {
                    edits.add(new TextEdit(r, params.getNewName()));
                }
                Map<String, List<TextEdit>> changes = new HashMap<>();
                changes.put(params.getTextDocument().getUri(), edits);
                return new WorkspaceEdit(changes);
            });
        }

        @Override
        public CompletableFuture<SignatureHelp> signatureHelp(SignatureHelpParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            CompletableFuture<SignatureHelp> result = new CompletableFuture<>();
            backgroundExecutor.submit(new Callable<Void>() {

                public Void call() throws Exception {
                    Thread.sleep(200);
                    of.waitWhenDirty(backgroundExecutor, ar -> {
                        int paramIndex = 0, startPos = -1;
                        {
                            SortedMap<Integer, ParamTag> tagsBefore = ar.getParamTags().headMap(of.getRawPos(params.getPosition()) + 1);
                            int depth = 0;
                            loop: while (!tagsBefore.isEmpty()) {
                                int p = tagsBefore.lastKey();
                                ParamTag t = tagsBefore.get(p);
                                tagsBefore = tagsBefore.headMap(p);
                                switch(t) {
                                    case CALL_START:
                                        if (depth == 0) {
                                            startPos = p - 1;
                                            break loop;
                                        }
                                        depth--;
                                        break;
                                    case END:
                                        depth++;
                                        break;
                                    case NEXT:
                                        if (depth == 0)
                                            paramIndex++;
                                        break;
                                    case END_LAST:
                                    case PROC_START:
                                    default:
                                        break loop;
                                }
                            }
                        }
                        if (startPos == -1)
                            return new Two<Integer, IdentifierReference>(paramIndex, null);
                        while (startPos > 0 && of.getContent().charAt(startPos - 1) <= ' ') startPos--;
                        Identifier refid = ar.getIdReferences().get(startPos);
                        return new Two<>(paramIndex, refid.getDefinition());
                    }).thenApply(pair -> {
                        final int paramIndex_ = pair.getFirst();
                        IdentifierReference ref = lookupSymbolRef(pair.getSecond());
                        if (ref == null)
                            return null;
                        for (OberonFile of2 : allFiles(ref.getModule(), false)) {
                            try {
                                SignatureHelp sh = of2.waitWhenDirty(backgroundExecutor, ar2 -> {
                                    if (ar2.getModuleName().equals(ref.getModule())) {
                                        Identifier id = ar2.getIdDefinitions().get(ref.getEndPos());
                                        if (id != null) {
                                            int ssPos = id.getStartPos();
                                            SortedMap<Integer, ParamTag> tagsAfter = ar2.getParamTags().tailMap(ssPos);
                                            int p = tagsAfter.firstKey();
                                            ParamTag t = tagsAfter.get(p);
                                            if (t != ParamTag.PROC_START)
                                                return null;
                                            int psPos = p;
                                            tagsAfter = tagsAfter.tailMap(p + 1);
                                            List<ParameterInformation> pis = new ArrayList<>();
                                            while (!tagsAfter.isEmpty()) {
                                                p = tagsAfter.firstKey();
                                                t = tagsAfter.get(p);
                                                tagsAfter = tagsAfter.tailMap(p + 1);
                                                if (t != ParamTag.NEXT && t != ParamTag.END && t != ParamTag.END_LAST)
                                                    return null;
                                                ParameterInformation pi = new ParameterInformation();
                                                pi.setLabel(new Two<Integer, Integer>(psPos - ssPos, p - 1 - ssPos));
                                                pis.add(pi);
                                                psPos = p;
                                                if (t != ParamTag.NEXT)
                                                    break;
                                            }
                                            SignatureInformation si = new SignatureInformation(of2.getContent().substring(ssPos, psPos));
                                            si.setParameters(pis);
                                            return new SignatureHelp(Arrays.asList(si), 0, paramIndex_);
                                        }
                                    }
                                    return null;
                                }).get();
                                if (sh != null)
                                    return sh;
                            } catch (InterruptedException | ExecutionException ex) {
                            }
                        }
                        return null;
                    }).thenApply(r -> result.complete(r));
                    return null;
                }
            });
            return result;
        }

        @Override
        public CompletableFuture<List<FoldingRange>> foldingRange(FoldingRangeRequestParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            if (of == null)
                return CompletableFuture.completedFuture(new ArrayList<>());
            return of.waitWhenDirty(backgroundExecutor, ar -> {
                List<FoldingRange> result = new ArrayList<>();
                Map<Integer, Integer> lastLineForOuterFunc = new HashMap<>();
                for (Map.Entry<Integer, int[]> func : ar.getFunctionRanges().entrySet()) {
                    int outerFunc = func.getValue().length > 2 ? func.getValue()[2] : -1;
                    int lastLine = lastLineForOuterFunc.getOrDefault(outerFunc, -1);
                    int startLine = of.getPos(func.getKey()).getLine();
                    int endLine = of.getPos(func.getValue()[1]).getLine();
                    if (startLine > lastLine) {
                        result.add(new FoldingRange(startLine, endLine));
                        lastLineForOuterFunc.put(outerFunc, endLine);
                    }
                }
                return result;
            });
        }

        @Override
        public CompletableFuture<Hover> hover(HoverParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            if (of == null)
                return CompletableFuture.completedFuture(null);
            return of.waitWhenDirty(backgroundExecutor, ar -> {
                int pos = of.getRawPos(params.getPosition());
                Identifier def = findAt(ar.getIdDefinitions(), pos);
                if (def != null) {
                    return new Two<>(def, new IdentifierReference(ar.getModuleName(), def.getEndPos()));
                }
                Identifier ref = findAt(ar.getIdReferences(), pos);
                if (ref != null) {
                    return new Two<>(ref, ref.getDefinition());
                }
                return new Two<>((Identifier) null, (IdentifierReference) null);
            }).thenApply(pair -> {
                Identifier id = pair.getFirst();
                IdentifierReference def = lookupSymbolRef(pair.getSecond());
                List<Hover> hovers = new ArrayList<>();
                if (def != null) {
                    for (OberonFile of2 : allFiles(def.getModule(), false)) {
                        of2.waitToAddWhenDirty(hovers, backgroundExecutor, ar2 -> {
                            if (ar2.getModuleName() != null && ar2.getModuleName().equals(def.getModule())) {
                                Identifier rid = findAt(ar2.getIdDefinitions(), def.getEndPos());
                                if (rid != null) {
                                    String content = of2.getContent();
                                    int startPos = rid.getStartPos();
                                    while (startPos > 0 && content.charAt(startPos - 1) != '\n') startPos--;
                                    int endPos = rid.getEndPos();
                                    while (endPos < content.length() && content.charAt(endPos) != '\n') endPos++;
                                    return Arrays.asList(new Hover(new MarkupContent(MarkupKind.PLAINTEXT, of2.getContent().substring(startPos, endPos)), new Range(of.getPos(id.getStartPos()), of.getPos(id.getEndPos()))));
                                }
                            }
                            return Collections.emptyList();
                        });
                    }
                }
                if (!hovers.isEmpty()) {
                    Hover hover = hovers.get(0);
                    hover.setRange(new Range(of.getPos(id.getStartPos()), of.getPos(id.getEndPos())));
                    return hover;
                }
                return null;
            });
        }

        @Override
        public CompletableFuture<List<? extends TextEdit>> formatting(DocumentFormattingParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            if (of == null)
                return CompletableFuture.completedFuture(new ArrayList<>());
            String content = of.getContent();
            Range fullRange = new Range(of.getPos(0), of.getPos(of.getContent().length()));
            CompletableFuture<List<? extends TextEdit>> result = new CompletableFuture<>();
            backgroundExecutor.submit(() -> {
                String newText;
                try {
                    List<FormatTokenInfo> tokens = bridge.format(content);
                    OberonFormatter ofo = new OberonFormatter();
                    int pos = 0;
                    for (FormatTokenInfo token : tokens) {
                        if (pos < token.getStartPos()) {
                            ofo.appendWhitespace(content.substring(pos, token.getStartPos()));
                        }
                        ofo.appendToken(content.substring(token.getStartPos(), token.getEndPos()), token);
                        pos = token.getEndPos();
                    }
                    if (pos < content.length())
                        ofo.appendWhitespace(content.substring(pos));
                    newText = ofo.getResult();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    result.complete(new ArrayList<>());
                    return;
                }
                result.complete(Arrays.asList(new TextEdit(fullRange, newText)));
            });
            return result;
        }

        @Override
        public CompletableFuture<List<CallHierarchyItem>> prepareCallHierarchy(CallHierarchyPrepareParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            return of.waitWhenDirty(backgroundExecutor, (Function<AnalysisResult, Either<List<CallHierarchyItem>, IdentifierReference>>) ar -> {
                int pos = of.getRawPos(params.getPosition());
                Identifier id = findAt(ar.getIdDefinitions(), pos);
                IdentifierReference def;
                if (id != null) {
                    def = new IdentifierReference(ar.getModuleName(), id.getEndPos());
                } else {
                    id = findAt(ar.getIdReferences(), pos);
                    if (id != null) {
                        def = id.getDefinition();
                    } else {
                        int[] func = findFunction(ar.getFunctionRanges(), pos);
                        if (func != null) {
                            id = ar.getIdDefinitions().get(func[1]);
                            if (id != null) {
                                def = new IdentifierReference(ar.getModuleName(), func[1]);
                            } else {
                                return Either.forLeft(Collections.emptyList());
                            }
                        } else {
                            return Either.forLeft(Collections.emptyList());
                        }
                    }
                }
                if (def == null || !def.getModule().equals(ar.getModuleName())) {
                    return Either.forRight(def);
                }
                CallHierarchyItem chi = buildCallHierarchyItem(of, ar, id);
                return Either.forLeft(Arrays.asList(chi));
            }).thenApply((Either<List<CallHierarchyItem>, IdentifierReference> either) -> {
                if (either.isLeft())
                    return either.getLeft();
                IdentifierReference ref = lookupSymbolRef(either.getRight());
                List<CallHierarchyItem> result = new ArrayList<>();
                if (ref == null)
                    return result;
                for (OberonFile of2 : allFiles(ref.getModule(), false)) {
                    of2.waitToAddWhenDirty(result, backgroundExecutor, ar2 -> {
                        CallHierarchyItem chi = null;
                        if (ar2.getModuleName().equals(ref.getModule())) {
                            Identifier id = ar2.getIdDefinitions().get(ref.getEndPos());
                            if (id != null)
                                chi = buildCallHierarchyItem(of2, ar2, id);
                        }
                        return chi == null ? Collections.emptyList() : Arrays.asList(chi);
                    });
                }
                return result;
            });
        }

        @Override
        public CompletableFuture<List<CallHierarchyIncomingCall>> callHierarchyIncomingCalls(CallHierarchyIncomingCallsParams params) {
            @SuppressWarnings("unchecked") Two<String, Integer> details = (Two<String, Integer>) params.getItem().getData();
            String defModule = details.getFirst();
            int defEndPos = details.getSecond();
            CompletableFuture<List<CallHierarchyIncomingCall>> ret = new CompletableFuture<>();
            backgroundExecutor.submit(() -> {
                List<CallHierarchyIncomingCall> result = new ArrayList<>();
                for (OberonFile of : allFiles(defModule, true)) {
                    of.waitToAddWhenDirty(result, backgroundExecutor, ar -> {
                        Map<Integer, List<Range>> functionCallRanges = new TreeMap<>();
                        Map<Integer, List<Integer>> modRefs = ar.getModuleDeps().get(defModule);
                        if (modRefs != null) {
                            List<Integer> rends = modRefs.get(defEndPos);
                            if (rends != null) {
                                for (Integer rend : rends) {
                                    if (rend < 0)
                                        continue;
                                    Identifier rid = ar.getIdReferences().get(rend);
                                    if (rid == null)
                                        continue;
                                    int[] func = findFunction(ar.getFunctionRanges(), rend);
                                    if (func != null) {
                                        functionCallRanges.computeIfAbsent(func[1], x -> new ArrayList<>()).add(new Range(of.getPos(rid.getStartPos()), of.getPos(rid.getEndPos())));
                                    }
                                }
                            }
                        }
                        List<CallHierarchyIncomingCall> calls = new ArrayList<>();
                        for (int funcPos : functionCallRanges.keySet()) {
                            Identifier id = ar.getIdDefinitions().get(funcPos);
                            calls.add(new CallHierarchyIncomingCall(buildCallHierarchyItem(of, ar, id), functionCallRanges.get(funcPos)));
                        }
                        return calls;
                    });
                }
                ret.complete(result);
            });
            return ret;
        }

        @Override
        public CompletableFuture<List<CallHierarchyOutgoingCall>> callHierarchyOutgoingCalls(CallHierarchyOutgoingCallsParams params) {
            @SuppressWarnings("unchecked") Two<String, Integer> details = (Two<String, Integer>) params.getItem().getData();
            String defModule = details.getFirst();
            int defEndPos = details.getSecond();
            CompletableFuture<List<CallHierarchyOutgoingCall>> ret = new CompletableFuture<>();
            backgroundExecutor.submit(() -> {
                List<Map.Entry<String, Map<Integer, List<Range>>>> tempResult = new ArrayList<>();
                for (OberonFile of : allFiles(defModule, false)) {
                    of.waitToAddWhenDirty(tempResult, backgroundExecutor, ar -> {
                        Map<String, Map<Integer, List<Range>>> functionRefRanges = new TreeMap<>();
                        if (ar.getModuleName().equals(defModule)) {
                            Identifier rid = findAt(ar.getIdDefinitions(), defEndPos);
                            if (rid != null && rid.getKind() == SymbolKind.Function) {
                                int[] func = findFunction(ar.getFunctionRanges(), defEndPos);
                                if (func != null && func[1] == defEndPos) {
                                    for (Identifier ref : ar.getIdReferences().subMap(defEndPos, func[2]).values()) {
                                        if (ref.getKind() == SymbolKind.Function) {
                                            IdentifierReference def = lookupSymbolRef(ref.getDefinition());
                                            if (def != null) {
                                                functionRefRanges.computeIfAbsent(def.getModule(), x -> new HashMap<>()).computeIfAbsent(def.getEndPos(), x -> new ArrayList<>()).add(new Range(of.getPos(ref.getStartPos()), of.getPos(ref.getEndPos())));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        return new ArrayList<>(functionRefRanges.entrySet());
                    });
                }
                List<CallHierarchyOutgoingCall> result = new ArrayList<>();
                for (Map.Entry<String, Map<Integer, List<Range>>> entry : tempResult) {
                    for (OberonFile of : allFiles(entry.getKey(), false)) {
                        of.waitToAddWhenDirty(result, backgroundExecutor, ar -> {
                            List<CallHierarchyOutgoingCall> calls = new ArrayList<>();
                            if (ar.getModuleName().equals(entry.getKey())) {
                                for (Map.Entry<Integer, List<Range>> positions : entry.getValue().entrySet()) {
                                    Identifier id = ar.getIdDefinitions().get(positions.getKey());
                                    calls.add(new CallHierarchyOutgoingCall(buildCallHierarchyItem(of, ar, id), positions.getValue()));
                                }
                            }
                            return calls;
                        });
                    }
                }
                ret.complete(result);
            });
            return ret;
        }

        @Override
        public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActionParams params) {
            OberonFile of = fileForURI(params.getTextDocument().getUri());
            return of.waitWhenDirty(backgroundExecutor, ar -> {
                return fillCodeActions(params, of, ar);
            });
        }

        @Override
        public CompletableFuture<CodeAction> resolveCodeAction(CodeAction unresolved) {
            return fillResolvedCodeAction(unresolved);
        }
    };
}
Also used : Arrays(java.util.Arrays) DidChangeTextDocumentParams(org.eclipse.lsp4j.DidChangeTextDocumentParams) LanguageServer(org.eclipse.lsp4j.services.LanguageServer) DidSaveTextDocumentParams(org.eclipse.lsp4j.DidSaveTextDocumentParams) PublishDiagnosticsParams(org.eclipse.lsp4j.PublishDiagnosticsParams) Map(java.util.Map) SemanticTokensParams(org.eclipse.lsp4j.SemanticTokensParams) CallHierarchyIncomingCallsParams(org.eclipse.lsp4j.CallHierarchyIncomingCallsParams) RenameParams(org.eclipse.lsp4j.RenameParams) LinkedEditingRanges(org.eclipse.lsp4j.LinkedEditingRanges) TextDocumentService(org.eclipse.lsp4j.services.TextDocumentService) SignatureHelpOptions(org.eclipse.lsp4j.SignatureHelpOptions) Set(java.util.Set) WorkspaceService(org.eclipse.lsp4j.services.WorkspaceService) LocationLink(org.eclipse.lsp4j.LocationLink) Executors(java.util.concurrent.Executors) SemanticTokensLegend(org.eclipse.lsp4j.SemanticTokensLegend) JsonArray(com.google.gson.JsonArray) DocumentHighlightKind(org.eclipse.lsp4j.DocumentHighlightKind) FoldingRange(org.eclipse.lsp4j.FoldingRange) CallHierarchyPrepareParams(org.eclipse.lsp4j.CallHierarchyPrepareParams) LanguageClientAware(org.eclipse.lsp4j.services.LanguageClientAware) SymbolKind(org.eclipse.lsp4j.SymbolKind) HoverParams(org.eclipse.lsp4j.HoverParams) Identifier(lspserver.OberonFile.Identifier) Callable(java.util.concurrent.Callable) Diagnostic(org.eclipse.lsp4j.Diagnostic) Hover(org.eclipse.lsp4j.Hover) ArrayList(java.util.ArrayList) TextEdit(org.eclipse.lsp4j.TextEdit) CallHierarchyOutgoingCall(org.eclipse.lsp4j.CallHierarchyOutgoingCall) DocumentFormattingParams(org.eclipse.lsp4j.DocumentFormattingParams) AnalysisResult(lspserver.OberonFile.AnalysisResult) InitializeResult(org.eclipse.lsp4j.InitializeResult) DocumentHighlight(org.eclipse.lsp4j.DocumentHighlight) DidChangeWatchedFilesParams(org.eclipse.lsp4j.DidChangeWatchedFilesParams) DocumentHighlightParams(org.eclipse.lsp4j.DocumentHighlightParams) PrepareRenameResult(org.eclipse.lsp4j.PrepareRenameResult) IOException(java.io.IOException) SignatureInformation(org.eclipse.lsp4j.SignatureInformation) ExecutionException(java.util.concurrent.ExecutionException) SignatureHelp(org.eclipse.lsp4j.SignatureHelp) Two(org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two) TreeMap(java.util.TreeMap) WorkspaceEdit(org.eclipse.lsp4j.WorkspaceEdit) RenameOptions(org.eclipse.lsp4j.RenameOptions) CompletionOptions(org.eclipse.lsp4j.CompletionOptions) SemanticTokensServerFull(org.eclipse.lsp4j.SemanticTokensServerFull) SignatureHelpParams(org.eclipse.lsp4j.SignatureHelpParams) LanguageClient(org.eclipse.lsp4j.services.LanguageClient) MarkupKind(org.eclipse.lsp4j.MarkupKind) MessageType(org.eclipse.lsp4j.MessageType) FoldingRangeRequestParams(org.eclipse.lsp4j.FoldingRangeRequestParams) DidChangeWorkspaceFoldersParams(org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams) LinkedEditingRangeParams(org.eclipse.lsp4j.LinkedEditingRangeParams) Location(org.eclipse.lsp4j.Location) Either(org.eclipse.lsp4j.jsonrpc.messages.Either) DidCloseTextDocumentParams(org.eclipse.lsp4j.DidCloseTextDocumentParams) CodeAction(org.eclipse.lsp4j.CodeAction) DiagnosticTag(org.eclipse.lsp4j.DiagnosticTag) MarkupContent(org.eclipse.lsp4j.MarkupContent) SemanticTokens(org.eclipse.lsp4j.SemanticTokens) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DocumentSymbolOptions(org.eclipse.lsp4j.DocumentSymbolOptions) CodeActionOptions(org.eclipse.lsp4j.CodeActionOptions) PrepareRenameParams(org.eclipse.lsp4j.PrepareRenameParams) Collectors(java.util.stream.Collectors) DefinitionParams(org.eclipse.lsp4j.DefinitionParams) ServerCapabilities(org.eclipse.lsp4j.ServerCapabilities) CompletionItem(org.eclipse.lsp4j.CompletionItem) List(java.util.List) Command(org.eclipse.lsp4j.Command) CallHierarchyOutgoingCallsParams(org.eclipse.lsp4j.CallHierarchyOutgoingCallsParams) DidOpenTextDocumentParams(org.eclipse.lsp4j.DidOpenTextDocumentParams) SemanticTokensWithRegistrationOptions(org.eclipse.lsp4j.SemanticTokensWithRegistrationOptions) InitializeParams(org.eclipse.lsp4j.InitializeParams) SortedMap(java.util.SortedMap) IntStream(java.util.stream.IntStream) CompletionParams(org.eclipse.lsp4j.CompletionParams) ServerInfo(org.eclipse.lsp4j.ServerInfo) FormatTokenInfo(lspserver.OberonFormatter.FormatTokenInfo) DocumentSymbolParams(org.eclipse.lsp4j.DocumentSymbolParams) ParamTag(lspserver.OberonFile.ParamTag) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Range(org.eclipse.lsp4j.Range) Function(java.util.function.Function) CallHierarchyItem(org.eclipse.lsp4j.CallHierarchyItem) SymbolInformation(org.eclipse.lsp4j.SymbolInformation) HashSet(java.util.HashSet) CallHierarchyIncomingCall(org.eclipse.lsp4j.CallHierarchyIncomingCall) CodeActionParams(org.eclipse.lsp4j.CodeActionParams) MessageParams(org.eclipse.lsp4j.MessageParams) Position(org.eclipse.lsp4j.Position) CompletionList(org.eclipse.lsp4j.CompletionList) NoSuchElementException(java.util.NoSuchElementException) DidChangeConfigurationParams(org.eclipse.lsp4j.DidChangeConfigurationParams) ExecutorService(java.util.concurrent.ExecutorService) TextDocumentSyncKind(org.eclipse.lsp4j.TextDocumentSyncKind) ParameterInformation(org.eclipse.lsp4j.ParameterInformation) IdentifierReference(lspserver.OberonFile.IdentifierReference) CodeActionKind(org.eclipse.lsp4j.CodeActionKind) Comparator(java.util.Comparator) Collections(java.util.Collections) DocumentSymbol(org.eclipse.lsp4j.DocumentSymbol) ReferenceParams(org.eclipse.lsp4j.ReferenceParams) FormatTokenInfo(lspserver.OberonFormatter.FormatTokenInfo) DocumentFormattingParams(org.eclipse.lsp4j.DocumentFormattingParams) ArrayList(java.util.ArrayList) CallHierarchyItem(org.eclipse.lsp4j.CallHierarchyItem) DidCloseTextDocumentParams(org.eclipse.lsp4j.DidCloseTextDocumentParams) DidOpenTextDocumentParams(org.eclipse.lsp4j.DidOpenTextDocumentParams) CodeActionParams(org.eclipse.lsp4j.CodeActionParams) Position(org.eclipse.lsp4j.Position) DocumentSymbolParams(org.eclipse.lsp4j.DocumentSymbolParams) WorkspaceEdit(org.eclipse.lsp4j.WorkspaceEdit) Two(org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two) FoldingRangeRequestParams(org.eclipse.lsp4j.FoldingRangeRequestParams) SignatureInformation(org.eclipse.lsp4j.SignatureInformation) Hover(org.eclipse.lsp4j.Hover) SortedMap(java.util.SortedMap) Map(java.util.Map) TreeMap(java.util.TreeMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) ParamTag(lspserver.OberonFile.ParamTag) CompletableFuture(java.util.concurrent.CompletableFuture) Either(org.eclipse.lsp4j.jsonrpc.messages.Either) ExecutionException(java.util.concurrent.ExecutionException) CallHierarchyOutgoingCallsParams(org.eclipse.lsp4j.CallHierarchyOutgoingCallsParams) SemanticTokens(org.eclipse.lsp4j.SemanticTokens) DefinitionParams(org.eclipse.lsp4j.DefinitionParams) DocumentHighlight(org.eclipse.lsp4j.DocumentHighlight) TreeMap(java.util.TreeMap) AnalysisResult(lspserver.OberonFile.AnalysisResult) IdentifierReference(lspserver.OberonFile.IdentifierReference) DocumentSymbol(org.eclipse.lsp4j.DocumentSymbol) DidChangeTextDocumentParams(org.eclipse.lsp4j.DidChangeTextDocumentParams) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) SymbolInformation(org.eclipse.lsp4j.SymbolInformation) SemanticTokensParams(org.eclipse.lsp4j.SemanticTokensParams) Identifier(lspserver.OberonFile.Identifier) CompletionParams(org.eclipse.lsp4j.CompletionParams) DocumentHighlightParams(org.eclipse.lsp4j.DocumentHighlightParams) ArrayList(java.util.ArrayList) List(java.util.List) CompletionList(org.eclipse.lsp4j.CompletionList) HashSet(java.util.HashSet) LinkedEditingRanges(org.eclipse.lsp4j.LinkedEditingRanges) DidSaveTextDocumentParams(org.eclipse.lsp4j.DidSaveTextDocumentParams) SignatureHelp(org.eclipse.lsp4j.SignatureHelp) FoldingRange(org.eclipse.lsp4j.FoldingRange) Range(org.eclipse.lsp4j.Range) FoldingRange(org.eclipse.lsp4j.FoldingRange) CallHierarchyIncomingCall(org.eclipse.lsp4j.CallHierarchyIncomingCall) CompletionItem(org.eclipse.lsp4j.CompletionItem) SignatureHelpParams(org.eclipse.lsp4j.SignatureHelpParams) LinkedEditingRangeParams(org.eclipse.lsp4j.LinkedEditingRangeParams) CallHierarchyIncomingCallsParams(org.eclipse.lsp4j.CallHierarchyIncomingCallsParams) ParameterInformation(org.eclipse.lsp4j.ParameterInformation) TextDocumentService(org.eclipse.lsp4j.services.TextDocumentService) Function(java.util.function.Function) ReferenceParams(org.eclipse.lsp4j.ReferenceParams) HoverParams(org.eclipse.lsp4j.HoverParams) RenameParams(org.eclipse.lsp4j.RenameParams) PrepareRenameParams(org.eclipse.lsp4j.PrepareRenameParams) CodeAction(org.eclipse.lsp4j.CodeAction) PrepareRenameParams(org.eclipse.lsp4j.PrepareRenameParams) MarkupContent(org.eclipse.lsp4j.MarkupContent) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) NoSuchElementException(java.util.NoSuchElementException) CallHierarchyPrepareParams(org.eclipse.lsp4j.CallHierarchyPrepareParams) CallHierarchyOutgoingCall(org.eclipse.lsp4j.CallHierarchyOutgoingCall) Command(org.eclipse.lsp4j.Command) TextEdit(org.eclipse.lsp4j.TextEdit) Location(org.eclipse.lsp4j.Location)

Example 4 with LinkedEditingRanges

use of org.eclipse.lsp4j.LinkedEditingRanges in project lsp4e by eclipse.

the class LSPLinkedEditingBase method collectLinkedEditingRanges.

protected CompletableFuture<LinkedEditingRanges> collectLinkedEditingRanges(IDocument document, int offset) {
    fLinkedEditingRanges = null;
    cancel();
    if (document == null) {
        return CompletableFuture.completedFuture(null);
    }
    Position position;
    try {
        position = LSPEclipseUtils.toPosition(offset, document);
    } catch (BadLocationException e) {
        LanguageServerPlugin.logError(e);
        return CompletableFuture.completedFuture(null);
    }
    URI uri = LSPEclipseUtils.toUri(document);
    if (uri == null) {
        return CompletableFuture.completedFuture(null);
    }
    TextDocumentIdentifier identifier = new TextDocumentIdentifier(uri.toString());
    TextDocumentPositionParams params = new TextDocumentPositionParams(identifier, position);
    AtomicReference<LinkedEditingRanges> range = new AtomicReference<>();
    return LanguageServiceAccessor.getLanguageServers(document, capabilities -> LSPEclipseUtils.hasCapability(capabilities.getLinkedEditingRangeProvider())).thenComposeAsync(languageServers -> CompletableFuture.allOf(languageServers.stream().map(ls -> ls.getTextDocumentService().linkedEditingRange(LSPEclipseUtils.toLinkedEditingRangeParams(params)).thenAcceptAsync(result -> {
        if (result != null && result.getRanges() != null && result.getRanges().size() > 1) {
            range.set(result);
        }
    })).toArray(CompletableFuture[]::new))).thenApplyAsync(theVoid -> range.get());
}
Also used : IPreferenceChangeListener(org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener) TextDocumentPositionParams(org.eclipse.lsp4j.TextDocumentPositionParams) CompletableFuture(java.util.concurrent.CompletableFuture) TextDocumentIdentifier(org.eclipse.lsp4j.TextDocumentIdentifier) AtomicReference(java.util.concurrent.atomic.AtomicReference) LSPEclipseUtils(org.eclipse.lsp4e.LSPEclipseUtils) IDocument(org.eclipse.jface.text.IDocument) InstanceScope(org.eclipse.core.runtime.preferences.InstanceScope) PreferenceChangeEvent(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) IEclipsePreferences(org.eclipse.core.runtime.preferences.IEclipsePreferences) BadLocationException(org.eclipse.jface.text.BadLocationException) Position(org.eclipse.lsp4j.Position) URI(java.net.URI) LanguageServerPlugin(org.eclipse.lsp4e.LanguageServerPlugin) LanguageServiceAccessor(org.eclipse.lsp4e.LanguageServiceAccessor) LinkedEditingRanges(org.eclipse.lsp4j.LinkedEditingRanges) TextDocumentIdentifier(org.eclipse.lsp4j.TextDocumentIdentifier) CompletableFuture(java.util.concurrent.CompletableFuture) Position(org.eclipse.lsp4j.Position) AtomicReference(java.util.concurrent.atomic.AtomicReference) TextDocumentPositionParams(org.eclipse.lsp4j.TextDocumentPositionParams) URI(java.net.URI) BadLocationException(org.eclipse.jface.text.BadLocationException) LinkedEditingRanges(org.eclipse.lsp4j.LinkedEditingRanges)

Example 5 with LinkedEditingRanges

use of org.eclipse.lsp4j.LinkedEditingRanges in project quarkus-ls by redhat-developer.

the class QuteAssert method testLinkedEditingFor.

public static void testLinkedEditingFor(String value, String fileUri, String projectUri, String templateBaseDir, LinkedEditingRanges expected) throws BadLocationException {
    int offset = value.indexOf('|');
    value = value.substring(0, offset) + value.substring(offset + 1);
    QuteProjectRegistry projectRegistry = new MockQuteProjectRegistry();
    Template template = createTemplate(value, fileUri, projectUri, templateBaseDir, projectRegistry);
    QuteLanguageService languageService = new QuteLanguageService(new JavaDataModelCache(projectRegistry));
    Position position = template.positionAt(offset);
    LinkedEditingRanges actual = languageService.findLinkedEditingRanges(template, position, () -> {
    });
    assertLinkedEditing(actual, expected);
}
Also used : JavaDataModelCache(com.redhat.qute.project.datamodel.JavaDataModelCache) Position(org.eclipse.lsp4j.Position) QuteProjectRegistry(com.redhat.qute.project.QuteProjectRegistry) MockQuteProjectRegistry(com.redhat.qute.project.MockQuteProjectRegistry) QuteLanguageService(com.redhat.qute.services.QuteLanguageService) MockQuteProjectRegistry(com.redhat.qute.project.MockQuteProjectRegistry) Template(com.redhat.qute.parser.template.Template) LinkedEditingRanges(org.eclipse.lsp4j.LinkedEditingRanges)

Aggregations

LinkedEditingRanges (org.eclipse.lsp4j.LinkedEditingRanges)7 Position (org.eclipse.lsp4j.Position)4 ArrayList (java.util.ArrayList)3 Range (org.eclipse.lsp4j.Range)3 HashMap (java.util.HashMap)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 IDocument (org.eclipse.jface.text.IDocument)2 LinkedEditingRangeParams (org.eclipse.lsp4j.LinkedEditingRangeParams)2 JsonArray (com.google.gson.JsonArray)1 BadLocationException (com.redhat.qute.ls.commons.BadLocationException)1 Node (com.redhat.qute.parser.template.Node)1 Template (com.redhat.qute.parser.template.Template)1 MockQuteProjectRegistry (com.redhat.qute.project.MockQuteProjectRegistry)1 QuteProjectRegistry (com.redhat.qute.project.QuteProjectRegistry)1 JavaDataModelCache (com.redhat.qute.project.datamodel.JavaDataModelCache)1 QuteLanguageService (com.redhat.qute.services.QuteLanguageService)1 IOException (java.io.IOException)1 URI (java.net.URI)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1