Doc Symbols proper support
This commit is contained in:
@@ -13,8 +13,6 @@ package org.springframework.ide.vscode.boot.app;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -128,7 +126,7 @@ public class SpringSymbolIndex implements InitializingBean {
|
||||
private String watchXMLChangedRegistration;
|
||||
|
||||
// Futures resolved when project is initialized/indexed
|
||||
private Map<URI, CompletableFuture<Void>> initializedProjects = new HashMap<>();
|
||||
private Map<URI, CompletableFuture<IJavaProject>> initializedProjects = new HashMap<>();
|
||||
|
||||
|
||||
private SimpleWorkspaceService getWorkspaceService() {
|
||||
@@ -538,61 +536,52 @@ public class SpringSymbolIndex implements InitializingBean {
|
||||
.map(enhanced -> enhanced.getSymbol());
|
||||
}
|
||||
|
||||
synchronized private CompletableFuture<Void> projectInitializedFuture(IJavaProject project) {
|
||||
synchronized private CompletableFuture<IJavaProject> projectInitializedFuture(IJavaProject project) {
|
||||
if (project == null) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
} else {
|
||||
URI uri = project.getLocationUri();
|
||||
return initializedProjects.computeIfAbsent(uri, u -> new CompletableFuture<Void>());
|
||||
return initializedProjects.computeIfAbsent(uri, u -> CompletableFuture.completedFuture(project));
|
||||
}
|
||||
}
|
||||
|
||||
public List<? extends SymbolInformation> getSymbols(String docURI) {
|
||||
try {
|
||||
try {
|
||||
TextDocument doc = server.getTextDocumentService().getLatestSnapshot(docURI);
|
||||
URI uri = URI.create(docURI);
|
||||
|
||||
/*
|
||||
* Workaround for docUri coming from vscode-languageclient on Windows
|
||||
*
|
||||
* It comes in as "file:///c%3A/Users/ab/spring-petclinic/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java"
|
||||
*
|
||||
* While symbols index would have this uri instead:
|
||||
* - "file:///C:/Users/ab/spring-petclinic/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java"
|
||||
*
|
||||
* i.e. lower vs upper case drive letter and escaped drive colon
|
||||
*/
|
||||
if ("file".equals(uri.getScheme())) {
|
||||
String path = URLDecoder.decode(uri.getPath(), StandardCharsets.UTF_8);
|
||||
int colonIdx = path.indexOf(':');
|
||||
if (colonIdx > 0 && colonIdx < 3) {
|
||||
int driveIdx = colonIdx - 1;
|
||||
if (Character.isLowerCase(path.charAt(driveIdx))) {
|
||||
StringBuilder sb = new StringBuilder(path.substring(0, driveIdx));
|
||||
sb.append(Character.toUpperCase(path.charAt(driveIdx)));
|
||||
sb.append(path.substring(driveIdx + 1));
|
||||
path = sb.toString();
|
||||
CompletableFuture<IJavaProject> projectInitialized = futureProjectFinder.findFuture(uri).thenCompose(project -> projectInitializedFuture(project));
|
||||
IJavaProject project = projectInitialized.get(15, TimeUnit.SECONDS);
|
||||
ImmutableList.Builder<SymbolInformation> builder = ImmutableList.builder();
|
||||
if (project != null && doc != null) {
|
||||
// Collect symbols from the opened document
|
||||
for (SpringIndexer indexer : this.indexers) {
|
||||
if (indexer.isInterestedIn(docURI)) {
|
||||
try {
|
||||
for (EnhancedSymbolInformation enhanced : indexer.computeSymbols(project, docURI,
|
||||
doc.get())) {
|
||||
builder.add(enhanced.getSymbol());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("{}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
uri = UriUtil.toUri(new File(path));
|
||||
}
|
||||
|
||||
CompletableFuture<Void> projectInitialized = futureProjectFinder.findFuture(uri).thenCompose(project -> projectInitializedFuture(project));
|
||||
projectInitialized.get(15, TimeUnit.SECONDS);
|
||||
List<EnhancedSymbolInformation> docSymbols = this.symbolsByDoc.get(uri.toString());
|
||||
if (docSymbols != null) {
|
||||
synchronized (docSymbols) {
|
||||
ImmutableList.Builder<SymbolInformation> builder = ImmutableList.builder();
|
||||
for (EnhancedSymbolInformation enhanced : docSymbols) {
|
||||
builder.add(enhanced.getSymbol());
|
||||
} else {
|
||||
// Take symbols from the index if there is no opened document.
|
||||
List<EnhancedSymbolInformation> docSymbols = this.symbolsByDoc.get(uri.toString());
|
||||
if (docSymbols != null) {
|
||||
synchronized (docSymbols) {
|
||||
for (EnhancedSymbolInformation enhanced : docSymbols) {
|
||||
builder.add(enhanced.getSymbol());
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
} catch (Exception e) {
|
||||
log.warn("", e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public List<SymbolAddOnInformation> getAllAdditionalInformation(Predicate<SymbolAddOnInformation> filter) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2022 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
|
||||
@@ -33,4 +33,9 @@ public class EnhancedSymbolInformation {
|
||||
return additionalInformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EnhancedSymbolInformation [symbol=" + symbol + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2022 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
|
||||
@@ -36,4 +36,10 @@ public class CachedSymbol {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CachedSymbol [docURI=" + docURI + ", enhancedSymbol=" + enhancedSymbol + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2022 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
|
||||
@@ -10,6 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
/**
|
||||
@@ -19,6 +22,8 @@ public interface SpringIndexer {
|
||||
|
||||
String[] getFileWatchPatterns();
|
||||
boolean isInterestedIn(String docURI);
|
||||
|
||||
List<EnhancedSymbolInformation> computeSymbols(IJavaProject project, String docURI, String content) throws Exception;
|
||||
|
||||
void initializeProject(IJavaProject project) throws Exception;
|
||||
void removeProject(IJavaProject project) throws Exception;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2022 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
|
||||
@@ -19,6 +19,7 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -230,6 +231,35 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
scanAffectedFiles(project, context.getScannedTypes(), scannedFiles);
|
||||
}
|
||||
}
|
||||
|
||||
public List<EnhancedSymbolInformation> computeSymbols(IJavaProject project, String docURI, String content) throws Exception {
|
||||
ASTParser parser = createParser(project, false);
|
||||
|
||||
if (content != null) {
|
||||
String unitName = docURI.substring(docURI.lastIndexOf("/"));
|
||||
parser.setUnitName(unitName);
|
||||
log.debug("Scan file: {}", unitName);
|
||||
parser.setSource(content.toCharArray());
|
||||
|
||||
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
|
||||
|
||||
if (cu != null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
String file = UriUtil.toFileString(docURI);
|
||||
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, file,
|
||||
0, docRef, content, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>());
|
||||
|
||||
scanAST(context);
|
||||
|
||||
return generatedSymbols.stream().map(s -> s.getEnhancedSymbol()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
|
||||
}
|
||||
|
||||
private Set<String> scanFilesInternally(IJavaProject project, DocumentDescriptor[] docs) throws Exception {
|
||||
ASTParser parser = createParser(project, false);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2022 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
|
||||
@@ -17,6 +17,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -30,6 +31,7 @@ import org.eclipse.lemminx.dom.DOMNode;
|
||||
import org.eclipse.lemminx.dom.DOMParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
@@ -308,5 +310,16 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnhancedSymbolInformation> computeSymbols(IJavaProject project, String docURI, String content)
|
||||
throws Exception {
|
||||
if (content != null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<>();
|
||||
scanFile(project, content, docURI, 0, generatedSymbols);
|
||||
return generatedSymbols.stream().map(s -> s.getEnhancedSymbol()).collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user