diff --git a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Indexer.java b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Indexer.java index 105920c..71fba97 100644 --- a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Indexer.java +++ b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Indexer.java @@ -6,10 +6,12 @@ package com.microsoft.java.lsif.core.internal.indexer; import java.io.File; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -49,12 +51,14 @@ import com.microsoft.java.lsif.core.internal.protocol.Document; import com.microsoft.java.lsif.core.internal.protocol.Event; import com.microsoft.java.lsif.core.internal.protocol.Group; +import com.microsoft.java.lsif.core.internal.protocol.ItemEdge; import com.microsoft.java.lsif.core.internal.protocol.PackageInformation; import com.microsoft.java.lsif.core.internal.protocol.Project; import com.microsoft.java.lsif.core.internal.protocol.Group.ConflictResolution; import com.microsoft.java.lsif.core.internal.visitors.DiagnosticVisitor; import com.microsoft.java.lsif.core.internal.visitors.DocumentVisitor; import com.microsoft.java.lsif.core.internal.visitors.LsifVisitor; +import com.microsoft.java.lsif.core.internal.visitors.SymbolData; import com.microsoft.java.lsif.core.internal.visitors.VisitorUtils; import io.reactivex.Observable; @@ -133,6 +137,7 @@ private void buildIndex(IPath path, IProgressMonitor monitor, LsifService lsif) dumpParallelly(sourceList, threadPool, projVertex, lsif, hasPackageInformation, monitor); + emitReferenceEdges(lsif); VisitorUtils.endAllDocument(lsif); LsifEmitter.getInstance().emit( lsif.getVertexBuilder().event(Event.EventScope.Project, Event.EventKind.END, projVertex.getId())); @@ -174,6 +179,22 @@ private List getAllSourceFiles(IJavaProject javaProject) throw return res; } + private void emitReferenceEdges(LsifService lsif) { + for (Entry> entry : Repository.getInstance().getReferenceResultsMap().entrySet()) { + SymbolData fromSymbolData = entry.getKey(); + List referenceResultsInVs = new ArrayList(); + List referenceLinksInVs = new ArrayList(); + for (SymbolData symbolData : entry.getValue()) { + referenceResultsInVs.add(symbolData.getReferenceResult().getId()); + referenceLinksInVs.add(symbolData.getGroupMoniker().getId()); + } + LsifEmitter.getInstance().emit(lsif.getEdgeBuilder().item(fromSymbolData.getReferenceResult(), referenceResultsInVs, fromSymbolData.getDocument(), + ItemEdge.ItemEdgeProperties.REFERENCE_RESULTS)); + LsifEmitter.getInstance().emit(lsif.getEdgeBuilder().item(fromSymbolData.getReferenceResult(), referenceLinksInVs, fromSymbolData.getDocument(), + ItemEdge.ItemEdgeProperties.REFERENCE_LINKS)); + } + } + /** * Generate and emit the package information of the given project and return if * the project is published. diff --git a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Repository.java b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Repository.java index 5d29668..90730fd 100644 --- a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Repository.java +++ b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/indexer/Repository.java @@ -7,6 +7,8 @@ import java.io.File; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -56,6 +58,10 @@ public class Repository { // Value: PackageInformation private Map mavenProjectMap = new ConcurrentHashMap<>(); + // Key: SymbolData + // Value: List + private Map> referenceResultsMap = new ConcurrentHashMap<>(); + private Repository() { } @@ -199,4 +205,17 @@ private void addMavenProject(String id, MavenProject mavenProject) { this.mavenProjectMap.put(id, mavenProject); } + public synchronized void addReferenceResults(SymbolData from, SymbolData to) { + if (this.referenceResultsMap.containsKey(from)) { + this.referenceResultsMap.get(from).add(to); + } else { + this.referenceResultsMap.put(from, Arrays.asList(to)); + } + + } + + public Map> getReferenceResultsMap() { + return this.referenceResultsMap; + } + } diff --git a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/protocol/ItemEdge.java b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/protocol/ItemEdge.java index 0fd3233..a80da83 100644 --- a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/protocol/ItemEdge.java +++ b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/protocol/ItemEdge.java @@ -38,6 +38,7 @@ public static class ItemEdgeProperties { public static final String DEFINITIONS = "definitions"; public static final String REFERENCES = "references"; public static final String REFERENCE_RESULTS = "referenceResults"; + public static final String REFERENCE_LINKS = "referenceLinks"; public static final String IMPLEMENTATION_RESULTS = "implementationResults"; } } diff --git a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/LsifVisitor.java b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/LsifVisitor.java index 6f2b580..c801b05 100644 --- a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/LsifVisitor.java +++ b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/LsifVisitor.java @@ -107,7 +107,7 @@ private void resolve(int startPosition, int length, boolean needResolveImpl, int symbolData.resolveMoniker(lsif, element, modifier, hasPackageInformation); /* Resolve definition */ - symbolData.resolveDefinition(lsif, definitionLocation); + symbolData.resolveDefinition(lsif, element, definitionLocation); /* Resolve typeDefinition */ symbolData.resolveTypeDefinition(lsif, docVertex, sourceLspRange); diff --git a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/SymbolData.java b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/SymbolData.java index f5afd19..d8ccb3f 100644 --- a/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/SymbolData.java +++ b/com.microsoft.java.lsif.core/src/com/microsoft/java/lsif/core/internal/visitors/SymbolData.java @@ -16,6 +16,7 @@ import org.apache.maven.scm.provider.ScmUrlUtils; import org.apache.maven.shared.utils.StringUtils; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IField; @@ -32,9 +33,11 @@ import org.eclipse.jdt.internal.core.PackageFragmentRoot; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; +import org.eclipse.jdt.ls.core.internal.handlers.FindLinksHandler; import org.eclipse.lsp4j.Hover; import org.eclipse.lsp4j.Location; +import com.microsoft.java.lsif.core.internal.JdtlsUtils; import com.microsoft.java.lsif.core.internal.emitter.LsifEmitter; import com.microsoft.java.lsif.core.internal.indexer.LsifService; import com.microsoft.java.lsif.core.internal.indexer.Repository; @@ -72,6 +75,18 @@ public SymbolData(Project project, Document document) { this.document = document; } + public Document getDocument() { + return this.document; + } + + public ReferenceResult getReferenceResult() { + return this.referenceResult; + } + + public Moniker getGroupMoniker() { + return this.groupMoniker; + } + synchronized public void ensureResultSet(LsifService lsif, Range sourceRange) { if (this.resultSet == null) { ResultSet resultSet = lsif.getVertexBuilder().resultSet(); @@ -137,7 +152,7 @@ synchronized public void generateExportMoniker(LsifService lsif, String identifi LsifEmitter.getInstance().emit(lsif.getEdgeBuilder().attach(this.schemeMoniker, this.groupMoniker)); } - synchronized public void resolveDefinition(LsifService lsif, Location definitionLocation) { + synchronized public void resolveDefinition(LsifService lsif, IJavaElement element, Location definitionLocation) { if (this.definitionResolved) { return; } @@ -148,9 +163,37 @@ synchronized public void resolveDefinition(LsifService lsif, Location definition DefinitionResult defResult = VisitorUtils.ensureDefinitionResult(lsif, this.resultSet); LsifEmitter.getInstance().emit(lsif.getEdgeBuilder().item(defResult, definitionRange, document, ItemEdge.ItemEdgeProperties.DEFINITIONS)); + if (element instanceof IMethod) { + IMethod mostAbstractMethod = getMostAbstractDeclaration((IMethod) element); + if (mostAbstractMethod != null) { + Location abstractDefinitionLocation = JdtlsUtils.getElementLocation(mostAbstractMethod); + String id = VisitorUtils.createSymbolKey(abstractDefinitionLocation); + Document abstractDefinitionDocument = Repository.getInstance().enlistDocument(lsif, + abstractDefinitionLocation.getUri(), this.project); + SymbolData abstractSymbolData = Repository.getInstance().enlistSymbolData(id, + abstractDefinitionDocument, this.project); + Repository.getInstance().addReferenceResults(this, abstractSymbolData); + } + } this.definitionResolved = true; } + private IMethod getMostAbstractDeclaration(IMethod method) { + IMethod current = null; + try { + while (method != null) { + method = FindLinksHandler.findOverriddenMethod(method, new NullProgressMonitor()); + if (method == null) { + return current; + } + current = method; + } + } catch (JavaModelException e) { + return null; + } + return null; + } + synchronized public void resolveTypeDefinition(LsifService lsif, Document docVertex, org.eclipse.lsp4j.Range sourceLspRange) { if (this.typeDefinitionResolved) { @@ -190,8 +233,7 @@ synchronized public void resolveImplementation(LsifService lsif, Document docVer this.implementationResolved = true; } - synchronized public void resolveReference(LsifService lsif, Document sourceDocument, Location definitionLocation, - Range sourceRange) { + synchronized public void resolveReference(LsifService lsif, Document sourceDocument, Location definitionLocation, Range sourceRange) { if (this.referenceResult == null) { ReferenceResult referenceResult = VisitorUtils.ensureReferenceResult(lsif, this.resultSet); this.referenceResult = referenceResult;