Skip to content

Commit 914efff

Browse files
committed
Fix for resolve bug in patterns
In a construct like {a_, a_} :> a_ the second a did not refer to the first a which it should. All "a" should have one single symbol they refer to.
1 parent f6e2425 commit 914efff

6 files changed

Lines changed: 41 additions & 45 deletions

File tree

src/de/halirutan/mathematica/lang/psi/impl/SymbolImpl.java

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525

2626
import com.intellij.lang.ASTNode;
2727
import com.intellij.openapi.util.TextRange;
28-
import com.intellij.psi.*;
28+
import com.intellij.psi.PsiElement;
29+
import com.intellij.psi.PsiElementVisitor;
30+
import com.intellij.psi.PsiFileFactory;
31+
import com.intellij.psi.PsiReference;
2932
import com.intellij.psi.impl.source.resolve.ResolveCache;
3033
import com.intellij.util.IncorrectOperationException;
3134
import de.halirutan.mathematica.file.MathematicaFileType;
@@ -212,27 +215,9 @@ public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOpe
212215
return null;
213216
}
214217

215-
/**
216-
* This method is used by {@link PsiManager#areElementsEquivalent(PsiElement, PsiElement)}
217-
* @param another the other element which is tested to be equal to this element
218-
* @return true if the full symbol name is the same.
219-
*/
220-
@Override
221-
public boolean isEquivalentTo(PsiElement another) {
222-
if (super.isEquivalentTo(another)) {
223-
return true;
224-
}
225-
if (another instanceof PsiReference) {
226-
final PsiElement myDef = resolve();
227-
final PsiElement otherDef = ((PsiReference) another).resolve();
228-
return myDef != null && otherDef != null && myDef == otherDef;
229-
}
230-
return false;
231-
}
232-
233218
@Override
234219
public boolean isReferenceTo(PsiElement element) {
235-
return getManager().areElementsEquivalent(resolve(), element);
220+
return (element instanceof Symbol || element instanceof LightSymbol) && getManager().areElementsEquivalent(resolve(), element);
236221
}
237222

238223
@NotNull

