Skip to content

Commit a637bca

Browse files
committed
Improve and fix setting up modules and language levels per module
1 parent 396401e commit a637bca

16 files changed

Lines changed: 251 additions & 235 deletions

src/de/halirutan/mathematica/codeinsight/inspections/bugs/UnsupportedVersion.java

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,12 @@
2727
import com.intellij.codeInspection.LocalInspectionToolSession;
2828
import com.intellij.codeInspection.ProblemsHolder;
2929
import com.intellij.openapi.module.Module;
30-
import com.intellij.openapi.module.ModuleManager;
31-
import com.intellij.openapi.module.ModuleType;
30+
import com.intellij.openapi.module.ModuleUtilCore;
3231
import com.intellij.openapi.projectRoots.Sdk;
33-
import com.intellij.openapi.roots.ModuleFileIndex;
34-
import com.intellij.openapi.roots.ModuleRootManager;
3532
import com.intellij.openapi.roots.ProjectRootManager;
3633
import com.intellij.openapi.ui.ComboBox;
3734
import com.intellij.openapi.ui.VerticalFlowLayout;
3835
import com.intellij.openapi.util.TextRange;
39-
import com.intellij.openapi.vfs.VirtualFile;
4036
import com.intellij.psi.PsiElement;
4137
import com.intellij.psi.PsiElementVisitor;
4238
import com.intellij.psi.PsiFile;
@@ -48,8 +44,7 @@
4844
import de.halirutan.mathematica.lang.psi.api.Symbol;
4945
import de.halirutan.mathematica.lang.psi.api.lists.Association;
5046
import de.halirutan.mathematica.lang.psi.impl.LightBuiltInSymbol;
51-
import de.halirutan.mathematica.module.MathematicaLanguageLevelModuleExtensionImpl;
52-
import de.halirutan.mathematica.module.MathematicaModuleType;
47+
import de.halirutan.mathematica.module.MathematicaLanguageLevelModuleExtension;
5348
import de.halirutan.mathematica.sdk.MathematicaLanguageLevel;
5449
import de.halirutan.mathematica.sdk.MathematicaSdkType;
5550
import org.jetbrains.annotations.Nls;
@@ -73,6 +68,7 @@ public class UnsupportedVersion extends AbstractInspection {
7368

7469
@SuppressWarnings({"InstanceVariableNamingConvention", "WeakerAccess"})
7570
public boolean useSDKLanguageLevelOrHighest = true;
71+
@SuppressWarnings("WeakerAccess")
7672
public boolean useModuleLanguageLevelOrHighest = true;
7773

7874
/**
@@ -168,23 +164,13 @@ public HighlightDisplayLevel getDefaultLevel() {
168164
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly, @NotNull LocalInspectionToolSession session) {
169165
if (session.getFile().getFileType() instanceof MathematicaFileType) {
170166

171-
// TODO: There must be a simpler way to find the module for a source file
172167
if (useModuleLanguageLevelOrHighest) {
173168
final PsiFile file = session.getFile();
174-
final ModuleManager instance = ModuleManager.getInstance(file.getProject());
175-
for (Module module : instance.getModules()) {
176-
if (ModuleType.is(module, MathematicaModuleType.getInstance())) {
177-
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
178-
final ModuleFileIndex fileIndex = moduleRootManager.getFileIndex();
179-
final VirtualFile virtualFile = file.getVirtualFile();
180-
if (fileIndex.isInContent(virtualFile)) {
181-
final MathematicaLanguageLevelModuleExtensionImpl languageLevelModuleExtension =
182-
moduleRootManager.getModuleExtension(MathematicaLanguageLevelModuleExtensionImpl.class);
183-
if (languageLevelModuleExtension.getMathematicaLanguageLevel() != null) {
184-
return new WrongVersionVisitor(holder, languageLevelModuleExtension.getMathematicaLanguageLevel());
185-
}
186-
}
187-
}
169+
final Module moduleForFile = ModuleUtilCore.findModuleForFile(file.getVirtualFile(), file.getProject());
170+
if (moduleForFile != null) {
171+
final MathematicaLanguageLevel mathematicaLanguageLevel =
172+
MathematicaLanguageLevelModuleExtension.getInstance(moduleForFile).getMathematicaLanguageLevel();
173+
return new WrongVersionVisitor(holder, mathematicaLanguageLevel);
188174
}
189175
}
190176

src/de/halirutan/mathematica/lang/resolve/processors/LocalDefinitionResolveProcessor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ import de.halirutan.mathematica.lang.resolve.resolvers.TableLikeResolver
8383
class LocalDefinitionResolveProcessor(private val myStartElement: Symbol) : BaseScopeProcessor() {
8484
/**
8585
* Returns the list of all symbols collected during a run. Before returning
86-
* the list, it removes duplicates, so that no entry appears more than once in the autocompletion window.
86+
* the list, it removes duplicates, so that no entry appears more than once in the auto-completion window.
8787
*
8888
* @return Sorted and cleaned list of collected symbols.
8989
*/
9090
var resolveResult: SymbolResolveResult? = null
9191

9292
/**
9393
* There are several places where a local variable can be "defined". First I check all localization constructs which
94-
* are always function call like `Module[{blub},...]`. The complete list of localization constructs can be
94+
* are always function call like `Module[{var},...]`. The complete list of localization constructs can be
9595
* found in [MScope].
9696
*
9797
*

src/de/halirutan/mathematica/lang/resolve/resolvers/FunctionLikeResolver.kt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.intellij.psi.ResolveState
2727
import de.halirutan.mathematica.lang.psi.LocalizationConstruct
2828
import de.halirutan.mathematica.lang.psi.api.FunctionCall
2929
import de.halirutan.mathematica.lang.psi.api.Symbol
30+
import de.halirutan.mathematica.lang.psi.api.lists.MList
3031
import de.halirutan.mathematica.lang.resolve.SymbolResolveHint
3132
import de.halirutan.mathematica.lang.resolve.SymbolResolveResult
3233

@@ -49,14 +50,25 @@ class FunctionLikeResolver : Resolver {
4950

5051
// Symbol to resolve is located in the body of Compile
5152
if (lastParent == body) {
52-
defLists
53-
.filter { it is Symbol && it.hasSameName(symbol) }
54-
.forEach { return SymbolResolveResult(it, scope, scopingElement, true) }
53+
for (defList in defLists) {
54+
if (defList is MList) {
55+
for (elm in defList.listElements) {
56+
if (elm is Symbol && elm.hasSameName(symbol)) {
57+
return SymbolResolveResult(elm, scope, scopingElement, true)
58+
}
59+
60+
}
61+
}
62+
}
5563
} else {
5664
defLists.indexOf(lastParent).takeUnless { it == -1 }?.let {
57-
val defList = defLists[it]
58-
if (defList is Symbol && defList == symbol) {
59-
return SymbolResolveResult(defList, scope, scopingElement, true)
65+
val expr = defLists[it]
66+
if (expr is MList) {
67+
for (elm in expr.listElements) {
68+
if (elm is Symbol && elm == symbol) {
69+
return SymbolResolveResult(elm, scope, scopingElement, true)
70+
}
71+
}
6072
}
6173
}
6274
}

src/de/halirutan/mathematica/module/MathematicaApplicationModule.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import de.halirutan.mathematica.MathematicaBundle;
66

77
/**
8-
* @author patrick (08.12.17).
8+
* A module builder that creates a package structure containing a separate folder for the source code. Under this folder
9+
* it creates PacletInfo.m, package and notebook file and a Kernel directory with an init.m
910
*/
1011
public class MathematicaApplicationModule extends MathematicaModuleBuilder {
12+
13+
@SuppressWarnings("WeakerAccess")
1114
public MathematicaApplicationModule() {
1215
}
1316

14-
1517
@Override
1618
public String getPresentableName() {
1719
return MathematicaBundle.message("project.template.application");

src/de/halirutan/mathematica/module/MathematicaBasicModule.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
package de.halirutan.mathematica.module;
22

3-
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
4-
import com.intellij.ide.util.projectWizard.WizardContext;
5-
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
3+
import com.intellij.openapi.project.Project;
4+
import com.intellij.openapi.vfs.VirtualFile;
65
import de.halirutan.mathematica.MathematicaBundle;
7-
import org.jetbrains.annotations.NotNull;
86

97
/**
10-
* @author patrick (08.12.17).
8+
* A module builder that adds a simple package and a notebook file and nothing more
119
*/
1210
public class MathematicaBasicModule extends MathematicaModuleBuilder {
11+
12+
@SuppressWarnings("WeakerAccess")
1313
public MathematicaBasicModule() {
1414
}
1515

1616
@Override
17-
public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
18-
return ModuleWizardStep.EMPTY_ARRAY;
17+
protected void createModuleStructure(Project project, VirtualFile contentRoot) {
18+
createProjectFiles(project, contentRoot);
1919
}
2020

2121
@Override

src/de/halirutan/mathematica/module/MathematicaEmptyModule.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import de.halirutan.mathematica.MathematicaBundle;
44

55
/**
6-
* @author patrick (08.12.17).
6+
* Module builder for an empty module that does not create any folder structure or files
77
*/
88
public class MathematicaEmptyModule extends MathematicaModuleBuilder {
9+
10+
@SuppressWarnings("WeakerAccess")
911
public MathematicaEmptyModule() {
1012
}
1113

src/de/halirutan/mathematica/module/MathematicaGeneralModuleSettingsEditor.java

Lines changed: 0 additions & 56 deletions
This file was deleted.
Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,43 @@
11
package de.halirutan.mathematica.module;
22

3+
import com.intellij.openapi.module.Module;
4+
import com.intellij.openapi.roots.ModuleExtension;
5+
import com.intellij.openapi.roots.ModuleRootManager;
36
import de.halirutan.mathematica.sdk.MathematicaLanguageLevel;
4-
5-
import javax.annotation.Nullable;
7+
import org.jetbrains.annotations.NotNull;
68

79
/**
10+
* Interface declaring the methods that should be used by the user. Most other stuff in {@link MathematicaLanguageLevelModuleExtensionImpl}
11+
* is internal (although declared public to make it accessible for the IntelliJ framework).
812
* @author patrick (21.12.17).
913
*/
10-
public interface MathematicaLanguageLevelModuleExtension {
11-
@Nullable
12-
MathematicaLanguageLevel getMathematicaLanguageLevel();
14+
public abstract class MathematicaLanguageLevelModuleExtension extends ModuleExtension {
15+
16+
/**
17+
* Returns an instance of the extension for a module. Always use this and not the constructor of the implementing
18+
* class.
19+
*
20+
* @param module The module you want the extension for
21+
*
22+
* @return Instance that can be accessed and changed
23+
*/
24+
public static MathematicaLanguageLevelModuleExtension getInstance(Module module) {
25+
return ModuleRootManager.getInstance(module).getModuleExtension(MathematicaLanguageLevelModuleExtension.class);
26+
}
27+
28+
/**
29+
* Gets the current the language version for the module.
30+
*
31+
* @return Mathematica version that is used in the module
32+
*/
33+
@NotNull
34+
public abstract MathematicaLanguageLevel getMathematicaLanguageLevel();
1335

14-
void setMathematicaLanguageLevel(MathematicaLanguageLevel languageLevel);
36+
/**
37+
* Sets the language version for a module.
38+
*
39+
* @param languageLevel New language version.
40+
*/
41+
public abstract void setMathematicaLanguageLevel(MathematicaLanguageLevel languageLevel);
1542

1643
}

0 commit comments

Comments
 (0)