aboutsummaryrefslogtreecommitdiffstats
path: root/integration
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2022-02-18 15:40:43 +0100
committerJon Bratseth <bratseth@gmail.com>2022-02-18 15:40:43 +0100
commit99dbe4e87730d1eb9e6d29a61b4789d3308e59a1 (patch)
tree1ea1ec9ec2807d04b58b55f766801129fe2a4c4e /integration
parentf087f021607d473defd070a6ea7bc231dd2b78d4 (diff)
Find profile definition
Diffstat (limited to 'integration')
-rw-r--r--integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/RankProfileDefinitionFinder.java68
-rw-r--r--integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/SdFindUsagesHandler.java6
-rw-r--r--integration/intellij/src/main/java/ai/vespa/intellij/schema/utils/Tokens.java7
-rw-r--r--integration/intellij/src/test/java/ai/vespa/intellij/findUsages/FindRankProfileDefinitionTest.java20
-rw-r--r--integration/intellij/src/test/java/ai/vespa/intellij/findUsages/UsagesTester.java9
5 files changed, 107 insertions, 3 deletions
diff --git a/integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/RankProfileDefinitionFinder.java b/integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/RankProfileDefinitionFinder.java
new file mode 100644
index 00000000000..651b7836e5d
--- /dev/null
+++ b/integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/RankProfileDefinitionFinder.java
@@ -0,0 +1,68 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package ai.vespa.intellij.schema.findUsages;
+
+import ai.vespa.intellij.schema.model.RankProfile;
+import ai.vespa.intellij.schema.psi.SdRankProfileDefinition;
+import ai.vespa.intellij.schema.utils.AST;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.util.Processor;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Finds the definition of a function.
+ *
+ * @author bratseth
+ */
+public class RankProfileDefinitionFinder extends UsageFinder {
+
+ private final PsiElement referringElement;
+ private final String profileNameToFind;
+ private final Set<RankProfile> visited = new HashSet<>();
+
+ public RankProfileDefinitionFinder(PsiElement referringElement, SearchScope scope, Processor<? super UsageInfo> processor) {
+ super(scope, processor);
+ this.referringElement = referringElement;
+ this.profileNameToFind = ReadAction.compute(() -> referringElement.getText());
+ }
+
+ /** Returns true if this finder is appropriate for this task, false if others should be tried. */
+ public boolean findDefinition() {
+ RankProfile referringProfile = ReadAction.compute(() -> resolveReferringProfile());
+ if (referringProfile == null) return false;
+ findDefinitionAbove(referringProfile);
+ return true;
+ }
+
+ /**
+ * Returns the profile which inherits the one we're to find the definition of, or null if
+ * referringElement is not the name of an inherited profile.
+ */
+ private RankProfile resolveReferringProfile() {
+ SdRankProfileDefinition profileDefinition = PsiTreeUtil.getParentOfType(referringElement, SdRankProfileDefinition.class);
+ if (profileDefinition == null) return null;
+ if (AST.inherits(profileDefinition).stream().noneMatch(node -> node.getText().equals(referringElement.getText()))) return null;
+ return resolveSchema(profileDefinition).rankProfiles().get(profileDefinition.getName());
+ }
+
+ private void findDefinitionAbove(RankProfile profile) {
+ ProgressIndicatorProvider.checkCanceled();
+ if ( ! visited.add(profile)) return;
+ ReadAction.compute(() -> findDefinitionIn(profile));
+ for (var parent : ReadAction.compute(() -> profile.parents().values()))
+ findDefinitionAbove(parent);
+ }
+
+ private boolean findDefinitionIn(RankProfile profile) {
+ if (profileNameToFind.equals(profile.name()))
+ processor().process(new UsageInfo(profile.definition()));
+ return true;
+ }
+
+}
diff --git a/integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/SdFindUsagesHandler.java b/integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/SdFindUsagesHandler.java
index 15f3d8f3b29..7ff14b69368 100644
--- a/integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/SdFindUsagesHandler.java
+++ b/integration/intellij/src/main/java/ai/vespa/intellij/schema/findUsages/SdFindUsagesHandler.java
@@ -33,8 +33,10 @@ public class SdFindUsagesHandler extends FindUsagesHandler {
else if (elementToSearch instanceof SdRankProfileDefinition) {
new RankProfileUsageFinder((SdRankProfileDefinition) elementToSearch, options.searchScope, processor).findUsages();
}
- else {
- new FunctionDefinitionFinder(elementToSearch, options.searchScope, processor).findDefinition();
+ else { // try find definitions
+ boolean suitable = new RankProfileDefinitionFinder(elementToSearch, options.searchScope, processor).findDefinition();
+ if ( ! suitable)
+ new FunctionDefinitionFinder(elementToSearch, options.searchScope, processor).findDefinition();
}
}
diff --git a/integration/intellij/src/main/java/ai/vespa/intellij/schema/utils/Tokens.java b/integration/intellij/src/main/java/ai/vespa/intellij/schema/utils/Tokens.java
index 5d4ae376c77..f706ebd756d 100644
--- a/integration/intellij/src/main/java/ai/vespa/intellij/schema/utils/Tokens.java
+++ b/integration/intellij/src/main/java/ai/vespa/intellij/schema/utils/Tokens.java
@@ -24,9 +24,10 @@ public class Tokens {
* Advances to the next token, if it is of the given type.
*
* @return true if the current token was of the given type and we advanced it, false
- * if it was not and nothing was changed
+ * if it was not and nothing was changed
*/
public boolean skip(IElementType... tokenTypes) {
+ if (current() == null) return false;
boolean is = is(tokenTypes);
if (is)
i++;
@@ -40,6 +41,7 @@ public class Tokens {
* if it was not and nothing was changed
*/
public boolean skipWhitespace() {
+ if (current() == null) return false;
boolean is = isWhitespace();
if (is)
i++;
@@ -48,6 +50,7 @@ public class Tokens {
/** Returns whether the current token is of the given type */
public boolean is(IElementType... tokenTypes) {
+ if (current() == null) return false;
for (IElementType type : tokenTypes)
if (current().getElementType() == type) return true;
return false;
@@ -55,11 +58,13 @@ public class Tokens {
/** Returns whether the current token is whitespace */
public boolean isWhitespace() {
+ if (current() == null) return false;
return current().getPsi() instanceof PsiWhiteSpace;
}
/** Returns whether the current token is an element */
public boolean isElement() {
+ if (current() == null) return false;
return current() instanceof LeafPsiElement;
}
diff --git a/integration/intellij/src/test/java/ai/vespa/intellij/findUsages/FindRankProfileDefinitionTest.java b/integration/intellij/src/test/java/ai/vespa/intellij/findUsages/FindRankProfileDefinitionTest.java
new file mode 100644
index 00000000000..5694c0587a1
--- /dev/null
+++ b/integration/intellij/src/test/java/ai/vespa/intellij/findUsages/FindRankProfileDefinitionTest.java
@@ -0,0 +1,20 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package ai.vespa.intellij.findUsages;
+
+import ai.vespa.intellij.PluginTestBase;
+import com.intellij.usageView.UsageInfo;
+import org.junit.Test;
+
+/**
+ * @author bratseth
+ */
+public class FindRankProfileDefinitionTest extends PluginTestBase {
+
+ @Test
+ public void testFindUsagesInRankProfileModularity() {
+ useDir("src/test/applications/rankprofilemodularity");
+ var tester = new UsagesTester("test.sd", getProject());
+ UsageInfo usage = tester.findRankProfileDefinition("outside_schema1", 40);
+ }
+
+}
diff --git a/integration/intellij/src/test/java/ai/vespa/intellij/findUsages/UsagesTester.java b/integration/intellij/src/test/java/ai/vespa/intellij/findUsages/UsagesTester.java
index 319240b9ceb..c1e6c9282b6 100644
--- a/integration/intellij/src/test/java/ai/vespa/intellij/findUsages/UsagesTester.java
+++ b/integration/intellij/src/test/java/ai/vespa/intellij/findUsages/UsagesTester.java
@@ -52,6 +52,15 @@ class UsagesTester {
return usageProcessor.usages.get(0);
}
+ /** Finds the rank profile referred (by inheritance) at the given character offset in the given profile. */
+ UsageInfo findRankProfileDefinition(String profileName, int offset) {
+ PsiElement referringElement = schema.rankProfiles().get(profileName).definition().findElementAt(offset);
+ findUsages(referringElement);
+ assertEquals("Expected to find definition of " + referringElement.getText(),
+ 1, usageProcessor.usages.size());
+ return usageProcessor.usages.get(0);
+ }
+
private void findUsages(PsiElement element) {
var options = new FindUsagesOptions(project);
usageProcessor.usages.clear();