src/de/halirutan/mathematica/lang/psi/util/PatternSymbolExtractor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import de.halirutan.mathematica.lang.psi.api.pattern.Pattern
4141
*/
4242
class PatternSymbolExtractor : MathematicaVisitor() {
4343

44-
val patternSymbols = HashSet<Symbol>()
44+
val patternSymbols = ArrayList<Symbol>()
4545
/* Except | Longest | Optional | PatternTest | Repeated | RepeatedNull | Shortest
4646
* HoldPattern | IgnoringInactive | KeyValuePattern | Literal | Longest | Optional | Repeated | RepeatedNull | Shortest
4747
* */

tests/de/halirutan/mathematica/MathematicaLexerTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ protected Lexer createLexer() {
3535
return new MathematicaLexer();
3636
}
3737

38-
public void testSlots1() throws Exception {
38+
public void testSlots1() {
3939
doTest("#[#Test&, #\"Test\"&]&;",
4040
"SLOT ('#')\n" +
4141
"LEFT_BRACKET ('[')\n" +
@@ -50,7 +50,7 @@ public void testSlots1() throws Exception {
5050
"SEMICOLON (';')");
5151
}
5252

53-
public void testNumbers() throws Exception {
53+
public void testNumbers() {
5454
doTest("1", "NUMBER ('1')");
5555
doTest("1.0", "NUMBER ('1.0')");
5656
doTest("16^^abc", "NUMBER ('16^^abc')");
@@ -62,7 +62,7 @@ public void testNumbers() throws Exception {
6262
doTest("12``12", "NUMBER ('12``12')");
6363
}
6464

65-
public void testRepeatedAmbiguity() throws Exception {
65+
public void testRepeatedAmbiguity() {
6666
// Actually, this is not what Mathematica parses which is Repeated[1]
6767
// but the documentation states that the point for the number 1. should bind stronger
6868
doTest("1..", "NUMBER ('1.')\n" + "POINT ('.')");

tests/de/halirutan/mathematica/lang/resolve/LocalVariableResolveTestCase.kt

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,37 @@ class LocalVariableResolveTestCase : AbstractResolveTest() {
4545
"Compile[{{x, _Real}, y, {z, _Real, 0}}, x+<ref>y+z ]" to TextRange.create(21, 22)
4646
)
4747

48+
private val ruleDelayedLike = mapOf(
49+
"{test_, test_} :> <ref>test" to TextRange.create(1, 5),
50+
"HoldComplete[ReturnPacket[{expr_ :> expr_}]] :> HoldComplete[<ref>expr]" to TextRange.create(27, 31)
51+
)
52+
4853
fun testModule() {
49-
for (testCase in moduleLike) {
50-
val psiReference = configureByFileText(testCase.key)
54+
for ((key, value) in moduleLike) {
55+
val psiReference = configureByFileText(key)
5156
val resolve = psiReference.resolve()
5257
TestCase.assertNotNull(resolve)
53-
TestCase.assertEquals(testCase.value, resolve?.textRange)
54-
}
58+
TestCase.assertEquals(value, resolve?.textRange)
5559
}
60+
}
5661

5762
fun testCompile() {
58-
for (testCase in compileLike) {
59-
val ref = configureByFileText(testCase.key)
63+
for ((key, value) in compileLike) {
64+
val ref = configureByFileText(key)
6065
val resolve = ref.resolve()
6166
TestCase.assertNotNull(resolve)
62-
TestCase.assertEquals(testCase.value, resolve?.textRange)
67+
TestCase.assertEquals(value, resolve?.textRange)
6368
}
69+
}
70+
71+
fun testRuleDelayed() {
72+
for ((key, value) in ruleDelayedLike) {
73+
val ref = configureByFileText(key)
74+
val resolve = ref.resolve()
75+
TestCase.assertNotNull(resolve)
76+
TestCase.assertEquals(value, resolve?.textRange)
6477
}
78+
}
6579

6680

6781
}

tests/de/halirutan/mathematica/lang/resolve/ResolvePerformanceTest.kt

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323

2424
package de.halirutan.mathematica.lang.resolve
2525

26-
import de.halirutan.mathematica.lang.psi.MathematicaRecursiveVisitor
27-
import de.halirutan.mathematica.lang.psi.api.Symbol
28-
2926

3027
/**
3128
* @author patrick (20.07.17).
@@ -37,14 +34,14 @@ class ResolvePerformanceTest : AbstractResolveTest() {
3734
val count = object {
3835
var value = 0
3936
}
40-
val file = createFile("LargeFile.m", loadFile("LargeFile.m"))
37+
// val file = createFile("LargeFile.m", loadFile("LargeFile.m"))
4138
val start = System.nanoTime()
42-
file.accept(object : MathematicaRecursiveVisitor() {
43-
override fun visitSymbol(symbol: Symbol) {
44-
val resolve = symbol.resolve()
45-
resolve?.let { count.value++ }
46-
}
47-
})
39+
// file.accept(object : MathematicaRecursiveVisitor() {
40+
// override fun visitSymbol(symbol: Symbol) {
41+
// val resolve = symbol.resolve()
42+
// resolve?.let { count.value++ }
43+
// }
44+
// })
4845
val stop = System.nanoTime()
4946
println("Resolved ${count.value} Symbols in ${(stop - start) / 1e9} seconds")
5047
}

tests/de/halirutan/mathematica/refactoring/RenameTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
*/
3030
public class RenameTest extends LightCodeInsightFixtureTestCase{
3131

32-
public void testNormalVariable() throws Exception {
32+
public void testNormalVariable() {
3333
myFixture.configureByText(MathematicaFileType.INSTANCE,
3434
"var1;\n" +
3535
"var1::usage = \"var1 is equal to nothing..\";\n" +
@@ -40,7 +40,7 @@ public void testNormalVariable() throws Exception {
4040
"var2=1;");
4141
}
4242

43-
public void testModule() throws Exception {
43+
public void testModule() {
4444
myFixture.configureByText(MathematicaFileType.INSTANCE,
4545
"var;\n" +
4646
"var::usage = \"var is equal to nothing..\";\n" +
@@ -61,14 +61,14 @@ public void testModule() throws Exception {
6161
"]");
6262
}
6363

64-
public void testUsage() throws Exception {
64+
public void testUsage() {
6565
myFixture.configureByText(MathematicaFileType.INSTANCE,
6666
"func::usage = \"func<caret> is a function called like func[]\";");
6767
myFixture.renameElementAtCaret("newFunc");
6868
myFixture.checkResult("newFunc::usage = \"newFunc is a function called like newFunc[]\";");
6969
}
7070

71-
public void testUsage2() throws Exception {
71+
public void testUsage2() {
7272
myFixture.configureByText(MathematicaFileType.INSTANCE,
7373
"func<caret>::usage = \"func is a function called like func[]\";");
7474
myFixture.renameElementAtCaret("newFunc");

0 commit comments

Comments
 (0)