Skip to content

Commit 5b0cb44

Browse files
committed
Extended SymbolResolveResult
1 parent ddd025c commit 5b0cb44

13 files changed

Lines changed: 197 additions & 252 deletions

.idea/modules/Mathematica-IntelliJ-Plugin_main.iml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules/Mathematica-IntelliJ-Plugin_test.iml

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/scopes/scope_settings.xml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/de/halirutan/mathematica/file/MathematicaFileTypeFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121

2222
package de.halirutan.mathematica.file;
2323

24+
import com.intellij.icons.AllIcons;
25+
import com.intellij.ide.DataManager;
2426
import com.intellij.openapi.fileTypes.FileTypeConsumer;
2527
import com.intellij.openapi.fileTypes.FileTypeFactory;
28+
import com.intellij.openapi.project.Project;
29+
import com.intellij.openapi.project.ProjectManager;
30+
import com.intellij.openapi.project.ex.ProjectManagerEx;
2631
import de.halirutan.mathematica.file.MathematicaFileType;
2732
import org.jetbrains.annotations.NotNull;
2833

@@ -33,6 +38,7 @@ public class MathematicaFileTypeFactory extends FileTypeFactory {
3338

3439
@Override
3540
public void createFileTypes(@NotNull FileTypeConsumer consumer) {
41+
final Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
3642
consumer.consume(MathematicaFileType.INSTANCE, "m;mb;mt;nb;wl;wlt");
3743
}
3844

src/de/halirutan/mathematica/lang/psi/util/LocalizationConstruct.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ public enum MScope {
132132
FILE_SCOPE("File Scope"),
133133
NULL_SCOPE("Null Scope");
134134

135-
private final String myName;
136-
private final ScopeParameter myType;
137-
private final int myScopePositionStart;
138-
private final int myScopePositionEnd;
135+
final String myName;
136+
final ScopeParameter myType;
137+
final int myScopePositionStart;
138+
final int myScopePositionEnd;
139139

140140
MScope(final String name, final ScopeParameter type, int start, int end) {
141141
myName = name;

src/de/halirutan/mathematica/lang/psi/util/MathematicaPsiUtilities.java

Lines changed: 14 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -261,21 +261,23 @@ public static SymbolResolveResult resolveLocalFunctionVariables(Symbol myStartEl
261261
return null;
262262
}
263263

264+
final MScope scope = functionCall.getScopingConstruct();
265+
264266
final PsiElement lastParent = state.get(SymbolResolveHint.LAST_PARENT);
265267
final PsiElement firstArgument = arguments.get(0);
266268
PsiElement definitions = arguments.size() > 1 ? firstArgument : null;
267269
if (definitions != null) {
268-
boolean inDefition = definitions.equals(lastParent);
270+
boolean inDefinition = definitions.equals(lastParent);
269271
if (firstArgument instanceof Symbol && !((Symbol) firstArgument).getSymbolName().equals("Null") && ((Symbol) firstArgument).getFullSymbolName().equals(myStartElement.getFullSymbolName())) {
270-
return new SymbolResolveResult(firstArgument, MScope.FUNCTION, true);
272+
return new SymbolResolveResult(firstArgument, scope, functionCall, true);
271273
} else if (firstArgument instanceof MList) {
272-
final List<Symbol> defs = getDefinitionSymbolsFromList(firstArgument);
273-
for (Symbol def : defs) {
274+
final List<Symbol> defSymbols = getDefinitionSymbolsFromList(firstArgument);
275+
for (Symbol def : defSymbols) {
274276
if (def.getFullSymbolName().equals(myStartElement.getFullSymbolName())) {
275-
if (!inDefition || def.equals(myStartElement)) {
276-
return new SymbolResolveResult(def, MScope.FUNCTION, true);
277+
if (!inDefinition || def.equals(myStartElement)) {
278+
return new SymbolResolveResult(def, scope, functionCall, true);
277279
} else {
278-
return new SymbolResolveResult(myStartElement, MScope.NULL_SCOPE, true);
280+
return new SymbolResolveResult(myStartElement, scope, functionCall, true);
279281
}
280282
}
281283
}
@@ -351,11 +353,11 @@ public static SymbolResolveResult resolveLocalModuleLikeVariables(@NotNull Symbo
351353
if (e instanceof Symbol) {
352354
if (((Symbol) e).getSymbolName().equals(symbol.getSymbolName())) {
353355
if (!isInDefList || e.equals(symbol)) {
354-
return new SymbolResolveResult(e, scopingConstruct, true);
356+
return new SymbolResolveResult(e, scopingConstruct, functionCall, true);
355357
} else {
356358
final List<Symbol> definitionInList = getDefinitionSymbolsFromList(moduleDefList);
357359
if (definitionInList.contains(symbol)) {
358-
return new SymbolResolveResult(symbol, scopingConstruct, false);
360+
return new SymbolResolveResult(symbol, scopingConstruct, functionCall, false);
359361
} else {
360362
return null;
361363
}
@@ -425,7 +427,7 @@ public static SymbolResolveResult resolveLocalTableLikeVariables(Symbol myStartE
425427
final PsiElement firstListElement = getFirstListElement(currentIterator);
426428
if (firstListElement instanceof Symbol) {
427429
if (((Symbol) firstListElement).getFullSymbolName().equals(myStartElement.getFullSymbolName())) {
428-
return new SymbolResolveResult(firstListElement, scopingConstruct, true);
430+
return new SymbolResolveResult(firstListElement, scopingConstruct, functionCall, true);
429431
}
430432
}
431433
}
@@ -434,7 +436,7 @@ public static SymbolResolveResult resolveLocalTableLikeVariables(Symbol myStartE
434436
// self-reference if we are the iterator
435437
if (args[pos] instanceof MList) {
436438
if (Objects.equals(getFirstListElement(args[pos]), myStartElement)) {
437-
return new SymbolResolveResult(myStartElement, scopingConstruct, true);
439+
return new SymbolResolveResult(myStartElement, scopingConstruct, functionCall, true);
438440
}
439441
}
440442

@@ -444,7 +446,7 @@ public static SymbolResolveResult resolveLocalTableLikeVariables(Symbol myStartE
444446
final PsiElement firstListElement = getFirstListElement(args[i]);
445447
if (firstListElement instanceof Symbol) {
446448
if (((Symbol) firstListElement).getFullSymbolName().equals(myStartElement.getFullSymbolName())) {
447-
return new SymbolResolveResult(firstListElement, scopingConstruct, true);
449+
return new SymbolResolveResult(firstListElement, scopingConstruct, functionCall, true);
448450
}
449451
}
450452
}
@@ -529,47 +531,6 @@ public static List<Symbol> getLocalCompileLikeVariables(FunctionCall element) {
529531
}
530532

531533

532-
@Nullable
533-
public static SymbolResolveResult resolveLocalCompileLikeVariables(Symbol myStartElement, FunctionCall functionCall, ResolveState state) {
534-
535-
final PsiElement lastParent = state.get(SymbolResolveHint.LAST_PARENT);
536-
final List<PsiElement> arguments = getArguments(functionCall);
537-
if (arguments.size() < 1) {
538-
return null;
539-
}
540-
541-
final PsiElement firstArgument = arguments.get(0);
542-
boolean inDef = firstArgument.equals(lastParent);
543-
544-
545-
final MScope scopingConstruct = functionCall.getScopingConstruct();
546-
if (firstArgument instanceof Symbol) {
547-
if (((Symbol) firstArgument).getFullSymbolName().equals(myStartElement.getFullSymbolName())) {
548-
return new SymbolResolveResult(firstArgument, scopingConstruct, true);
549-
}
550-
} else if (firstArgument instanceof MList) {
551-
final PsiElement[] children = firstArgument.getChildren();
552-
for (PsiElement child : children) {
553-
if (child instanceof MList) {
554-
child = child.getFirstChild();
555-
}
556-
if (child instanceof Symbol) {
557-
if (inDef) {
558-
if (child.equals(myStartElement)) {
559-
return new SymbolResolveResult(child, scopingConstruct, true);
560-
}
561-
} else {
562-
if (((Symbol) child).getFullSymbolName().equals(myStartElement.getFullSymbolName())) {
563-
return new SymbolResolveResult(child, scopingConstruct, true);
564-
}
565-
}
566-
}
567-
}
568-
}
569-
return null;
570-
}
571-
572-
573534
/**
574535
* This extracts the local defined argument for a <code>Limit[Sin[x]/x, x-> 0]</code> call. Note that the returned
575536
* list has always only one element since <code>Limit</code> always uses only one variable.

src/de/halirutan/mathematica/lang/resolve/MathematicaSymbolResolver.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
import static de.halirutan.mathematica.lang.psi.util.MathematicaPsiUtilities.isBuiltInSymbol;
4848

4949
/**
50+
* The symbol resolver works currently in 3 steps to find a possible definition of a symbol that appears in the code.
51+
* It will check if the symbol is a built-in symbol
52+
* It will make a tree-walk upwards to check if the symbol is in any localization construct
53+
* It will check the file, if the symbol is defined as a global symbol like a function at file-scope
54+
* It will check the file-index and look for symbols that are exported from other files
5055
* @author patrick (08.07.17).
5156
*/
5257
public class MathematicaSymbolResolver implements AbstractResolver<Symbol, SymbolResolveResult> {
@@ -56,27 +61,29 @@ public class MathematicaSymbolResolver implements AbstractResolver<Symbol, Symbo
5661
public SymbolResolveResult resolve(@NotNull Symbol ref, boolean incompleteCode) {
5762

5863
if (isBuiltInSymbol(ref)){
59-
return new SymbolResolveResult(new LightBuiltInSymbol(ref), MScope.KERNEL_SCOPE, true);
64+
return new SymbolResolveResult(new LightBuiltInSymbol(ref), MScope.KERNEL_SCOPE, null, true);
6065
}
6166

6267
LocalDefinitionResolveProcessor processor = new LocalDefinitionResolveProcessor(ref);
6368
final PsiFile containingFile = ref.getContainingFile();
6469
PsiTreeUtil.treeWalkUp(processor, ref, containingFile, ResolveState.initial());
65-
final Symbol referringSymbol = processor.getMyReferringSymbol();
66-
if (referringSymbol != null) {
67-
return new SymbolResolveResult(referringSymbol, processor.getMyLocalization(), true);
70+
final SymbolResolveResult resolveResult = processor.getResolveResult();
71+
if (resolveResult != null) {
72+
return resolveResult;
6873
}
6974

7075
GlobalDefinitionResolveProcessor globalProcessor = new GlobalDefinitionResolveProcessor(ref);
7176
PsiTreeUtil.processElements(containingFile, globalProcessor);
7277

7378

74-
final PsiElement globalDefinition = globalProcessor.getMyReferringSymbol();
75-
if (globalDefinition != null) {
79+
final SymbolResolveResult globalProcessorResolveResult = globalProcessor.getResolveResult();
80+
if (globalProcessorResolveResult != null) {
7681
if (containingFile instanceof MathematicaPsiFile) {
77-
((MathematicaPsiFile) containingFile).cacheDefinition(globalDefinition.getText());
82+
if (globalProcessorResolveResult.getElement() != null) {
83+
((MathematicaPsiFile) containingFile).cacheDefinition(globalProcessorResolveResult.getElement().getText());
84+
}
7885
}
79-
return new SymbolResolveResult(globalDefinition, MScope.FILE_SCOPE, true);
86+
return globalProcessorResolveResult;
8087
}
8188

8289
final FileBasedIndex fileIndex = FileBasedIndex.getInstance();
@@ -94,15 +101,15 @@ public SymbolResolveResult resolve(@NotNull Symbol ref, boolean incompleteCode)
94101
// final PsiElement elementAt = psiFile.findElementAt(key.getOffset());
95102
final Symbol elementAt = PsiTreeUtil.findElementOfClassAtOffset(psiFile, key.getOffset(), Symbol.class, true);
96103
if (elementAt != null) {
97-
return new SymbolResolveResult(elementAt, MScope.FILE_SCOPE, true);
104+
return new SymbolResolveResult(elementAt, MScope.FILE_SCOPE, psiFile, true);
98105
}
99-
return new SymbolResolveResult(psiFile, MScope.FILE_SCOPE, true);
106+
return new SymbolResolveResult(psiFile, MScope.FILE_SCOPE, psiFile, true);
100107
}
101108
}
102109
}
103110
}
104111

105-
return new SymbolResolveResult(new LightUndefinedSymbol(ref), MScope.NULL_SCOPE, true);
112+
return new SymbolResolveResult(new LightUndefinedSymbol(ref), MScope.NULL_SCOPE, ref.getContainingFile(), false);
106113

107114
}
108115

src/de/halirutan/mathematica/lang/resolve/SymbolResolveResult.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323

2424
import com.intellij.psi.PsiElement;
2525
import com.intellij.psi.ResolveResult;
26-
import de.halirutan.mathematica.lang.psi.util.LocalizationConstruct;
2726
import de.halirutan.mathematica.lang.psi.util.LocalizationConstruct.MScope;
27+
import org.jetbrains.annotations.NotNull;
2828
import org.jetbrains.annotations.Nullable;
2929

3030
/**
@@ -33,12 +33,14 @@
3333
public class SymbolResolveResult implements ResolveResult {
3434

3535
private final PsiElement myElement;
36+
private final PsiElement myScopingElement;
3637
private final boolean myIsValid;
3738
private MScope myLocalization;
3839

39-
public SymbolResolveResult(PsiElement element, MScope scope, boolean isValid) {
40+
public SymbolResolveResult(@NotNull PsiElement element, @NotNull MScope scope, @Nullable PsiElement myScopingElement, boolean isValid) {
4041
this.myElement = element;
4142
this.myLocalization = scope;
43+
this.myScopingElement = myScopingElement;
4244
this.myIsValid = isValid;
4345
}
4446

@@ -52,6 +54,10 @@ public MScope getLocalization() {
5254
return myLocalization;
5355
}
5456

57+
public PsiElement getScopingElement() {
58+
return myScopingElement;
59+
}
60+
5561
@Override
5662
public boolean isValidResult() {
5763
return myIsValid;

0 commit comments

Comments
 (0)