[intellij sh] IDEA-234818 Add base implementation of go to definition in another file

GitOrigin-RevId: 69014e8d197dfc6305b90f3ed6c1631fec6eb7c5
This commit is contained in:
Mikhail Mazurkevich
2022-01-13 20:16:58 +00:00
committed by intellij-monorepo-bot
parent db984b8c0e
commit e2b9655708
62 changed files with 309 additions and 3 deletions
@@ -10,7 +10,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import static com.intellij.sh.ShTypes.*;
import com.intellij.sh.psi.*;
public class ShIncludeCommandImpl extends ShCommandImpl implements ShIncludeCommand {
public class ShIncludeCommandImpl extends ShIncludeCommandMixin implements ShIncludeCommand {
public ShIncludeCommandImpl(ASTNode node) {
super(node);
+4 -1
View File
@@ -159,7 +159,10 @@ private redirection_inner ::= ('<&' | '>&') (number | '-')
private redirection_target ::= process_substitution | <<parseUntilSpace w>> {name="redirection target"}
process_substitution ::= ('<(' | '>(') list ')' {pin=1}
include_command ::= include_directive (simple_command_element | <<keywordsRemapped>>)+ {pin=0}
include_command ::= include_directive (simple_command_element | <<keywordsRemapped>>)+ {
pin=0
mixin="com.intellij.sh.psi.impl.ShIncludeCommandMixin"
}
include_directive ::= &('source' | '.') word {extends=generic_command_directive}
shell_command ::= if_command
@@ -0,0 +1,53 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.sh.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.sh.psi.ShIncludeCommand;
import com.intellij.sh.psi.ShSimpleCommandElement;
import com.intellij.sh.psi.ShString;
import org.jetbrains.annotations.NotNull;
import java.util.List;
abstract class ShIncludeCommandMixin extends ShCommandImpl implements ShIncludeCommand {
ShIncludeCommandMixin(ASTNode node) {
super(node);
}
@Override
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
@NotNull ResolveState state,
PsiElement lastParent,
@NotNull PsiElement place) {
List<ShSimpleCommandElement> commandsList = getSimpleCommandElementList();
if (commandsList.size() <= 0) return true;
ShSimpleCommandElement simpleCommandElement = commandsList.get(0);
String relativeFilePath = simpleCommandElement.getText();
if (simpleCommandElement instanceof ShString) {
ShString shString = (ShString)simpleCommandElement;
if (relativeFilePath.length() >= 2 &&
(shString.getOpenQuote() != null && shString.getCloseQuote() != null) ||
(shString.getRawString() != null && relativeFilePath.startsWith("'") && relativeFilePath.endsWith("'"))) {
relativeFilePath = relativeFilePath.substring(1, relativeFilePath.length() - 1);
}
} else {
if (relativeFilePath.contains("\\ ")) {
relativeFilePath = relativeFilePath.replace("\\ ", " ");
}
}
PsiDirectory containingDirectory = getContainingFile().getContainingDirectory();
if (containingDirectory == null) return true;
VirtualFile relativeFile = VfsUtilCore.findRelativeFile(relativeFilePath, containingDirectory.getVirtualFile());
if (relativeFile == null) return true;
VirtualFile sourceFile = place.getContainingFile().getVirtualFile();
if (relativeFile.equals(sourceFile)) return true;
PsiFile includedPsiFile = PsiManager.getInstance(getProject()).findFile(relativeFile);
if (includedPsiFile == null) return true;
return includedPsiFile.processDeclarations(processor, state, this, place);
}
}
@@ -0,0 +1,5 @@
#!/bin/zsh
<caret>foo
source "./target.sh"
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,5 @@
#!/bin/zsh
source "./another folder/target.sh"
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,5 @@
#!/bin/zsh
source ./another\ folder/target.sh
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,5 @@
#!/bin/zsh
source folder/target.sh
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
source ./target.sh
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,9 @@
#!/bin/zsh
source "./target.sh"
function foo() {
echo "One more text"
}
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,5 @@
#!/bin/zsh
source ../target.sh
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,5 @@
#!/bin/zsh
source './target.sh'
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,5 @@
#!/bin/zsh
source "./target.sh"
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,6 @@
#!/bin/zsh
source "./target.sh"
<caret>foo
@@ -0,0 +1,7 @@
#!/bin/zsh
source "./source.sh"
function bar() {
echo "Another Text"
}
@@ -0,0 +1,6 @@
#!/bin/zsh
source "./tmp.sh"
<caret>foo
@@ -0,0 +1,3 @@
#!/bin/zsh
source ./source.sh
@@ -0,0 +1,3 @@
#!/bin/zsh
source ./target.sh
@@ -0,0 +1,6 @@
#!/bin/zsh
. "./tmp.sh"
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Another Text"
}
@@ -0,0 +1,3 @@
#!/bin/zsh
. ./target.sh
@@ -0,0 +1,5 @@
#!/bin/zsh
source target.sh
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -0,0 +1,6 @@
#!/bin/zsh
source "./tmp.sh"
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Another Text"
}
@@ -0,0 +1,3 @@
#!/bin/zsh
source ./target.sh
@@ -0,0 +1,5 @@
#!/bin/zsh
source target.sh 1 "Some text" true
<caret>foo
@@ -0,0 +1,5 @@
#!/bin/zsh
function foo() {
echo "Simple text"
}
@@ -2,6 +2,7 @@
package com.intellij.sh;
import com.intellij.sh.actions.ShBaseGenerateActionsTest;
import com.intellij.sh.codeInsight.ShFunctionResolverInImportedFileTest;
import com.intellij.sh.codeInsight.ShFunctionResolverTest;
import com.intellij.sh.completion.ShCompletionTest;
import com.intellij.sh.completion.ShFileCompletionTest;
@@ -81,6 +82,7 @@ public class ShTestSuite {
suite.addTestSuite(ShTypingTest.class);
suite.addTestSuite(ShLineIndentProviderTest.class);
suite.addTestSuite(ShFunctionResolverTest.class);
suite.addTestSuite(ShFunctionResolverInImportedFileTest.class);
return suite;
}
}
@@ -0,0 +1,81 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sh.codeInsight;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
public class ShFunctionResolverInImportedFileTest extends BasePlatformTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
myFixture.setTestDataPath(PluginPathManager.getPluginHomePath("sh") + "/testData/resolve/imported_file_scope");
myFixture.copyDirectoryToProject(getTestName(true), "");
}
public void testCaseOne() {
doTest();
}
public void testCaseTwo() {
doTest();
}
public void testCaseThree() {
doTest();
}
public void testCaseFour() {
doTest();
}
public void testCaseFive() {
doTest();
}
public void testCaseSix() {
doTest("./parent folder/source.sh");
}
public void testCaseEight() {
doNullTest();
}
public void testCaseNine() {
doTest();
}
public void testSameFolder() {
doTest();
}
public void testWithParams() {
doTest();
}
public void testCyclicImport() {
doNullTest();
}
public void testCyclicImportCaseTwo() {
doNullTest();
}
public void testTransitiveImport() {
doTest();
}
public void testDotTransitiveImport() {
doTest();
}
private void doNullTest() {
myFixture.configureByFile("source.sh");
PsiReference reference = myFixture.getFile().findReferenceAt(myFixture.getCaretOffset());
assertNull(reference.resolve());
}
private void doTest() {
doTest( "source.sh", "target.sh");
}
private void doTest(String filePath) {
doTest( filePath, "target.sh");
}
private void doTest(String filePath, String targetFilePath) {
myFixture.configureByFile(filePath);
PsiReference reference = myFixture.getFile().findReferenceAt(myFixture.getCaretOffset());
PsiElement targetElement = reference.resolve();
assertNotNull(targetElement);
assertEquals(targetFilePath, targetElement.getContainingFile().getVirtualFile().getName());
}
}
@@ -24,7 +24,7 @@ public class ShFunctionResolverTest extends BasePlatformTestCase {
@NotNull
@Override
protected String getTestDataPath() {
return PluginPathManager.getPluginHomePath("sh") + "/testData/resolve/";
return PluginPathManager.getPluginHomePath("sh") + "/testData/resolve/file_scope";
}
public void testSimpleFunction() {