Merge branch 'master' into jdt-classpath
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bosh-yaml",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"description": "Provides validation and content assist for various Bosh configuration files",
|
||||
"repository": "https://github.com/spring-projects/atom-bosh",
|
||||
"icon": "icon.png",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cf-manifest-yaml",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"description": "Cloud Foundry Deployment Manifest YAML support for Atom",
|
||||
"repository": "https://github.com/spring-projects/atom-cf-manifest-yaml",
|
||||
"icon": "icon.png",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "concourse-pipeline-yaml",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"description": "Provides validation and content assist for Concourse CI pipeline and task configuration yml files",
|
||||
"repository": "https://github.com/spring-projects/atom-concourse",
|
||||
"icon": "icon.png",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "spring-boot",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"description": "Spring Boot support for Atom",
|
||||
"repository": "https://github.com/spring-projects/atom-spring-boot",
|
||||
"icon": "icon.png",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"jarUrl": "https://s3-us-west-1.amazonaws.com/s3-test.spring.io/sts4/fatjars/snapshots/spring-boot-language-server-0.1.5-201803051440.jar"
|
||||
"jarUrl": "https://s3-us-west-1.amazonaws.com/s3-test.spring.io/sts4/fatjars/snapshots/spring-boot-language-server-0.1.5-201803091709.jar"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.DocumentHighlight;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DocumentHighlightHandler {
|
||||
|
||||
List<? extends DocumentHighlight> handle(TextDocumentPositionParams position);
|
||||
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -355,6 +354,9 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
if (hasDocumentSymbolHandler()) {
|
||||
c.setDocumentSymbolProvider(true);
|
||||
}
|
||||
if (hasDocumentHighlightHandler()) {
|
||||
c.setDocumentHighlightProvider(true);
|
||||
}
|
||||
if (hasCodeLensHandler()) {
|
||||
CodeLensOptions codeLensOptions = new CodeLensOptions();
|
||||
codeLensOptions.setResolveProvider(hasCodeLensResolveProvider());
|
||||
@@ -389,6 +391,10 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
return getTextDocumentService().hasDocumentSymbolHandler();
|
||||
}
|
||||
|
||||
private boolean hasDocumentHighlightHandler() {
|
||||
return getTextDocumentService().hasDocumentHighlightHandler();
|
||||
}
|
||||
|
||||
private boolean hasCodeLensHandler() {
|
||||
return getTextDocumentService().hasCodeLensHandler();
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
private DefinitionHandler definitionHandler;
|
||||
private ReferencesHandler referencesHandler;
|
||||
private DocumentSymbolHandler documentSymbolHandler;
|
||||
private DocumentHighlightHandler documentHighlightHandler;
|
||||
|
||||
private CodeLensHandler codeLensHandler;
|
||||
private CodeLensResolveHandler codeLensResolveHandler;
|
||||
@@ -109,6 +110,11 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
this.documentSymbolHandler = h;
|
||||
}
|
||||
|
||||
public synchronized void onDocumentHighlight(DocumentHighlightHandler h) {
|
||||
Assert.isNull("A DocumentHighlightHandler is already set, multiple handlers not supported yet", documentHighlightHandler);
|
||||
this.documentHighlightHandler = h;
|
||||
}
|
||||
|
||||
public synchronized void onCompletion(CompletionHandler h) {
|
||||
Assert.isNull("A completion handler is already set, multiple handlers not supported yet", completionHandler);
|
||||
this.completionHandler = h;
|
||||
@@ -260,6 +266,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
public final static List<? extends Location> NO_REFERENCES = ImmutableList.of();
|
||||
public final static List<? extends SymbolInformation> NO_SYMBOLS = ImmutableList.of();
|
||||
public final static List<? extends CodeLens> NO_CODELENS = ImmutableList.of();
|
||||
public final static List<DocumentHighlight> NO_HIGHLIGHTS = ImmutableList.of();
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(TextDocumentPositionParams position) {
|
||||
@@ -437,7 +444,13 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(TextDocumentPositionParams position) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
return async.invoke(() -> {
|
||||
DocumentHighlightHandler handler = this.documentHighlightHandler;
|
||||
if (handler != null) {
|
||||
return handler.handle(position);
|
||||
}
|
||||
return NO_HIGHLIGHTS;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean hasDefinitionHandler() {
|
||||
@@ -452,6 +465,10 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
return this.documentSymbolHandler!=null;
|
||||
}
|
||||
|
||||
public boolean hasDocumentHighlightHandler() {
|
||||
return this.documentHighlightHandler!=null;
|
||||
}
|
||||
|
||||
public boolean hasCodeLensHandler() {
|
||||
return this.codeLensHandler != null;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<name>commons-parent</name>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<version>0.2.0-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -27,12 +27,14 @@ import org.springframework.ide.vscode.boot.java.conditionals.ConditionalsLiveHov
|
||||
import org.springframework.ide.vscode.boot.java.data.DataRepositorySymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCodeLensEngine;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCompletionEngine;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaDocumentHighlightEngine;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaDocumentSymbolHandler;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaReferencesHandler;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaWorkspaceSymbolHandler;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.CodeLensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.CompletionProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.HighlightProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.HoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider;
|
||||
@@ -44,6 +46,7 @@ import org.springframework.ide.vscode.boot.java.requestmapping.LiveAppURLSymbolP
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxHandlerCodeLensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxRouteHighlightProdivder;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxRouterSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.scope.ScopeCompletionProcessor;
|
||||
import org.springframework.ide.vscode.boot.java.snippets.JavaSnippet;
|
||||
@@ -61,6 +64,7 @@ import org.springframework.ide.vscode.commons.languageserver.composable.Language
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.CodeLensHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentHighlightHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.LSFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.ReferencesHandler;
|
||||
@@ -94,6 +98,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
private JavaProjectFinder projectFinder;
|
||||
private BootJavaHoverProvider hoverProvider;
|
||||
private CodeLensHandler codeLensHandler;
|
||||
private DocumentHighlightHandler highlightsEngine;
|
||||
|
||||
public BootJavaLanguageServerComponents(SimpleLanguageServer server, LSFactory<BootLanguageServerParams> _params) {
|
||||
this.server = server;
|
||||
@@ -151,7 +156,10 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
|
||||
codeLensHandler = createCodeLensEngine();
|
||||
documents.onCodeLens(codeLensHandler);
|
||||
|
||||
|
||||
highlightsEngine = createDocumentHighlightEngine();
|
||||
documents.onDocumentHighlight(highlightsEngine);
|
||||
|
||||
workspaceService.onDidChangeConfiguraton(settings -> {
|
||||
config.handleConfigurationChange(settings);
|
||||
if (config.isBootHintsEnabled()) {
|
||||
@@ -180,6 +188,10 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
return codeLensHandler;
|
||||
}
|
||||
|
||||
public DocumentHighlightHandler getDocumentHighlightHandler() {
|
||||
return highlightsEngine;
|
||||
}
|
||||
|
||||
private void initialize(InitializeParams params) {
|
||||
this.indexer.initialize(server.getWorkspaceRoots());
|
||||
}
|
||||
@@ -314,6 +326,13 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
|
||||
return new BootJavaCodeLensEngine(this, codeLensProvider);
|
||||
}
|
||||
|
||||
protected BootJavaDocumentHighlightEngine createDocumentHighlightEngine() {
|
||||
Collection<HighlightProvider> highlightProvider = new ArrayList<>();
|
||||
highlightProvider.add(new WebfluxRouteHighlightProdivder(this));
|
||||
|
||||
return new BootJavaDocumentHighlightEngine(this, highlightProvider);
|
||||
}
|
||||
|
||||
public ProjectObserver getProjectObserver() {
|
||||
return projectObserver;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.DocumentHighlight;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentHighlightHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class BootJavaDocumentHighlightEngine implements DocumentHighlightHandler {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(BootJavaDocumentHighlightEngine.class);
|
||||
|
||||
private BootJavaLanguageServerComponents server;
|
||||
private Collection<HighlightProvider> highlightProviders;
|
||||
|
||||
public BootJavaDocumentHighlightEngine(BootJavaLanguageServerComponents server, Collection<HighlightProvider> highlightProviders) {
|
||||
this.server = server;
|
||||
this.highlightProviders = highlightProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DocumentHighlight> handle(TextDocumentPositionParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
String docURI = params.getTextDocument().getUri();
|
||||
|
||||
if (documents.get(docURI) != null) {
|
||||
TextDocument doc = documents.get(docURI).copy();
|
||||
try {
|
||||
return provideDocumentHighlights(doc, params.getPosition());
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
|
||||
return SimpleTextDocumentService.NO_HIGHLIGHTS;
|
||||
}
|
||||
|
||||
private List<DocumentHighlight> provideDocumentHighlights(TextDocument document, Position position) {
|
||||
List<DocumentHighlight> result = new ArrayList<>();
|
||||
for (HighlightProvider highlightProvider : highlightProviders) {
|
||||
highlightProvider.provideHighlights(document, position, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,9 +18,9 @@ import org.eclipse.lsp4j.SymbolInformation;
|
||||
public class EnhancedSymbolInformation {
|
||||
|
||||
private final SymbolInformation symbol;
|
||||
private final Object additionalInformation;
|
||||
private final SymbolAddOnInformation[] additionalInformation;
|
||||
|
||||
public EnhancedSymbolInformation(SymbolInformation symbol, Object additionalInformation) {
|
||||
public EnhancedSymbolInformation(SymbolInformation symbol, SymbolAddOnInformation[] additionalInformation) {
|
||||
this.symbol = symbol;
|
||||
this.additionalInformation = additionalInformation;
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public class EnhancedSymbolInformation {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public Object getAdditionalInformation() {
|
||||
public SymbolAddOnInformation[] getAdditionalInformation() {
|
||||
return additionalInformation;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.DocumentHighlight;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public interface HighlightProvider {
|
||||
|
||||
public void provideHighlights(TextDocument document, Position position, List<DocumentHighlight> resultAccumulator);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public interface SymbolAddOnInformation {
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.links;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
/**
|
||||
* Source links for Atom client
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class AtomSourceLinks extends AbstractSourceLinks {
|
||||
|
||||
private static Supplier<Logger> LOG = Suppliers.memoize(() -> LoggerFactory.getLogger(AbstractSourceLinks.class));
|
||||
|
||||
public AtomSourceLinks(BootJavaLanguageServerComponents server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> sourceLinkForResourcePath(Path path) {
|
||||
try {
|
||||
return Optional.of("atom://core/open/file?filename=" + URLEncoder.encode(path.toString(), "UTF8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LOG.get().error("Cannot build source URL for " + path, e);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String positionLink(CompilationUnit cu, String fqName) {
|
||||
if (cu != null) {
|
||||
Region region = findTypeRegion(cu, fqName);
|
||||
if (region != null) {
|
||||
int column = cu.getColumnNumber(region.getOffset());
|
||||
int line = cu.getLineNumber(region.getOffset());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("&line=");
|
||||
sb.append(line);
|
||||
sb.append("&column=");
|
||||
sb.append(column + 1); // 1-based columns?
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> jarUrl(IJavaProject project, String fqName, File jarFile) {
|
||||
// JAR URLs are not supported yet
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,6 +55,8 @@ public final class SourceLinkFactory {
|
||||
return new VSCodeSourceLinks(server);
|
||||
case ECLIPSE:
|
||||
return new EclipseSourceLinks();
|
||||
case ATOM:
|
||||
return new AtomSourceLinks(server);
|
||||
default:
|
||||
return NO_SOURCE_LINKS;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -21,7 +22,7 @@ import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformati
|
||||
public class RouteUtils {
|
||||
|
||||
public static EnhancedSymbolInformation createRouteSymbol(Location location, String path,
|
||||
String[] httpMethods, String[] contentTypes, String[] acceptTypes, Object enhancedInformation) {
|
||||
String[] httpMethods, String[] contentTypes, String[] acceptTypes, SymbolAddOnInformation[] enhancedInformation) {
|
||||
|
||||
if (path != null && path.length() > 0) {
|
||||
String label = "@" + (path.startsWith("/") ? path : ("/" + path));
|
||||
|
||||
@@ -10,41 +10,53 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxAcceptTypeFinder extends ASTVisitor {
|
||||
|
||||
private Set<String> acceptTypes;
|
||||
private List<WebfluxRouteElement> acceptTypes;
|
||||
private TextDocument doc;
|
||||
|
||||
public WebfluxAcceptTypeFinder() {
|
||||
this.acceptTypes = new LinkedHashSet<>();
|
||||
public WebfluxAcceptTypeFinder(TextDocument doc) {
|
||||
this.doc = doc;
|
||||
this.acceptTypes = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Set<String> getAcceptTypes() {
|
||||
public List<WebfluxRouteElement> getAcceptTypes() {
|
||||
return acceptTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(name)) {
|
||||
String acceptType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (acceptType != null) {
|
||||
acceptTypes.add(acceptType);
|
||||
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(name)) {
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
acceptTypes.add(new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return !WebfluxUtils.isRouteMethodInvocation(methodBinding);
|
||||
}
|
||||
|
||||
@@ -10,53 +10,55 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxContentTypeFinder extends ASTVisitor {
|
||||
|
||||
private Set<String> contentTypes;
|
||||
private ASTNode root;
|
||||
private List<WebfluxRouteElement> contentTypes;
|
||||
private TextDocument doc;
|
||||
|
||||
public WebfluxContentTypeFinder(ASTNode root) {
|
||||
this.root = root;
|
||||
this.contentTypes = new LinkedHashSet<>();
|
||||
public WebfluxContentTypeFinder(TextDocument doc) {
|
||||
this.doc = doc;
|
||||
this.contentTypes = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Set<String> getContentTypes() {
|
||||
public List<WebfluxRouteElement> getContentTypes() {
|
||||
return contentTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
boolean visitChildren = true;
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (node != this.root) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(name)) {
|
||||
String contentType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (contentType != null) {
|
||||
contentTypes.add(contentType);
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
contentTypes.add(new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
visitChildren = false;
|
||||
}
|
||||
}
|
||||
return visitChildren;
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return !WebfluxUtils.isRouteMethodInvocation(methodBinding);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxElementsInformation implements SymbolAddOnInformation {
|
||||
|
||||
private Range[] ranges;
|
||||
|
||||
public WebfluxElementsInformation(Range... ranges) {
|
||||
this.ranges = ranges;
|
||||
}
|
||||
|
||||
public Range[] getRanges() {
|
||||
return ranges;
|
||||
}
|
||||
|
||||
public boolean contains(Position position) {
|
||||
for (Range range : ranges) {
|
||||
if (isEqualOrBefore(range.getStart(), position) && isEqualsOrBehind(range.getEnd(), position)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if position1 is the same or before position2 in a document
|
||||
*/
|
||||
protected boolean isEqualOrBefore(Position position1, Position position2) {
|
||||
if (position1.getLine() < position2.getLine()) return true;
|
||||
if (position1.getLine() == position2.getLine() && position1.getCharacter() <= position2.getCharacter()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if position1 is the same or behind position2 in a document
|
||||
*/
|
||||
protected boolean isEqualsOrBehind(Position position1, Position position2) {
|
||||
if (position1.getLine() > position2.getLine()) return true;
|
||||
if (position1.getLine() == position2.getLine() && position1.getCharacter() >= position2.getCharacter()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.Command;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.CodeLensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexer;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -55,7 +56,7 @@ public class WebfluxHandlerCodeLensProvider implements CodeLensProvider {
|
||||
final String handlerClass = methodBinding.getDeclaringClass().getBinaryName().trim();
|
||||
final String handlerMethod = methodBinding.getMethodDeclaration().toString().trim();
|
||||
|
||||
List<Object> handlerInfos = this.springIndexer.getAllAdditionalInformation((addon) -> {
|
||||
List<SymbolAddOnInformation> handlerInfos = this.springIndexer.getAllAdditionalInformation((addon) -> {
|
||||
if (addon instanceof WebfluxHandlerInformation) {
|
||||
WebfluxHandlerInformation handlerInfo = (WebfluxHandlerInformation) addon;
|
||||
return handlerInfo.getHandlerClass() != null && handlerInfo.getHandlerClass().equals(handlerClass)
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxHandlerInformation {
|
||||
public class WebfluxHandlerInformation implements SymbolAddOnInformation {
|
||||
|
||||
private final String handlerClass;
|
||||
private final String handlerMethod;
|
||||
|
||||
@@ -10,28 +10,34 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxMethodFinder extends ASTVisitor {
|
||||
|
||||
private Set<String> methods;
|
||||
private List<WebfluxRouteElement> methods;
|
||||
private ASTNode root;
|
||||
private TextDocument doc;
|
||||
|
||||
public WebfluxMethodFinder(ASTNode root) {
|
||||
public WebfluxMethodFinder(ASTNode root, TextDocument doc) {
|
||||
this.root = root;
|
||||
this.methods = new LinkedHashSet<>();
|
||||
this.doc = doc;
|
||||
this.methods = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Set<String> getMethods() {
|
||||
public List<WebfluxRouteElement> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
@@ -42,15 +48,25 @@ public class WebfluxMethodFinder extends ASTVisitor {
|
||||
if (node != this.root) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_HTTPMETHOD_METHODS.contains(name)) {
|
||||
methods.add(name);
|
||||
}
|
||||
else if (name != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(name)) {
|
||||
methods.add(WebfluxUtils.extractQualifiedNameArgument(node));
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_HTTPMETHOD_METHODS.contains(name)) {
|
||||
Range range = doc.toRange(node.getStartPosition(), node.getLength());
|
||||
methods.add(new WebfluxRouteElement(name, range));
|
||||
}
|
||||
else if (name != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(name)) {
|
||||
QualifiedName qualifiedName = WebfluxUtils.extractQualifiedNameArgument(node);
|
||||
if (qualifiedName.getName() != null) {
|
||||
Range range = doc.toRange(qualifiedName.getStartPosition(), qualifiedName.getLength());
|
||||
methods.add(new WebfluxRouteElement(qualifiedName.getName().toString(), range));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
visitChildren = false;
|
||||
|
||||
@@ -10,24 +10,34 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxPathFinder extends ASTVisitor {
|
||||
|
||||
private String path;
|
||||
private List<WebfluxRouteElement> path;
|
||||
private ASTNode root;
|
||||
private TextDocument doc;
|
||||
|
||||
public WebfluxPathFinder(ASTNode root) {
|
||||
public WebfluxPathFinder(ASTNode root, TextDocument doc) {
|
||||
this.root = root;
|
||||
this.doc = doc;
|
||||
this.path = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
public List<WebfluxRouteElement> getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -38,12 +48,21 @@ public class WebfluxPathFinder extends ASTVisitor {
|
||||
if (node != this.root) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ALL_PATH_METHODS.contains(name)) {
|
||||
path = WebfluxUtils.extractStringLiteralArgument(node);
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ALL_PATH_METHODS.contains(name)) {
|
||||
StringLiteral stringLiteral = WebfluxUtils.extractStringLiteralArgument(node);
|
||||
if (stringLiteral != null) {
|
||||
Range range = doc.toRange(stringLiteral.getStartPosition(), stringLiteral.getLength());
|
||||
path.add(new WebfluxRouteElement(stringLiteral.getLiteralValue(), range));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
visitChildren = false;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import org.eclipse.lsp4j.Range;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxRouteElement {
|
||||
|
||||
private String element;
|
||||
private Range elementRange;
|
||||
|
||||
public WebfluxRouteElement(String element, Range elementRange) {
|
||||
super();
|
||||
this.element = element;
|
||||
this.elementRange = elementRange;
|
||||
}
|
||||
|
||||
public String getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public Range getElementRange() {
|
||||
return elementRange;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.DocumentHighlight;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.HighlightProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexer;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxRouteHighlightProdivder implements HighlightProvider {
|
||||
|
||||
private final SpringIndexer springIndexer;
|
||||
|
||||
public WebfluxRouteHighlightProdivder(BootJavaLanguageServerComponents bootJavaLanguageServerComponents) {
|
||||
this.springIndexer = bootJavaLanguageServerComponents.getSpringIndexer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideHighlights(TextDocument document, Position position, List<DocumentHighlight> resultAccumulator) {
|
||||
System.out.println(" PROVIDE HIGHLIGHTS: " + position.getLine() + "/" + position.getCharacter());
|
||||
|
||||
this.springIndexer.getAdditonalInformation(document.getUri())
|
||||
.stream()
|
||||
.filter(addon -> {
|
||||
if (addon instanceof WebfluxElementsInformation) {
|
||||
WebfluxElementsInformation handlerInfo = (WebfluxElementsInformation) addon;
|
||||
|
||||
if (handlerInfo.contains(position)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.flatMap(addon -> Arrays.asList(((WebfluxElementsInformation) addon).getRanges()).stream())
|
||||
.forEach(range -> resultAccumulator.add(new DocumentHighlight(range)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,6 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
@@ -25,10 +24,15 @@ import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.jdt.core.dom.Type;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -87,22 +91,30 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
|
||||
protected void extractMappingSymbol(MethodInvocation node, TextDocument doc, List<EnhancedSymbolInformation> result) {
|
||||
String path = extractPath(node);
|
||||
|
||||
String[] httpMethods = extractMethods(node);
|
||||
String[] contentTypes = extractContentTypes(node);
|
||||
String[] acceptTypes = extractAcceptTypes(node);
|
||||
WebfluxRouteElement[] pathElements = extractPath(node, doc);
|
||||
WebfluxRouteElement[] httpMethods = extractMethods(node, doc);
|
||||
WebfluxRouteElement[] contentTypes = extractContentTypes(node, doc);
|
||||
WebfluxRouteElement[] acceptTypes = extractAcceptTypes(node, doc);
|
||||
|
||||
int methodNameStart = node.getName().getStartPosition();
|
||||
int invocationStart = node.getStartPosition();
|
||||
|
||||
if (path != null && path.length() > 0) {
|
||||
StringBuilder pathBuilder = new StringBuilder();
|
||||
for (WebfluxRouteElement pathElement : pathElements) {
|
||||
pathBuilder.insert(0, pathElement.getElement());
|
||||
}
|
||||
|
||||
String path = pathBuilder.toString();
|
||||
|
||||
if (path.length() > 0) {
|
||||
try {
|
||||
|
||||
Location location = new Location(doc.getUri(), doc.toRange(methodNameStart, node.getLength() - (methodNameStart - invocationStart)));
|
||||
WebfluxHandlerInformation handler = extractHandlerInformation(node, path, httpMethods, contentTypes, acceptTypes);
|
||||
WebfluxElementsInformation elements = extractElementsInformation(pathElements, httpMethods, contentTypes, acceptTypes);
|
||||
|
||||
result.add(RouteUtils.createRouteSymbol(location, path, httpMethods, contentTypes, acceptTypes, handler));
|
||||
result.add(RouteUtils.createRouteSymbol(location, path, getElementStrings(httpMethods),
|
||||
getElementStrings(contentTypes), getElementStrings(acceptTypes), new SymbolAddOnInformation[] {handler, elements}));
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
e.printStackTrace();
|
||||
@@ -110,38 +122,55 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private String extractPath(MethodInvocation routerInvocation) {
|
||||
WebfluxPathFinder pathFinder = new WebfluxPathFinder(routerInvocation);
|
||||
routerInvocation.accept(pathFinder);
|
||||
private WebfluxElementsInformation extractElementsInformation(WebfluxRouteElement[] path, WebfluxRouteElement[] methods,
|
||||
WebfluxRouteElement[] contentTypes, WebfluxRouteElement[] acceptTypes) {
|
||||
List<Range> allRanges = new ArrayList<>();
|
||||
|
||||
List<String> path = new ArrayList<>();
|
||||
String firstPath = pathFinder.getPath();
|
||||
if (firstPath != null) {
|
||||
path.add(firstPath);
|
||||
WebfluxRouteElement[][] allElements = new WebfluxRouteElement[][] {path, methods, contentTypes, acceptTypes};
|
||||
for (int i = 0; i < allElements.length; i++) {
|
||||
for (int j = 0; j < allElements[i].length; j++) {
|
||||
allRanges.add(allElements[i][j].getElementRange());
|
||||
}
|
||||
}
|
||||
|
||||
return new WebfluxElementsInformation((Range[]) allRanges.toArray(new Range[allRanges.size()]));
|
||||
}
|
||||
|
||||
private WebfluxRouteElement[] extractPath(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxPathFinder pathFinder = new WebfluxPathFinder(routerInvocation, doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(pathFinder);
|
||||
}
|
||||
}
|
||||
|
||||
List<WebfluxRouteElement> path = pathFinder.getPath();
|
||||
|
||||
extractNestedValue(routerInvocation, path, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_PATH_METHOD.equals(methodName)) {
|
||||
String additionalPath = WebfluxUtils.extractStringLiteralArgument(methodInvocation);
|
||||
if (additionalPath != null && additionalPath.length() > 0) {
|
||||
return additionalPath;
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_PATH_METHOD.equals(methodName)) {
|
||||
StringLiteral stringLiteral = WebfluxUtils.extractStringLiteralArgument(methodInvocation);
|
||||
if (stringLiteral != null) {
|
||||
Range range = doc.toRange(stringLiteral.getStartPosition(), stringLiteral.getLength());
|
||||
return new WebfluxRouteElement(stringLiteral.getLiteralValue(), range);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
path.stream().forEach(part -> result.insert(0, part));
|
||||
|
||||
return result.toString();
|
||||
|
||||
return (WebfluxRouteElement[]) path.toArray(new WebfluxRouteElement[path.size()]);
|
||||
}
|
||||
|
||||
private String[] extractMethods(MethodInvocation routerInvocation) {
|
||||
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation);
|
||||
private WebfluxRouteElement[] extractMethods(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation, doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
@@ -149,23 +178,33 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
final Set<String> methods = methodFinder.getMethods();
|
||||
final List<WebfluxRouteElement> methods = methodFinder.getMethods();
|
||||
|
||||
extractNestedValue(routerInvocation, methods, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(methodName)) {
|
||||
return WebfluxUtils.extractQualifiedNameArgument(methodInvocation);
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(methodName)) {
|
||||
QualifiedName qualifiedName = WebfluxUtils.extractQualifiedNameArgument(methodInvocation);
|
||||
if (qualifiedName.getName() != null) {
|
||||
Range range = doc.toRange(qualifiedName.getStartPosition(), qualifiedName.getLength());
|
||||
return new WebfluxRouteElement(qualifiedName.getName().toString(), range);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) methods.toArray(new String[methods.size()]);
|
||||
return (WebfluxRouteElement[]) methods.toArray(new WebfluxRouteElement[methods.size()]);
|
||||
}
|
||||
|
||||
private String[] extractAcceptTypes(MethodInvocation routerInvocation) {
|
||||
WebfluxAcceptTypeFinder typeFinder = new WebfluxAcceptTypeFinder();
|
||||
private WebfluxRouteElement[] extractAcceptTypes(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxAcceptTypeFinder typeFinder = new WebfluxAcceptTypeFinder(doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
@@ -173,23 +212,33 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> acceptTypes = typeFinder.getAcceptTypes();
|
||||
final List<WebfluxRouteElement> acceptTypes = typeFinder.getAcceptTypes();
|
||||
|
||||
extractNestedValue(routerInvocation, acceptTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(methodName)) {
|
||||
return WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(methodName)) {
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
return new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) acceptTypes.toArray(new String[acceptTypes.size()]);
|
||||
return (WebfluxRouteElement[]) acceptTypes.toArray(new WebfluxRouteElement[acceptTypes.size()]);
|
||||
}
|
||||
|
||||
private String[] extractContentTypes(MethodInvocation routerInvocation) {
|
||||
WebfluxContentTypeFinder contentTypeFinder = new WebfluxContentTypeFinder(routerInvocation);
|
||||
private WebfluxRouteElement[] extractContentTypes(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxContentTypeFinder contentTypeFinder = new WebfluxContentTypeFinder(doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
@@ -197,22 +246,32 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> contentTypes = contentTypeFinder.getContentTypes();
|
||||
final List<WebfluxRouteElement> contentTypes = contentTypeFinder.getContentTypes();
|
||||
|
||||
extractNestedValue(routerInvocation, contentTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(methodName)) {
|
||||
return WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(methodName)) {
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
return new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) contentTypes.toArray(new String[contentTypes.size()]);
|
||||
return (WebfluxRouteElement[]) contentTypes.toArray(new WebfluxRouteElement[contentTypes.size()]);
|
||||
}
|
||||
|
||||
private void extractNestedValue(ASTNode node, Collection<String> values, Function<MethodInvocation, String> extractor) {
|
||||
private void extractNestedValue(ASTNode node, Collection<WebfluxRouteElement> values, Function<MethodInvocation, WebfluxRouteElement> extractor) {
|
||||
if (node == null || node instanceof TypeDeclaration) {
|
||||
return;
|
||||
}
|
||||
@@ -228,7 +287,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
for (Object argument : arguments) {
|
||||
if (argument instanceof MethodInvocation) {
|
||||
MethodInvocation nestedMethod = (MethodInvocation) argument;
|
||||
String value = extractor.apply(nestedMethod);
|
||||
WebfluxRouteElement value = extractor.apply(nestedMethod);
|
||||
if (value != null) {
|
||||
values.add(value);
|
||||
}
|
||||
@@ -241,7 +300,9 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
extractNestedValue(node.getParent(), values, extractor);
|
||||
}
|
||||
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String path, String[] httpMethods, String[] contentTypes, String[] acceptTypes) {
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String path, WebfluxRouteElement[] httpMethods,
|
||||
WebfluxRouteElement[] contentTypes, WebfluxRouteElement[] acceptTypes) {
|
||||
|
||||
List<?> arguments = node.arguments();
|
||||
|
||||
if (arguments != null) {
|
||||
@@ -257,7 +318,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
String handlerMethod = methodBinding.getMethodDeclaration().toString();
|
||||
if (handlerMethod != null) handlerMethod = handlerMethod.trim();
|
||||
|
||||
return new WebfluxHandlerInformation(handlerClass, handlerMethod, path, httpMethods, contentTypes, acceptTypes);
|
||||
return new WebfluxHandlerInformation(handlerClass, handlerMethod, path, getElementStrings(httpMethods), getElementStrings(contentTypes), getElementStrings(acceptTypes));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,5 +326,15 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getElementStrings(WebfluxRouteElement[] routeElements) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < routeElements.length; i++) {
|
||||
result.add(routeElements[i].getElement());
|
||||
}
|
||||
|
||||
return (String[]) result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,41 +41,34 @@ public class WebfluxUtils {
|
||||
public static final Set<String> REQUEST_PREDICATE_ALL_PATH_METHODS = new HashSet<>(Arrays.asList(REQUEST_PREDICATE_PATH_METHOD, "GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
|
||||
|
||||
|
||||
public static String extractStringLiteralArgument(MethodInvocation node) {
|
||||
public static StringLiteral extractStringLiteralArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof StringLiteral) {
|
||||
String path = ((StringLiteral) object).getLiteralValue();
|
||||
return path;
|
||||
return (StringLiteral) object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String extractQualifiedNameArgument(MethodInvocation node) {
|
||||
public static QualifiedName extractQualifiedNameArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof QualifiedName) {
|
||||
QualifiedName qualifiedName = (QualifiedName) object;
|
||||
if (qualifiedName.getName() != null) {
|
||||
return qualifiedName.getName().toString();
|
||||
}
|
||||
return (QualifiedName) object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String extractSimpleNameArgument(MethodInvocation node) {
|
||||
public static SimpleName extractSimpleNameArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof SimpleName) {
|
||||
SimpleName name = (SimpleName) object;
|
||||
if (name.getFullyQualifiedName() != null) {
|
||||
return name.getFullyQualifiedName().toString();
|
||||
}
|
||||
return (SimpleName) object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -58,6 +58,7 @@ import org.springframework.ide.vscode.boot.BootLanguageServerParams;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
@@ -82,9 +83,10 @@ public class SpringIndexer {
|
||||
private final AnnotationHierarchyAwareLookup<SymbolProvider> symbolProviders;
|
||||
|
||||
private final List<SymbolInformation> symbols;
|
||||
private final List<Object> addonInformation;
|
||||
private final List<SymbolAddOnInformation> addonInformation;
|
||||
|
||||
private final ConcurrentMap<String, List<SymbolInformation>> symbolsByDoc;
|
||||
private final ConcurrentMap<String, List<Object>> addonInformationByDoc;
|
||||
private final ConcurrentMap<String, List<SymbolAddOnInformation>> addonInformationByDoc;
|
||||
|
||||
private final Thread updateWorker;
|
||||
private final BlockingQueue<WorkerItem> updateQueue;
|
||||
@@ -314,7 +316,7 @@ public class SpringIndexer {
|
||||
return this.symbolsByDoc.get(docURI);
|
||||
}
|
||||
|
||||
public List<Object> getAllAdditionalInformation(Predicate<Object> filter) {
|
||||
public List<SymbolAddOnInformation> getAllAdditionalInformation(Predicate<SymbolAddOnInformation> filter) {
|
||||
waitForInitializeTask();
|
||||
|
||||
if (filter != null) {
|
||||
@@ -325,7 +327,7 @@ public class SpringIndexer {
|
||||
}
|
||||
}
|
||||
|
||||
public List<? extends Object> getAdditonalInformation(String docURI) {
|
||||
public List<? extends SymbolAddOnInformation> getAdditonalInformation(String docURI) {
|
||||
waitForInitializeTask();
|
||||
return this.addonInformationByDoc.get(docURI);
|
||||
}
|
||||
@@ -390,9 +392,9 @@ public class SpringIndexer {
|
||||
symbols.removeAll(oldSymbols);
|
||||
}
|
||||
|
||||
List<Object> oldAddInInformation = addonInformationByDoc.remove(docURI);
|
||||
if (oldAddInInformation != null) {
|
||||
addonInformation.removeAll(oldAddInInformation);
|
||||
List<SymbolAddOnInformation> oldAddOnInformation = addonInformationByDoc.remove(docURI);
|
||||
if (oldAddOnInformation != null) {
|
||||
addonInformation.removeAll(oldAddOnInformation);
|
||||
}
|
||||
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
@@ -501,8 +503,8 @@ public class SpringIndexer {
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(enhancedSymbol.getSymbol());
|
||||
|
||||
if (enhancedSymbol.getAdditionalInformation() != null) {
|
||||
addonInformation.add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<Object>()).add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformation.addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation()));
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolAddOnInformation>()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -522,8 +524,8 @@ public class SpringIndexer {
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(enhancedSymbol.getSymbol());
|
||||
|
||||
if (enhancedSymbol.getAdditionalInformation() != null) {
|
||||
addonInformation.add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<Object>()).add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformation.addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation()));
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolAddOnInformation>()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -547,8 +549,8 @@ public class SpringIndexer {
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(enhancedSymbol.getSymbol());
|
||||
|
||||
if (enhancedSymbol.getAdditionalInformation() != null) {
|
||||
addonInformation.add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<Object>()).add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformation.addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation()));
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolAddOnInformation>()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -711,7 +713,7 @@ public class SpringIndexer {
|
||||
symbols.removeAll(oldSymbols);
|
||||
}
|
||||
|
||||
List<Object> oldAddInInformation = addonInformationByDoc.remove(docURI);
|
||||
List<SymbolAddOnInformation> oldAddInInformation = addonInformationByDoc.remove(docURI);
|
||||
if (oldAddInInformation != null) {
|
||||
addonInformation.removeAll(oldAddInInformation);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.stream.Collectors;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxHandlerInformation;
|
||||
import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
@@ -50,7 +51,7 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertTrue(containsSymbol(symbols, "@/users - Content-Type: application/json", docUri, 13, 1, 13, 74));
|
||||
assertTrue(containsSymbol(symbols, "@/users/{username} - Content-Type: application/json", docUri, 18, 1, 18, 85));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
List<? extends SymbolAddOnInformation> addons = getAdditionalInformation(docUri);
|
||||
assertNull(addons);
|
||||
}
|
||||
|
||||
@@ -67,8 +68,8 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET - Accept: application/json", docUri, 24, 5, 24, 86));
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET - Accept: application/stream+json", docUri, 25, 5, 25, 94));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(4, addons.size());
|
||||
List<? extends SymbolAddOnInformation> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(8, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/hello", "GET").get(0);
|
||||
assertEquals("/hello", handlerInfo1.getPath());
|
||||
@@ -115,8 +116,8 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertTrue(containsSymbol(symbols, "@/person/ -- POST - Content-Type: application/json", docUri, 29, 6, 29, 83));
|
||||
assertTrue(containsSymbol(symbols, "@/person -- GET - Accept: application/json", docUri, 28, 7, 28, 60));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(3, addons.size());
|
||||
List<? extends SymbolAddOnInformation> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(6, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0);
|
||||
assertEquals("/person/{id}", handlerInfo1.getPath());
|
||||
@@ -155,8 +156,8 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertTrue(containsSymbol(symbols, "@/ -- POST - Accept: application/json - Content-Type: application/json,application/pdf", docUri, 31, 6, 31, 117));
|
||||
assertTrue(containsSymbol(symbols, "@/person -- GET,HEAD - Accept: text/plain,application/json", docUri, 30, 7, 30, 113));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(3, addons.size());
|
||||
List<? extends SymbolAddOnInformation> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(6, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0);
|
||||
assertEquals("/person/{id}", handlerInfo1.getPath());
|
||||
@@ -199,8 +200,8 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertTrue(containsSymbol(symbols, "@/person/ -- POST - Content-Type: application/json", docUri, 34, 5, 34, 82));
|
||||
assertTrue(containsSymbol(symbols, "@/nestedDelete -- DELETE", docUri, 35, 42, 35, 93));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(6, addons.size());
|
||||
List<? extends SymbolAddOnInformation> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(12, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/sub1/sub2/{id}", "GET").get(0);
|
||||
assertEquals("/person/sub1/sub2/{id}", handlerInfo1.getPath());
|
||||
@@ -272,11 +273,11 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
return harness.getServerWrapper().getComponents().getSpringIndexer().getSymbols(docUri);
|
||||
}
|
||||
|
||||
private List<? extends Object> getAdditionalInformation(String docUri) {
|
||||
private List<? extends SymbolAddOnInformation> getAdditionalInformation(String docUri) {
|
||||
return harness.getServerWrapper().getComponents().getSpringIndexer().getAdditonalInformation(docUri);
|
||||
}
|
||||
|
||||
private List<WebfluxHandlerInformation> getWebfluxHandler(List<? extends Object> addons, String path, String httpMethod) {
|
||||
private List<WebfluxHandlerInformation> getWebfluxHandler(List<? extends SymbolAddOnInformation> addons, String path, String httpMethod) {
|
||||
return addons.stream()
|
||||
.filter((obj) -> obj instanceof WebfluxHandlerInformation)
|
||||
.map((obj -> (WebfluxHandlerInformation) obj))
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxElementsInformation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxElementsInformationTest {
|
||||
|
||||
@Test
|
||||
public void testContainsSingleCharacterRange() {
|
||||
Range range = new Range(new Position(3, 10), new Position(3, 10));
|
||||
WebfluxElementsInformation information = new WebfluxElementsInformation(new Range[] {range});
|
||||
|
||||
assertFalse(information.contains(new Position(3, 9)));
|
||||
assertTrue(information.contains(new Position(3, 10)));
|
||||
assertFalse(information.contains(new Position(3, 11)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainsSingleLineRange() {
|
||||
Range range = new Range(new Position(3, 10), new Position(3, 20));
|
||||
WebfluxElementsInformation information = new WebfluxElementsInformation(new Range[] {range});
|
||||
|
||||
assertFalse(information.contains(new Position(3, 5)));
|
||||
assertTrue(information.contains(new Position(3, 11)));
|
||||
assertFalse(information.contains(new Position(3, 25)));
|
||||
|
||||
assertFalse(information.contains(new Position(1, 12)));
|
||||
assertFalse(information.contains(new Position(2, 1)));
|
||||
assertFalse(information.contains(new Position(4, 21)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainsMultipleLineRange() {
|
||||
Range range = new Range(new Position(2, 10), new Position(4, 5));
|
||||
WebfluxElementsInformation information = new WebfluxElementsInformation(new Range[] {range});
|
||||
|
||||
assertFalse(information.contains(new Position(1, 1)));
|
||||
assertFalse(information.contains(new Position(1, 11)));
|
||||
assertFalse(information.contains(new Position(2, 1)));
|
||||
|
||||
assertFalse(information.contains(new Position(2, 9)));
|
||||
assertTrue(information.contains(new Position(2, 10)));
|
||||
assertTrue(information.contains(new Position(2, 11)));
|
||||
assertTrue(information.contains(new Position(2, 40)));
|
||||
assertTrue(information.contains(new Position(3, 1)));
|
||||
assertTrue(information.contains(new Position(3, 12)));
|
||||
assertTrue(information.contains(new Position(3, 50)));
|
||||
assertTrue(information.contains(new Position(4, 1)));
|
||||
assertTrue(information.contains(new Position(4, 5)));
|
||||
assertFalse(information.contains(new Position(4, 6)));
|
||||
assertFalse(information.contains(new Position(4, 10)));
|
||||
|
||||
assertFalse(information.contains(new Position(5, 1)));
|
||||
assertFalse(information.contains(new Position(5, 20)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainsMultipleRanges() {
|
||||
Range range1 = new Range(new Position(2, 10), new Position(3, 20));
|
||||
Range range2 = new Range(new Position(5, 2), new Position(5, 3));
|
||||
Range range3 = new Range(new Position(10, 10), new Position(20, 20));
|
||||
Range range4 = new Range(new Position(4, 40), new Position(6, 3));
|
||||
|
||||
WebfluxElementsInformation information = new WebfluxElementsInformation(new Range[] {range1, range2, range3, range4});
|
||||
|
||||
assertFalse(information.contains(new Position(2, 9)));
|
||||
assertTrue(information.contains(new Position(2, 10)));
|
||||
assertTrue(information.contains(new Position(3, 19)));
|
||||
assertTrue(information.contains(new Position(3, 20)));
|
||||
assertFalse(information.contains(new Position(3, 21)));
|
||||
|
||||
assertTrue(information.contains(new Position(5, 1)));
|
||||
assertTrue(information.contains(new Position(5, 2)));
|
||||
assertTrue(information.contains(new Position(5, 3)));
|
||||
assertTrue(information.contains(new Position(5, 4)));
|
||||
|
||||
assertFalse(information.contains(new Position(4, 39)));
|
||||
assertTrue(information.contains(new Position(4, 40)));
|
||||
assertTrue(information.contains(new Position(4, 41)));
|
||||
|
||||
assertTrue(information.contains(new Position(6, 2)));
|
||||
assertTrue(information.contains(new Position(6, 3)));
|
||||
assertFalse(information.contains(new Position(6, 4)));
|
||||
|
||||
assertFalse(information.contains(new Position(9, 10)));
|
||||
assertFalse(information.contains(new Position(10, 9)));
|
||||
assertTrue(information.contains(new Position(10, 10)));
|
||||
assertTrue(information.contains(new Position(10, 21)));
|
||||
assertTrue(information.contains(new Position(15, 3)));
|
||||
assertTrue(information.contains(new Position(20, 20)));
|
||||
assertFalse(information.contains(new Position(20, 21)));
|
||||
assertFalse(information.contains(new Position(23, 1)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"displayName": "Bosh Editor",
|
||||
"description": "Provides validation and content assist for various Bosh configuration files",
|
||||
"icon": "icon.png",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"publisher": "Pivotal",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"displayName": "Concourse CI Pipeline Editor",
|
||||
"description": "Provides validation and content assist for Concourse CI pipeline and task configuration yml files",
|
||||
"icon": "icon.png",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"publisher": "Pivotal",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"displayName": "Cloudfoundry Manifest YML Support",
|
||||
"description": "Adds linting, content assist and hoverinfo's for Cloudfoundry Deployment Manifests (a.k.a. `manifest.yml`) files.",
|
||||
"icon": "icon.png",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"publisher": "Pivotal",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"displayName": "Spring Boot Tools",
|
||||
"description": "Provides validation and content assist for Spring Boot `application.properties`, `application.yml` properties files. As well as Boot-specific support for `.java` files.",
|
||||
"icon": "spring-boot-logo.png",
|
||||
"version": "0.1.6",
|
||||
"version": "0.2.0",
|
||||
"publisher": "Pivotal",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Reference in New Issue
Block a user