Skip to content
This repository has been archived by the owner on Oct 26, 2023. It is now read-only.

Commit

Permalink
feature: go to thrift file directly
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksandra Zdrojowa committed Sep 12, 2022
1 parent 4fbd271 commit ebaf7e0
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.intellij.plugins.thrift.completion;

import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.plugins.thrift.index.ThriftDeclarationIndex;
import com.intellij.plugins.thrift.lang.psi.ThriftDeclaration;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import org.apache.commons.compress.utils.Lists;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.scala.lang.psi.api.base.ScReference;
import org.jetbrains.plugins.scala.lang.resolve.ScalaResolveResult;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ThriftGotoDeclarationHandler implements GotoDeclarationHandler {

@NotNull
private List<ThriftDeclaration> getThriftDeclarations(List<String> fullyQualifiedNames, Project project) {
try {
return fullyQualifiedNames.stream()
.filter(name -> getElementName(name) != null && getPackageName(name) != null)
.map(name -> {
String elementName = getElementName(name);
String packageName = getPackageName(name);
return ThriftDeclarationIndex.findDeclaration(elementName, packageName, project, GlobalSearchScope.allScope(project));
})
.flatMap(Collection::stream)
.collect(Collectors.toList());
} catch (NoClassDefFoundError ignored) {}
return Lists.newArrayList();
}

@Override
public PsiElement @Nullable [] getGotoDeclarationTargets(@Nullable PsiElement sourceElement, int offset, Editor editor) {
assert sourceElement != null;

PsiFile containingFile = sourceElement.getContainingFile();
PsiReference ref = containingFile.findReferenceAt(sourceElement.getTextRange().getStartOffset());
List<String> fullyQualifiedNames = Collections.emptyList();

if (ref instanceof PsiJavaCodeReferenceElement) {
fullyQualifiedNames = Arrays.stream(((PsiJavaCodeReferenceElement) ref).multiResolve(false))
.map(ResolveResult::getElement)
.filter(javaResolveResult -> javaResolveResult instanceof PsiClass)
.map(javaResolveResult -> ((PsiClass) javaResolveResult).getQualifiedName())
.collect(Collectors.toList());
} else if (ref instanceof ScReference){
fullyQualifiedNames = Stream.of(((ScReference) ref).multiResolveScala(false))
.map(ScalaResolveResult::qualifiedNameId)
.map(qualifiedName -> qualifiedName.substring(qualifiedName.lastIndexOf(":") + 1))
.distinct()
.collect(Collectors.toList());
}

if(!fullyQualifiedNames.isEmpty()) {
PsiElement[] thriftMatches = getThriftDeclarations(fullyQualifiedNames, sourceElement.getProject()).stream()
.map(PsiElement::getNavigationElement)
.toArray(PsiElement[]::new);
if(thriftMatches.length > 0) {
return thriftMatches;
}
}
return null;
}

@Override
public @Nullable @Nls(capitalization = Nls.Capitalization.Title) String getActionText(@NotNull DataContext context) {
return GotoDeclarationHandler.super.getActionText(context);
}

private String getPackageName(String qualifiedName) {
try {
return qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
} catch (IndexOutOfBoundsException ex){
return null;
}
}

private String getElementName(String qualifiedName) {
try {
return qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
} catch (IndexOutOfBoundsException ex){
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.plugins.thrift.ThriftFileType;
import com.intellij.plugins.thrift.lang.psi.ThriftDeclaration;
import com.intellij.plugins.thrift.lang.psi.ThriftTopLevelDeclaration;
import com.intellij.plugins.thrift.lang.psi.*;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
Expand Down Expand Up @@ -87,25 +87,52 @@ public boolean process(String name) {
public static List<ThriftDeclaration> findDeclaration(@NotNull final String name,
@NotNull Project project,
@NotNull GlobalSearchScope scope) {
final List<ThriftDeclaration> result = new ArrayList<ThriftDeclaration>();
final List<ThriftDeclaration> result = new ArrayList<>();
final PsiManager manager = PsiManager.getInstance(project);
FileBasedIndex.getInstance().getFilesWithKey(
THRIFT_DECLARATION_INDEX,
Collections.singleton(name),
file -> {
PsiFile psiFile = manager.findFile(file);
if (psiFile != null) {
for (PsiElement child : psiFile.getChildren()) {
if (child instanceof ThriftTopLevelDeclaration && name.equals(((ThriftDeclaration) child).getName())) {
result.add((ThriftDeclaration) child);
}
}
}
return true;
},
scope
);
return result;
}

public static List<ThriftDeclaration> findDeclaration(@NotNull final String name,
@NotNull String requiredNamespace,
@NotNull Project project,
@NotNull GlobalSearchScope scope) {
final List<ThriftDeclaration> result = new ArrayList<>();
final PsiManager manager = PsiManager.getInstance(project);
FileBasedIndex.getInstance().getFilesWithKey(
THRIFT_DECLARATION_INDEX,
Collections.singleton(name),
new Processor<VirtualFile>() {
@Override
public boolean process(VirtualFile file) {
PsiFile psiFile = manager.findFile(file);
if (psiFile != null) {
for (PsiElement child : psiFile.getChildren()) {
if (child instanceof ThriftTopLevelDeclaration && name.equals(((ThriftDeclaration)child).getName())) {
result.add((ThriftDeclaration)child);
file -> {
PsiFile psiFile = manager.findFile(file);
List<String> availableNamespaces = new ArrayList<>(Collections.emptyList());
if (psiFile != null) {
for (PsiElement child : psiFile.getChildren()) {
if (child instanceof ThriftNamespace || (child instanceof PsiComment && child.getText().contains("namespace"))) {
String fullNamespaceName = child.getText();
availableNamespaces.add(fullNamespaceName.substring(fullNamespaceName.lastIndexOf(" ") + 1));
}
if (child instanceof ThriftTopLevelDeclaration && name.equals(((ThriftDeclaration) child).getName()) && availableNamespaces.contains(requiredNamespace)) {
result.add((ThriftDeclaration) child);
}
}
}
}
}
return true;
}
},
return true;
},
scope
);
return result;
Expand Down
3 changes: 3 additions & 0 deletions thrift/src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@
<frameworkSupport implementation="com.intellij.plugins.thrift.config.facet.ThriftFacetSupportProvider"/>
<facetType implementation="com.intellij.plugins.thrift.config.facet.ThriftFacetType"/>
<compileServer.plugin classpath="thrift-jps.jar" />

<gotoDeclarationHandler order="first" implementation="com.intellij.plugins.thrift.completion.ThriftGotoDeclarationHandler"/>

</extensions>

<actions>
Expand Down

0 comments on commit ebaf7e0

Please sign in to comment.