Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#203 abstract functions #205

Merged
merged 4 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ build/
soft/
src/main/gen/
src/main/java/intellij_awk/_AwkLexer.flex
/temp*/
/temp*/
/tmp/
27 changes: 23 additions & 4 deletions src/main/java/intellij_awk/AwkReferenceFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import com.intellij.util.IncorrectOperationException;
import intellij_awk.psi.AwkNamedElement;
import intellij_awk.psi.impl.AwkFunctionNameImpl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import java.util.*;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -32,9 +32,16 @@ public AwkReferenceFunction(@NotNull AwkNamedElement element, TextRange rangeInE
functionNames = AwkUtil.findFunctions(myElement.getProject(), funcName);
}

Set<PsiFile> seenFiles = new HashSet<>();

for (AwkFunctionNameImpl functionName : functionNames) {
PsiFile file = functionName.getContainingFile();
// only reference first found function in file, all others will be dups
if (seenFiles.contains(file)) {
continue;
}
seenFiles.add(file);
res.add(new PsiElementResolveResult(functionName));
break; // only reference first found function to prevent erroneous unused function error
}

return res.toArray(new ResolveResult[0]);
Expand All @@ -47,6 +54,18 @@ public AwkReferenceFunction(@NotNull AwkNamedElement element, TextRange rangeInE
return resolveResults.length == 1 ? resolveResults[0].getElement() : null;
}

/**
* See: <a
* href="https://intellij-support.jetbrains.com/hc/en-us/community/posts/206116059-ReferencesSearch-PsiPolyVariantReferences">link</a>
*/
@Override
public boolean isReferenceTo(@NotNull PsiElement element) {
PsiManager manager = getElement().getManager();
return Arrays.stream(multiResolve(false))
.anyMatch(
resolveResult -> manager.areElementsEquivalent(resolveResult.getElement(), element));
}

@Override
public PsiElement handleElementRename(@NotNull String newElementName)
throws IncorrectOperationException {
Expand Down
29 changes: 22 additions & 7 deletions src/test/java/intellij_awk/AwkFindUsagesTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@

import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.ResolveResult;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
import com.intellij.usageView.UsageInfo;
import intellij_awk.psi.AwkFunctionCallNameMixin;
import intellij_awk.psi.AwkUserVarNameMixin;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;

public class AwkFindUsagesTests extends BasePlatformTestCase {

Expand Down Expand Up @@ -308,6 +310,15 @@ public void testMultipleFilesVars6() {
doTest(0, "function f() { A<caret> = 1 }", "function f2() { A = 2 }");
}

public void testMultipleFilesFunctions() {
PsiFile psiFile = configureByFiles("BEGIN { fff<caret>() }", "function fff() {}", "function fff() {}\nfunction fff() {}");
ResolveResult[] resolveResults =
((PsiPolyVariantReference)
AwkUtil.findFirstMatchedDeep(psiFile, psiElement -> psiElement instanceof AwkFunctionCallNameMixin).getReference())
.multiResolve(false);
assertEquals(2,resolveResults.length);
}

public void testIndirect1() {
doTest(
4,
Expand All @@ -329,14 +340,18 @@ private void assertResolved(
}

private void doTest(int expectedUsagesCount, String code, String... otherFiles) {
myFixture.configureByText("a.awk", code);
configureByFiles(code, otherFiles);
PsiElement element = myFixture.getElementAtCaret();
Collection<UsageInfo> usages = myFixture.findUsages(element);
Assert.assertEquals(expectedUsagesCount, usages.size());
}
private PsiFile configureByFiles(String code, String... otherFiles) {
PsiFile psiFile = myFixture.configureByText("a.awk", code);
for (int i = 0; i < otherFiles.length; i++) {
String otherFileCode = otherFiles[i];
myFixture.addFileToProject("f" + i + ".awk", otherFileCode);
}
PsiElement element = myFixture.getElementAtCaret();
Collection<UsageInfo> usages = myFixture.findUsages(element);
Assert.assertEquals(expectedUsagesCount, usages.size());
return psiFile;
}

@NotNull
Expand Down
39 changes: 34 additions & 5 deletions src/test/java/intellij_awk/AwkInspectionTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ public void testUsedFunctionInFileOutsideProject() {
checkByFileNoProblemAtCaret(unusedFunction, true);
}

public void testIssue203NoUnusedFunctionErrForUsageInOtherFile() {
myFixture.configureByText("a.awk", "function <caret>f(){}");
myFixture.addFileToProject("c.awk", "BEGIN { f() } ");
assertNoInspectionAtCaret(unusedFunction);
}
public void testIssue203NoUnusedFunctionErrForRepeatingDefinitionInSeparateFiles() {
myFixture.configureByText("a.awk", "function <caret>f(){}");
myFixture.addFileToProject("b.awk", "function f() {}");
myFixture.addFileToProject("c.awk", "BEGIN { f() } ");
assertNoInspectionAtCaret(unusedFunction);
}

public void testIssue203UnusedFunctionErrForRepeatingDefinitionWhenFunctionIsUsedInSameFileAsDefined() {
myFixture.configureByText("a.awk", "function <caret>f(){}");
myFixture.addFileToProject("c.awk", "BEGIN { f() } function f() {}");
assertInspectionIsShown(unusedFunction);
}


public void testUsedVarInFileOutsideProject() {
checkByFileNoProblemAtCaret(unusedGlobalVariable, true);
}
Expand Down Expand Up @@ -298,6 +317,10 @@ private void checkByFileNoProblemAtCaret(Inspection inspection, boolean fileOuts
myFixture.configureByFile(testName);
}

assertNoInspectionAtCaret(inspection);
}

private void assertNoInspectionAtCaret(Inspection inspection) {
myFixture.enableInspections(inspection.inspection);

List<HighlightInfo> highlightInfos = myFixture.doHighlighting();
Expand All @@ -323,11 +346,7 @@ private void checkByFile(Inspection inspection, HighlightInfoChecker... highligh
String before = getTestName(true) + ".awk";
myFixture.configureByFile(before);

myFixture.enableInspections(inspection.inspection);
List<HighlightInfo> highlightInfos = myFixture.doHighlighting();
assertFalse(
"Inspection '" + inspection.quickFixName + "' must show, but is absent",
highlightInfos.isEmpty());
List<HighlightInfo> highlightInfos = assertInspectionIsShown(inspection);

if (highlightInfoCheckers != null) {
for (HighlightInfoChecker highlightInfoChecker : highlightInfoCheckers) {
Expand All @@ -348,6 +367,16 @@ private void checkByFile(Inspection inspection, HighlightInfoChecker... highligh
}
}

@NotNull
private List<HighlightInfo> assertInspectionIsShown(Inspection inspection) {
myFixture.enableInspections(inspection.inspection);
List<HighlightInfo> highlightInfos = myFixture.doHighlighting();
assertFalse(
"Inspection '" + inspection.quickFixName + "' must show, but is absent",
highlightInfos.isEmpty());
return highlightInfos;
}

private static class Inspection {
final LocalInspectionTool inspection;
final String quickFixName;
Expand Down
Loading