Skip to content

Commit c521084

Browse files
committed
First version of introduce variable in Module
1 parent 8be2c04 commit c521084

5 files changed

Lines changed: 288 additions & 0 deletions

File tree

resources/META-INF/plugin.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@
171171
<!--<applicationService serviceInterface="de.halirutan.mathematica.MathematicaSettings" serviceImplementation="de.halirutan.mathematica.MathematicaSettings"/>-->
172172
<!--<applicationConfigurable groupId="language" displayName="Mathematica" id="preferences.Mathematica"-->
173173
<!--instance="de.halirutan.mathematica.MathematicaSettingsConfigurable"/>-->
174+
<intentionAction>
175+
<className>de.halirutan.mathematica.intentions.localization.MoveVariableToLocalisation</className>
176+
</intentionAction>
174177
</extensions>
175178

176179
<actions>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#
2+
# Copyright (c) 2016 Patrick Scheibe
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
# THE SOFTWARE.
20+
#
21+
22+
familyName=Symbol intention
23+
localisation.name = Move variable to localisation
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2016 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.intentions;
23+
24+
import com.intellij.CommonBundle;
25+
import org.jetbrains.annotations.PropertyKey;
26+
27+
import java.lang.ref.Reference;
28+
import java.lang.ref.SoftReference;
29+
import java.util.ResourceBundle;
30+
31+
/**
32+
* @author patrick (7/8/14)
33+
*/
34+
public class IntentionBundle {
35+
private static final String BUNDLE = "de.halirutan.mathematica.intentions.IntentionBundle";
36+
private static Reference<ResourceBundle> ourBundle = null;
37+
38+
private IntentionBundle() {
39+
}
40+
41+
public static String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) {
42+
return CommonBundle.message(getBundle(), key, params);
43+
}
44+
45+
46+
private static ResourceBundle getBundle() {
47+
ResourceBundle bundle = null;
48+
if (ourBundle != null) bundle = ourBundle.get();
49+
if (bundle == null) {
50+
bundle = ResourceBundle.getBundle(BUNDLE);
51+
ourBundle = new SoftReference<ResourceBundle>(bundle);
52+
}
53+
return bundle;
54+
}
55+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2016 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.intentions.localization;
23+
24+
import com.intellij.openapi.util.Key;
25+
import com.intellij.psi.PsiElement;
26+
import com.intellij.psi.ResolveState;
27+
import com.intellij.psi.scope.PsiScopeProcessor;
28+
import com.intellij.psi.search.PsiElementProcessor;
29+
import de.halirutan.mathematica.parsing.psi.api.FunctionCall;
30+
import de.halirutan.mathematica.parsing.psi.util.LocalizationConstruct.ConstructType;
31+
import org.jetbrains.annotations.NotNull;
32+
import org.jetbrains.annotations.Nullable;
33+
34+
/**
35+
* @author patrick (27.12.16).
36+
*/
37+
public class FindLocalisationProcessor implements PsiScopeProcessor {
38+
39+
FunctionCall myLocalisationElement = null;
40+
41+
@Override
42+
public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) {
43+
if (element instanceof FunctionCall) {
44+
if (((FunctionCall) element).isScopingConstruct()) {
45+
ConstructType scopingConstruct = ((FunctionCall) element).getScopingConstruct();
46+
if (scopingConstruct.equals(ConstructType.BLOCK) ||
47+
scopingConstruct.equals(ConstructType.MODULE) ||
48+
scopingConstruct.equals(ConstructType.WITH)) {
49+
myLocalisationElement = (FunctionCall) element;
50+
return false;
51+
}
52+
}
53+
}
54+
return true;
55+
}
56+
57+
public FunctionCall getLocalisationElement() {
58+
return myLocalisationElement;
59+
}
60+
61+
@Nullable
62+
@Override
63+
public <T> T getHint(@NotNull Key<T> hintKey) {
64+
return null;
65+
}
66+
67+
@Override
68+
public void handleEvent(@NotNull Event event, @Nullable Object associated) {
69+
70+
}
71+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright (c) 2016 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.intentions.localization;
23+
24+
import com.intellij.codeInsight.intention.IntentionAction;
25+
import com.intellij.openapi.editor.CaretModel;
26+
import com.intellij.openapi.editor.Editor;
27+
import com.intellij.openapi.project.Project;
28+
import com.intellij.psi.*;
29+
import com.intellij.psi.util.PsiTreeUtil;
30+
import com.intellij.util.IncorrectOperationException;
31+
import de.halirutan.mathematica.intentions.IntentionBundle;
32+
import de.halirutan.mathematica.parsing.psi.api.Expression;
33+
import de.halirutan.mathematica.parsing.psi.api.FunctionCall;
34+
import de.halirutan.mathematica.parsing.psi.api.Symbol;
35+
import de.halirutan.mathematica.parsing.psi.api.lists.List;
36+
import de.halirutan.mathematica.parsing.psi.util.LocalizationConstruct.ConstructType;
37+
import de.halirutan.mathematica.parsing.psi.util.MathematicaPsiElementFactory;
38+
import org.jetbrains.annotations.Nls;
39+
import org.jetbrains.annotations.NotNull;
40+
import org.jetbrains.annotations.Nullable;
41+
42+
/**
43+
* @author patrick (27.12.16).
44+
*/
45+
public class MoveVariableToLocalisation implements IntentionAction {
46+
@Nls
47+
@NotNull
48+
@Override
49+
public String getText() {
50+
return IntentionBundle.message("localisation.name");
51+
}
52+
53+
@Nls
54+
@NotNull
55+
@Override
56+
public String getFamilyName() {
57+
return IntentionBundle.message("familyName");
58+
}
59+
60+
61+
62+
/**
63+
* Checks if there is a symbol at the caret and if there is no selection. Then it checks whether the symbol
64+
* has already a reference to a local construct like Module. If not, then we check if there is a surrounding
65+
* Module/Block/With that can be used for the introduction.
66+
* @param project current project
67+
* @param editor editor
68+
* @param file file we are editing
69+
* @return true if we can introduce a symbol in a surround Module/Block/With
70+
*/
71+
@Override
72+
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
73+
if (editor.getSelectionModel().hasSelection()) {
74+
return false;
75+
}
76+
PsiElement element = findElementAtCaret(file, editor);
77+
if (element != null) {
78+
PsiReference reference = element.getReference();
79+
if (reference != null) {
80+
PsiElement resolve = reference.resolve();
81+
if (resolve instanceof Symbol) {
82+
ConstructType elementConstruct = ((Symbol) resolve).getLocalizationConstruct();
83+
if (elementConstruct != ConstructType.NULL) {
84+
return false;
85+
}
86+
}
87+
}
88+
return !PsiTreeUtil.treeWalkUp(new FindLocalisationProcessor(), element, file, ResolveState.initial());
89+
}
90+
return false;
91+
}
92+
93+
@Override
94+
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
95+
final PsiElement element = findElementAtCaret(file, editor);
96+
if (element == null) {
97+
return;
98+
}
99+
assert element.isValid() : element;
100+
FindLocalisationProcessor processor = new FindLocalisationProcessor();
101+
boolean notFound = PsiTreeUtil.treeWalkUp(processor, element, file, ResolveState.initial());
102+
if (!notFound) {
103+
FunctionCall localisationElement = processor.myLocalisationElement;
104+
if (localisationElement != null && localisationElement.isValid()) {
105+
PsiElement initList = localisationElement.getArgument(1);
106+
if (initList instanceof List) {
107+
MathematicaPsiElementFactory factory = new MathematicaPsiElementFactory(project);
108+
String text = initList.getText();
109+
Expression newList = factory.createExpressionFromText(text.substring(0, text.length() - 1) +
110+
", " + element.getText() + "}");
111+
initList.replace(newList);
112+
}
113+
}
114+
}
115+
}
116+
117+
@Override
118+
public boolean startInWriteAction() {
119+
return true;
120+
}
121+
122+
@Nullable
123+
private PsiElement findElementAtCaret(PsiFile file, Editor editor) {
124+
CaretModel caretModel = editor.getCaretModel();
125+
int offset = caretModel.getOffset();
126+
PsiElement element = file.findElementAt(offset);
127+
if (element instanceof PsiWhiteSpace) {
128+
element = file.findElementAt(Math.max(0, offset - 1));
129+
}
130+
if (element != null && element.getContext() instanceof Symbol) {
131+
return element.getContext();
132+
}
133+
return null;
134+
}
135+
136+
}

0 commit comments

Comments
 (0)