Merge remote-tracking branch 'origin/master'

This commit is contained in:
Konstantin Bulenkov
2012-10-23 16:57:51 +02:00
139 changed files with 2189 additions and 688 deletions
@@ -76,6 +76,7 @@ class RunConfigurable extends BaseConfigurable {
private static final Icon SHARED_ICON = IconLoader.getTransparentIcon(AllIcons.Nodes.Symlink, .6f);
private static final Icon NON_SHARED_ICON = EmptyIcon.ICON_16;
@NonNls private static final String DIVIDER_PROPORTION = "dividerProportion";
@NonNls private static final String DEFAULTS = "Defaults";
private volatile boolean isDisposed = false;
@@ -210,7 +211,7 @@ class RunConfigurable extends BaseConfigurable {
}
// add defaults
final DefaultMutableTreeNode defaults = new DefaultMutableTreeNode("Defaults");
final DefaultMutableTreeNode defaults = new DefaultMutableTreeNode(DEFAULTS);
final ConfigurationType[] configurationTypes = RunManagerImpl.getInstanceImpl(myProject).getConfigurationFactories();
for (final ConfigurationType type : configurationTypes) {
if (!(type instanceof UnknownConfigurationType)) {
@@ -1269,7 +1270,7 @@ class RunConfigurable extends BaseConfigurable {
}
public void actionPerformed(final AnActionEvent e) {
TreeNode defaults = TreeUtil.findNodeWithObject("Defaults", myTree.getModel(), myRoot);
TreeNode defaults = TreeUtil.findNodeWithObject(DEFAULTS, myTree.getModel(), myRoot);
if (defaults != null) {
final ConfigurationType configurationType = getSelectedConfigurationType();
if (configurationType != null) {
@@ -1285,7 +1286,19 @@ class RunConfigurable extends BaseConfigurable {
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(TreeUtil.findNodeWithObject("Defaults", myTree.getModel(), myRoot) != null);
boolean isEnabled = TreeUtil.findNodeWithObject(DEFAULTS, myTree.getModel(), myRoot) != null;
TreePath path = myTree.getSelectionPath();
if (path != null) {
Object o = path.getLastPathComponent();
if (o instanceof DefaultMutableTreeNode && ((DefaultMutableTreeNode)o).getUserObject().equals(DEFAULTS)) {
isEnabled = false;
}
o = path.getParentPath().getLastPathComponent();
if (o instanceof DefaultMutableTreeNode && ((DefaultMutableTreeNode)o).getUserObject().equals(DEFAULTS)) {
isEnabled = false;
}
}
e.getPresentation().setEnabled(isEnabled);
}
}
@Nullable
@@ -254,7 +254,7 @@ public final class ActionMenu extends JMenu {
mayContextBeInvalid = false;
}
else {
context = DataManager.getInstance().getDataContext(this);
context = DataManager.getInstance().getDataContext();
mayContextBeInvalid = true;
}
Utils.fillMenu(myGroup.getAction(), this, myMnemonicEnabled, myPresentationFactory, context, myPlace, true, mayContextBeInvalid);
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.editor.actions;
import com.intellij.execution.impl.ConsoleViewUtil;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
/**
* @author Denis Zhdanov
* @since 10/23/12 4:52 PM
*/
public class ResetFontSizeAction extends EditorAction {
public ResetFontSizeAction() {
super(new MyHandler());
}
private static class MyHandler extends EditorActionHandler {
@Override
public void execute(Editor editor, DataContext dataContext) {
if (!(editor instanceof EditorEx)) {
return;
}
EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
int fontSize = editor.getUserData(ConsoleViewUtil.EDITOR_IS_CONSOLE_VIEW) == Boolean.TRUE
? globalScheme.getConsoleFontSize() : globalScheme.getEditorFontSize();
EditorEx editorEx = (EditorEx)editor;
editorEx.setFontSize(fontSize);
}
}
}
@@ -88,6 +88,7 @@ action.EditorRightWithSelection.text=Right with Selection
action.EditorIndentSelection.text=Indent Selection
action.EditorUnindentSelection.text=Unindent Selection
action.EditorTab.text=Tab
action.EditorResetFontSize.text=Reset Font Size
action.EmacsStyleIndent.text=Emacs Tab
action.EditorScrollUp.text=Scroll Up
action.EditorScrollDown.text=Scroll Down
@@ -144,12 +144,6 @@ refactoring.introduce.name.used.error=This name is already used
refactoring.introduce.variable.scope.error=Name clashes with existing variable
refactoring.introduce.placing.error=Cannot extract {0} variable
refactoring.inlineVariable=Inline Variable refactoring
refactoring.inlineMethod=Inline Method refactoring
refactoring.introduceField=Extract Field refactoring
refactoring.refactoring.introduceParameter=Extract Parameter refactoring
refactoring.introduceConstant=Extract Constant refactoring
refactoring.extractMethod=Extract Method refactoring
variable.of.type=Variable of &type:
convert.to.instance.method.title=Convert To Instance Method
convertToInstanceMethod.method.is.not.static=Cannot perform the refactoring\nMethod {0} is not static.
@@ -59,6 +59,7 @@
<action id="EditorRightWithSelection" class="com.intellij.openapi.editor.actions.MoveCaretRightWithSelectionAction"/>
<action id="EditorUnindentSelection" class="com.intellij.openapi.editor.actions.UnindentSelectionAction"/>
<action id="EditorTab" class="com.intellij.openapi.editor.actions.TabAction"/>
<action id="EditorResetFontSize" class="com.intellij.openapi.editor.actions.ResetFontSizeAction"/>
<action id="EditorScrollUp" class="com.intellij.openapi.editor.actions.ScrollUpAction"/>
<action id="EditorScrollDown" class="com.intellij.openapi.editor.actions.ScrollDownAction"/>
<action id="EditorScrollUpAndMove" class="com.intellij.openapi.editor.actions.ScrollUpAndMoveAction"/>
@@ -378,18 +378,52 @@ public abstract class UsefulTestCase extends TestCase {
}
public static <T> void assertSameElements(Collection<? extends T> collection, Collection<T> expected) {
assertSameElements(null, collection, expected);
}
public static <T> void assertSameElements(String message, Collection<? extends T> collection, Collection<T> expected) {
assertNotNull(collection);
assertNotNull(expected);
if (collection.size() != expected.size() || !new HashSet<T>(expected).equals(new HashSet<T>(collection))) {
Assert.assertEquals(toString(expected, "\n"), toString(collection, "\n"));
Assert.assertEquals(new HashSet<T>(expected), new HashSet<T>(collection));
Assert.assertEquals(message, toString(expected, "\n"), toString(collection, "\n"));
Assert.assertEquals(message, new HashSet<T>(expected), new HashSet<T>(collection));
}
}
public <T> void assertContainsOrdered(Collection<? extends T> collection, T... expected) {
assertContainsOrdered(collection, Arrays.asList(expected));
}
public <T> void assertContainsOrdered(Collection<? extends T> collection, Collection<T> expected) {
ArrayList<T> copy = new ArrayList<T>(collection);
copy.retainAll(expected);
assertOrderedEquals(toString(collection), copy, expected);
}
public <T> void assertContainsElements(Collection<? extends T> collection, T... expected) {
assertContainsElements(collection, Arrays.asList(expected));
}
public <T> void assertContainsElements(Collection<? extends T> collection, Collection<T> expected) {
ArrayList<T> copy = new ArrayList<T>(collection);
copy.retainAll(expected);
assertSameElements(toString(collection), copy, expected);
}
public static String toString(Object[] collection, String separator) {
return toString(Arrays.asList(collection), separator);
}
public <T> void assertDoesntContain(Collection<? extends T> collection, T... notExpected) {
assertDoesntContain(collection, Arrays.asList(notExpected));
}
public <T> void assertDoesntContain(Collection<? extends T> collection, Collection<T> notExpected) {
ArrayList<T> copy = new ArrayList<T>(collection);
copy.retainAll(notExpected);
assertEmpty(copy);
}
public static String toString(Collection<?> collection, String separator) {
List<String> list = ContainerUtil.map2List(collection, new Function<Object, String>() {
@Override
@@ -752,6 +752,7 @@ thread.start.in.construction.display.name=Call to 'Thread.start()' during object
non.final.clone.display.name=Non-final 'clone()' in secure context
unnecessary.temporary.on.conversion.from.string.display.name=Unnecessary temporary object in conversion from String
unnecessary.this.display.name=Unnecessary 'this' qualifier
unnecessary.this.ignore.assignments.option=Ignore field assignments
runtime.exec.with.non.constant.string.display.name=Call to 'Runtime.exec()' with non-constant string
system.properties.display.name=Access of system properties
chained.method.call.display.name=Chained method calls
@@ -1389,7 +1390,7 @@ unnecessary.parentheses.remove.quickfix=Remove unnecessary parentheses
unnecessary.qualifier.for.this.remove.quickfix=Remove unnecessary qualifier
unnecessary.semicolon.remove.quickfix=Remove unnecessary semicolon
unnecessary.super.constructor.remove.quickfix=Remove unnecessary 'super()'
unnecessary.this.remove.quickfix=Remove unnecessary 'this.'
unnecessary.this.remove.quickfix=Remove unnecessary 'this' qualifier
overly.strong.type.cast.problem.descriptor=Cast to <code>#ref</code> can be weakened to ''{0}'' #loc
field.count.inspection.include.constant.fields.in.count.checkbox=Include constant fields in count
field.count.inspection.static.final.fields.count.as.constant.checkbox='static final' fields count as constant
@@ -1673,7 +1674,7 @@ ignore.iterator.loop.variables=Ignore java.util.Iterator loop variables
rename.catch.parameter.to.ignored=Rename 'catch' parameter to 'ignored'
unnecessary.super.qualifier.display.name=Unnecessary 'super' qualifier
unnecessary.super.qualifier.problem.descriptor=Qualifier <code>#ref</code> is unnecessary in this context #loc
unnecessary.super.qualifier.quickfix=Remove unnecessary 'super.'
unnecessary.super.qualifier.quickfix=Remove unnecessary 'super' qualifier
collections.field.access.replaceable.by.method.call.display.name=Collections.EMPTY_* field access replaceable with 'Collections.empty*()' method call
collections.field.access.replaceable.by.method.call.problem.descriptor=<code>#ref</code> replaceable with ''Collections.{0}'' #loc
collections.field.access.replaceable.by.method.call.quickfix=Replace with ''{0}''
@@ -1696,7 +1697,7 @@ unnecessary.constant.array.creation.expression.problem.descriptor=<code>#ref</co
unnecessary.constant.array.creation.expression.quickfix=Replace with array initializer expression
ambiguous.method.call.display.name=Inherited method called, while local method might have been expected
ambiguous.method.call.problem.descriptor=Method <code>#ref()</code> from super class ''{0}'' called, when method from class ''{1}'' might have been expected #loc
ambiguous.method.call.quickfix=Qualify method call with 'super.'
ambiguous.method.call.quickfix=Add 'super' qualifier to method call
change.modifier.quickfix=Make ''{0}''
the.whole.project=the whole project
this.class=this class
@@ -1974,7 +1975,7 @@ ambiguous.field.access.display.name=Inherited field accessed while local variabl
ambiguous.field.access.hides.local.variable.problem.descriptor=Field <code>#ref</code> from super class ''{0}'' accessed, while local variable access might be expected #loc
ambiguous.field.access.hides.parameter.problem.descriptor=Field <code>#ref</code> from super class ''{0}'' accessed, while parameter access might be expected #loc
ambiguous.field.access.hides.field.problem.descriptor=Field <code>#ref</code> from super class ''{0}'' accessed, while field access from surrounding class might be expected #loc
ambiguous.field.access.quickfix=Qualify field access with 'super.'
ambiguous.field.access.quickfix=Add 'super' qualifier to field access
string.builder.replaceable.by.string.quickfix=Replace 'StringBuilder' with 'String'
string.buffer.replaceable.by.string.quickfix=Replace 'StringBuffer' with 'String'
add.0.to.ignore.if.annotated.by.list.quickfix=Add ''{0}'' to ''Ignore if annotated by'' list
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,11 @@
package com.siyeh.ig.style;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
@@ -27,9 +29,15 @@ import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.VariableSearchUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class UnnecessaryThisInspection extends BaseInspection {
@SuppressWarnings("PublicField")
public boolean ignoreAssignments = false;
@Override
@NotNull
public String getDisplayName() {
@@ -39,8 +47,14 @@ public class UnnecessaryThisInspection extends BaseInspection {
@Override
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"unnecessary.this.problem.descriptor");
return InspectionGadgetsBundle.message("unnecessary.this.problem.descriptor");
}
@Nullable
@Override
public JComponent createOptionsPanel() {
return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("unnecessary.this.ignore.assignments.option"), this,
"ignoreAssignments");
}
@Override
@@ -52,8 +66,7 @@ public class UnnecessaryThisInspection extends BaseInspection {
@NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"unnecessary.this.remove.quickfix");
return InspectionGadgetsBundle.message("unnecessary.this.remove.quickfix");
}
public void doFix(Project project, ProblemDescriptor descriptor)
@@ -75,33 +88,31 @@ public class UnnecessaryThisInspection extends BaseInspection {
return new UnnecessaryThisVisitor();
}
private static class UnnecessaryThisVisitor extends BaseInspectionVisitor {
private class UnnecessaryThisVisitor extends BaseInspectionVisitor {
@Override
public void visitReferenceExpression(
@NotNull PsiReferenceExpression expression) {
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
final PsiReferenceParameterList parameterList =
expression.getParameterList();
final PsiReferenceParameterList parameterList = expression.getParameterList();
if (parameterList == null) {
return;
}
if (parameterList.getTypeArguments().length > 0) {
return;
}
final PsiExpression qualifierExpression =
expression.getQualifierExpression();
final PsiExpression qualifierExpression = expression.getQualifierExpression();
if (!(qualifierExpression instanceof PsiThisExpression)) {
return;
}
final PsiThisExpression thisExpression =
(PsiThisExpression)qualifierExpression;
final PsiJavaCodeReferenceElement qualifier =
thisExpression.getQualifier();
final PsiThisExpression thisExpression = (PsiThisExpression)qualifierExpression;
final PsiJavaCodeReferenceElement qualifier = thisExpression.getQualifier();
final String referenceName = expression.getReferenceName();
if (referenceName == null) {
return;
}
if (ignoreAssignments && PsiUtil.isAccessedForWriting(expression)) {
return;
}
final PsiElement parent = expression.getParent();
if (qualifier == null) {
if (parent instanceof PsiCallExpression) {
@@ -114,8 +125,7 @@ public class UnnecessaryThisInspection extends BaseInspection {
return;
}
final PsiVariable variable = (PsiVariable)target;
if (!VariableSearchUtils.variableNameResolvesToTarget(
referenceName, variable, expression)) {
if (!VariableSearchUtils.variableNameResolvesToTarget(referenceName, variable, expression)) {
return;
}
registerError(thisExpression);
@@ -126,43 +136,31 @@ public class UnnecessaryThisInspection extends BaseInspection {
return;
}
if (parent instanceof PsiCallExpression) {
final PsiCallExpression callExpression =
(PsiCallExpression)parent;
final PsiMethod calledMethod =
callExpression.resolveMethod();
final PsiCallExpression callExpression = (PsiCallExpression)parent;
final PsiMethod calledMethod = callExpression.resolveMethod();
if (calledMethod == null) {
return;
}
final String methodName = calledMethod.getName();
PsiClass parentClass =
ClassUtils.getContainingClass(expression);
PsiClass parentClass = ClassUtils.getContainingClass(expression);
final Project project = expression.getProject();
final JavaPsiFacade psiFacade =
JavaPsiFacade.getInstance(project);
final PsiResolveHelper resolveHelper =
psiFacade.getResolveHelper();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiResolveHelper resolveHelper = psiFacade.getResolveHelper();
while (parentClass != null) {
if (qualifierName.equals(parentClass.getName())) {
registerError(thisExpression);
}
final PsiMethod[] methods =
parentClass.findMethodsByName(methodName, true);
final PsiMethod[] methods = parentClass.findMethodsByName(methodName, true);
for (PsiMethod method : methods) {
final PsiClass containingClass =
method.getContainingClass();
if (resolveHelper.isAccessible(method,
expression, containingClass)) {
if (method.hasModifierProperty(
PsiModifier.PRIVATE) &&
!PsiTreeUtil.isAncestor(containingClass,
expression, true)) {
final PsiClass containingClass = method.getContainingClass();
if (resolveHelper.isAccessible(method, expression, containingClass)) {
if (method.hasModifierProperty(PsiModifier.PRIVATE) && !PsiTreeUtil.isAncestor(containingClass, expression, true)) {
continue;
}
return;
}
}
parentClass =
ClassUtils.getContainingClass(parentClass);
parentClass = ClassUtils.getContainingClass(parentClass);
}
}
else {
@@ -171,23 +169,19 @@ public class UnnecessaryThisInspection extends BaseInspection {
return;
}
final PsiVariable variable = (PsiVariable)target;
if (!VariableSearchUtils.variableNameResolvesToTarget(
referenceName, variable, expression)) {
if (!VariableSearchUtils.variableNameResolvesToTarget(referenceName, variable, expression)) {
return;
}
PsiClass parentClass =
ClassUtils.getContainingClass(expression);
PsiClass parentClass = ClassUtils.getContainingClass(expression);
while (parentClass != null) {
if (qualifierName.equals(parentClass.getName())) {
registerError(thisExpression);
}
final PsiField field =
parentClass.findFieldByName(referenceName, true);
final PsiField field = parentClass.findFieldByName(referenceName, true);
if (field != null) {
return;
}
parentClass =
ClassUtils.getContainingClass(parentClass);
parentClass = ClassUtils.getContainingClass(parentClass);
}
}
}
@@ -1,11 +1,11 @@
<html>
<body>
Reports on any unnecessary qualification of <b>this</b> in the code.
Reports on any unnecessary qualification of <b>this</b>.
Using a qualifier on <b>this</b> to
disambiguate a code reference may easily become unnecessary via automatic refactorings, and should be deleted for clarity.
<p>
Sample:
<code>OuterClass.this.foo();</code>
For example:
<pre><code>OuterClass.<b>this</b>.foo();</code></pre>
<!-- tooltip end -->
<p>
<small>Powered by InspectionGadgets</small>
@@ -5,10 +5,12 @@ Using <b>this</b> to
disambiguate a code reference may easily become unnecessary via automatic refactorings, and is discouraged
by many coding styles.
<p>
Sample:
<code>this.a=3;</code>
For example:
<pre><code><b>this</b>.a = 3;</code></pre>
<!-- tooltip end -->
<p>
Use the checkbox below to ignore assignments to fields.
<p>
<small>Powered by InspectionGadgets</small>
</body>
</html>
@@ -334,4 +334,6 @@ top.level.class.maynot.have.protected.modifier=Top level class may not have 'pro
property.missing=propertyMissing
attribute.name.expected=Attribute name expected
java.style.for.each.statement.requires.a.type.declaration=Java-style for-each statement requires a type declaration
enums.may.not.have.extends.clause=Enums may not have 'extends' clause
enums.may.not.have.extends.clause=Enums may not have 'extends' clause
super.cannot.be.used.in.static.context='super' cannot be used in static context
qualified.0.is.allowed.only.in.nested.or.inner.classes=Qualified {0} is allowed only in nested/inner classes
@@ -36,6 +36,11 @@ public class ConvertToJavaAction extends BaseRefactoringAction {
return isEnabledOnElements(new PsiElement[]{element});
}
@Override
protected boolean isEnabledOnDataContext(DataContext dataContext) {
return super.isEnabledOnDataContext(dataContext);
}
@Override
protected boolean isAvailableInEditorOnly() {
return false;
@@ -36,6 +36,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
@@ -101,7 +102,10 @@ public class GrKeywordAndDeclarationHighlighter extends TextEditorHighlightingPa
return false; //It is allowed to name packages 'as', 'in' or 'def'
}
}
else if (token == GroovyTokenTypes.kDEF && element.getParent() instanceof GrAnnotationNameValuePair) return false;
else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) {
if (token == GroovyTokenTypes.kSUPER && ((GrReferenceExpression)parent).getQualifier() == null) return true;
if (token == GroovyTokenTypes.kTHIS && ((GrReferenceExpression)parent).getQualifier() == null) return true;
return false; //don't highlight foo.def
}
@@ -288,6 +288,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
@Override
public void visitReferenceExpression(final GrReferenceExpression referenceExpression) {
checkStringNameIdentifier(referenceExpression);
checkThisOrSuperReferenceExpression(referenceExpression, myHolder);
}
private void checkStringNameIdentifier(GrReferenceExpression ref) {
@@ -955,7 +956,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
final PsiClass clazz = invocation.getDelegatedClass();
if (clazz != null) {
//default constructor invocation
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getThisOrSuperKeyword(), true);
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getInvokedExpression(), true);
if (argumentTypes != null && argumentTypes.length > 0) {
String message = GroovyBundle.message("cannot.apply.default.constructor", clazz.getName());
myHolder.createWarningAnnotation(argList, message);
@@ -1030,16 +1031,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
checkThisOrSuperReferenceExpression(superExpression, myHolder);
}
@Override
public void visitThisExpression(GrThisReferenceExpression thisExpression) {
checkThisOrSuperReferenceExpression(thisExpression, myHolder);
}
@Override
public void visitLiteralExpression(GrLiteral literal) {
final IElementType elementType = literal.getFirstChild().getNode().getElementType();
@@ -1409,40 +1400,43 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
return PsiTreeUtil.getParentOfType(statement, GrLoopStatement.class, true, GrClosableBlock.class, GrMember.class, GroovyFile.class);
}
private static void checkThisOrSuperReferenceExpression(GrExpression expression, AnnotationHolder holder) {
if (GroovyConfigUtils.getInstance().isVersionAtLeast(expression, GroovyConfigUtils.GROOVY1_8)) return;
private static void checkThisOrSuperReferenceExpression(GrReferenceExpression ref, AnnotationHolder holder) {
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement == null) return;
final GrReferenceExpression qualifier = expression instanceof GrThisReferenceExpression
? ((GrThisReferenceExpression)expression).getQualifier()
: ((GrSuperReferenceExpression)expression).getQualifier();
if (qualifier == null) {
if (expression instanceof GrSuperReferenceExpression) { //'this' refers to java.lang.Class<ThisClass> in static context
final GrMethod method = PsiTreeUtil.getParentOfType(expression, GrMethod.class);
if (method != null && method.hasModifierProperty(STATIC)) {
Annotation annotation =
holder.createInfoAnnotation(expression, GroovyBundle.message("cannot.reference.nonstatic", expression.getText()));
annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS);
}
}
}
else {
final PsiElement resolved = qualifier.resolve();
IElementType elementType = nameElement.getNode().getElementType();
if (!(elementType == GroovyTokenTypes.kSUPER || elementType == GroovyTokenTypes.kTHIS)) return;
final GrExpression qualifier = ref.getQualifier();
if (qualifier instanceof GrReferenceExpression) {
final PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass) {
if (PsiTreeUtil.isAncestor(resolved, expression, true)) {
if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, expression, true)) {
Annotation annotation =
holder.createInfoAnnotation(expression, GroovyBundle.message("cannot.reference.nonstatic", expression.getText()));
annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS);
GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true, GroovyFile.class);
if (containingClass == null || containingClass.getContainingClass() == null && !containingClass.isAnonymous()) {
holder.createErrorAnnotation(ref, GroovyBundle.message("qualified.0.is.allowed.only.in.nested.or.inner.classes",
nameElement.getText()));
return;
}
if (PsiTreeUtil.isAncestor(resolved, ref, true)) {
if (PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, true)) {
holder.createInfoAnnotation(nameElement, null).setTextAttributes(DefaultHighlighter.KEYWORD);
}
}
else {
String qname = ((PsiClass)resolved).getQualifiedName();
assert qname != null;
holder.createErrorAnnotation(expression, GroovyBundle.message("is.not.enclosing.class", qname));
holder.createErrorAnnotation(ref, GroovyBundle.message("is.not.enclosing.class", qname));
}
}
else {
holder.createErrorAnnotation(qualifier, GroovyBundle.message("unknown.class", qualifier.getText()));
}
else if (qualifier == null) {
if (elementType == GroovyTokenTypes.kSUPER) {
final GrMember container = PsiTreeUtil.getParentOfType(ref, GrMethod.class, GrClassInitializer.class);
if (container != null && container.hasModifierProperty(STATIC)) {
holder.createErrorAnnotation(ref, GroovyBundle.message("super.cannot.be.used.in.static.context"));
}
}
}
}
@@ -58,6 +58,7 @@ public class GrReassignedLocalVarsChecker {
return null;
}
assert resolved != null;
return getLeastUpperBoundByVar((GrVariable)resolved);
}
@@ -548,7 +548,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitConstructorInvocation(GrConstructorInvocation invocation) {
super.visitConstructorInvocation(invocation);
checkConstructorCall(invocation, invocation.getThisOrSuperKeyword());
checkConstructorCall(invocation, invocation.getInvokedExpression());
}
@Override
@@ -209,7 +209,9 @@ public class GroovyAccessibilityInspection extends BaseInspection {
@Override
public void visitReferenceExpression(GrReferenceExpression ref) {
super.visitReferenceExpression(ref);
checkRef(ref);
if (!(ref.getParent() instanceof GrConstructorInvocation)) { //constructor invocation is checked in separate place
checkRef(ref);
}
}
@Override
@@ -229,7 +231,7 @@ public class GroovyAccessibilityInspection extends BaseInspection {
refElement = ((GrNewExpression)call).getReferenceElement();
}
else if (call instanceof GrConstructorInvocation) {
refElement = ((GrConstructorInvocation)call).getThisOrSuperKeyword();
refElement = ((GrConstructorInvocation)call).getInvokedExpression();
}
if (refElement == null) {
refElement = call;
@@ -19,6 +19,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.BoolUtils;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition;
@@ -36,6 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrC
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@SuppressWarnings({"OverlyComplexClass"})
class RecursionUtils {
@@ -45,7 +47,7 @@ class RecursionUtils {
}
public static boolean statementMayReturnBeforeRecursing(
GrStatement statement, GrMethod method) {
@Nullable GrStatement statement, GrMethod method) {
if (statement == null) {
return true;
}
@@ -183,7 +185,7 @@ class RecursionUtils {
}
private static boolean codeBlockMayReturnBeforeRecursing(
GrCodeBlock block, GrMethod method, boolean endsInImplicitReturn) {
@Nullable GrCodeBlock block, GrMethod method, boolean endsInImplicitReturn) {
if (block == null) {
return true;
}
@@ -205,14 +207,12 @@ class RecursionUtils {
return recursionVisitor.isRecursive();
}
private static boolean expressionDefinitelyRecurses(GrExpression exp,
private static boolean expressionDefinitelyRecurses(@Nullable GrExpression exp,
GrMethod method) {
if (exp == null) {
return false;
}
if (exp instanceof GrLiteral ||
exp instanceof GrThisReferenceExpression ||
exp instanceof GrSuperReferenceExpression) {
if (exp instanceof GrLiteral) {
return false;
}
if (exp instanceof GrMethodCallExpression) {
@@ -399,7 +399,7 @@ class RecursionUtils {
method.hasModifierProperty(PsiModifier.PRIVATE)) {
return true;
}
if (qualifier == null || qualifier instanceof GrThisReferenceExpression) {
if (qualifier == null || qualifier instanceof GrReferenceExpression && PsiUtil.isThisReference(qualifier)) {
return true;
}
}
@@ -410,7 +410,7 @@ class RecursionUtils {
return callExpressionDefinitelyRecurses(exp, method);
}
private static boolean statementDefinitelyRecurses(GrStatement statement,
private static boolean statementDefinitelyRecurses(@Nullable GrStatement statement,
GrMethod method) {
if (statement == null) {
return false;
@@ -137,7 +137,7 @@ public class GroovyPointlessBooleanInspection extends BaseInspection {
return lhs.getText() + negatedComparison + rhs.getText();
} else {
final String baseText = exp.getText();
if (ParenthesesUtils.getPrecendence(exp) >
if (ParenthesesUtils.getPrecedence(exp) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + baseText + ')';
} else {
@@ -35,12 +35,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import javax.swing.*;
@@ -172,8 +172,14 @@ public class GrMethodMayBeStaticInspection extends BaseInspection {
@Override
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
if (referenceExpression.getParent() instanceof GrReferenceExpression) return;
registerInstanceRefs();
return;
}
GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null || qualifier instanceof GrThisSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
GroovyResolveResult result = referenceExpression.advancedResolve();
PsiElement element = result.getElement();
if (isPrintOrPrintln(element)) return; //print & println are resolved in all places
@@ -190,13 +196,6 @@ public class GrMethodMayBeStaticInspection extends BaseInspection {
}
}
@Override
public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expression) {
if (expression.getParent() instanceof GrReferenceExpression) return;
registerInstanceRefs();
}
private void registerInstanceRefs() {
if (myIsInClosure > 0) {
myHaveNoInstanceRefsInClosure = false;
@@ -21,18 +21,17 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspection {
@@ -98,7 +97,7 @@ public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspectio
if (!(methodExpression instanceof GrReferenceExpression)) {
return;
}
final GrReferenceExpression referenceExpression = (GrReferenceExpression) methodExpression;
final GrReferenceExpression referenceExpression = (GrReferenceExpression)methodExpression;
final String name = referenceExpression.getReferenceName();
if (name == null || !name.startsWith(GET_PREFIX)) {
return;
@@ -112,11 +111,8 @@ public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspectio
return;
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
return;
}
if (qualifier == null) return;
if (PsiUtil.isThisOrSuperRef(qualifier)) return;
registerMethodCallError(grMethodCallExpression);
}
}
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection {
@@ -106,9 +105,7 @@ public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection {
@@ -107,9 +106,7 @@ public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection {
@@ -106,9 +105,7 @@ public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
@@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection {
private final ReplaceWithPropertyAccessFix fix = new ReplaceWithPropertyAccessFix();
@@ -108,9 +107,7 @@ public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection {
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
@@ -21,18 +21,17 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovySetterCallCanBePropertyAccessInspection extends BaseInspection {
private final ReplaceWithPropertyAccessFix fix = new ReplaceWithPropertyAccessFix();
@@ -116,9 +115,7 @@ public class GroovySetterCallCanBePropertyAccessInspection extends BaseInspectio
return;
}
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null ||
qualifier instanceof GrThisReferenceExpression ||
qualifier instanceof GrSuperReferenceExpression) {
if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
return;
}
registerMethodCallError(grMethodCallExpression);
@@ -27,8 +27,8 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSynchronizedStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovyAccessToStaticFieldLockedOnInstanceInspection
extends BaseInspection {
@@ -79,29 +79,26 @@ public class GroovyAccessToStaticFieldLockedOnInstanceInspection
}
PsiElement elementToCheck = expression;
while (true) {
final GrSynchronizedStatement syncStatement =
PsiTreeUtil.getParentOfType(elementToCheck,
GrSynchronizedStatement.class);
final GrSynchronizedStatement syncStatement = PsiTreeUtil.getParentOfType(elementToCheck, GrSynchronizedStatement.class);
if (syncStatement == null) {
break;
}
final GrExpression lockExpression =
syncStatement.getMonitor();
if (lockExpression instanceof GrReferenceExpression) {
final GrReferenceExpression reference =
(GrReferenceExpression) lockExpression;
final GrExpression lockExpression = syncStatement.getMonitor();
if (lockExpression instanceof GrReferenceExpression && PsiUtil.isThisReference(lockExpression)) {
isLockedOnInstance = true;
}
else if (lockExpression instanceof GrReferenceExpression) {
final GrReferenceExpression reference = (GrReferenceExpression) lockExpression;
final PsiElement referent = reference.resolve();
if (referent instanceof PsiField) {
final PsiField referentField = (PsiField) referent;
if (referentField.hasModifierProperty(
PsiModifier.STATIC)) {
if (referentField.hasModifierProperty(PsiModifier.STATIC)) {
isLockedOnClass = true;
} else {
isLockedOnInstance = true;
}
}
} else if (lockExpression instanceof GrThisReferenceExpression) {
isLockedOnInstance = true;
}
elementToCheck = syncStatement;
}
@@ -22,7 +22,8 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSynchronizedStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public class GroovySynchronizationOnThisInspection extends BaseInspection {
@@ -52,7 +53,7 @@ public class GroovySynchronizationOnThisInspection extends BaseInspection {
public void visitSynchronizedStatement(GrSynchronizedStatement synchronizedStatement) {
super.visitSynchronizedStatement(synchronizedStatement);
final GrExpression lock = synchronizedStatement.getMonitor();
if (lock == null || !(lock instanceof GrThisReferenceExpression)) {
if (lock == null || !(lock instanceof GrReferenceExpression && PsiUtil.isThisReference(lock))) {
return;
}
registerError(lock);
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.codeInspection.utils;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.intentions.utils.ComparisonUtils;
import org.jetbrains.plugins.groovy.intentions.utils.ParenthesesUtils;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
@@ -38,7 +39,7 @@ public class BoolUtils {
return GroovyTokenTypes.mBNOT.equals(sign);
}
public static boolean isTrue(GrCondition condition) {
public static boolean isTrue(@Nullable GrCondition condition) {
if (condition == null) {
return false;
}
@@ -68,7 +69,7 @@ public class BoolUtils {
final GrExpression rhs = binaryExpression.getRightOperand();
assert rhs != null;
return lhs.getText() + negatedComparison + rhs.getText();
} else if (ParenthesesUtils.getPrecendence(condition) >
} else if (ParenthesesUtils.getPrecedence(condition) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + condition.getText() + ')';
} else {
@@ -54,10 +54,8 @@ public class EquivalenceChecker {
super();
}
private static final int THIS_EXPRESSION = 0;
private static final int LITERAL_EXPRESSION = 1;
private static final int REFERENCE_EXPRESSION = 3;
private static final int SUPER_EXPRESSION = 4;
private static final int CALL_EXPRESSION = 5;
private static final int NEW_EXPRESSION = 6;
private static final int ARRAY_LITERAL_EXPRESSION = 7;
@@ -355,7 +353,9 @@ public class EquivalenceChecker {
return openBlocksAreEquivalent(block1, block2);
}
private static boolean openBlocksAreEquivalent(GrOpenBlock block1, GrOpenBlock block2) {
private static boolean openBlocksAreEquivalent(@Nullable GrOpenBlock block1, @Nullable GrOpenBlock block2) {
if (block1 == null || block2 == null) return false;
final GrStatement[] statements1 = block1.getStatements();
final GrStatement[] statements2 = block2.getStatements();
if (statements1.length != statements2.length) {
@@ -418,9 +418,6 @@ public class EquivalenceChecker {
return false;
}
switch (type1) {
case THIS_EXPRESSION:
case SUPER_EXPRESSION:
return true;
case LITERAL_EXPRESSION:
case REFERENCE_EXPRESSION:
final String text1 = expToCompare1.getText();
@@ -460,8 +457,8 @@ public class EquivalenceChecker {
return typecastExpressionsAreEquivalent((GrTypeCastExpression) expToCompare1,
(GrTypeCastExpression) expToCompare2);
case SAFE_CAST_EXPRESSION:
return safecastExpressionsAreEquivalent((GrSafeCastExpression) expToCompare1,
(GrSafeCastExpression) expToCompare2);
return safeCastExpressionsAreEquivalent((GrSafeCastExpression)expToCompare1,
(GrSafeCastExpression)expToCompare2);
case INSTANCEOF_EXPRESSION:
return instanceofExpressionsAreEquivalent((GrInstanceOfExpression) expToCompare1,
(GrInstanceOfExpression) expToCompare2);
@@ -538,8 +535,12 @@ public class EquivalenceChecker {
if (!expressionsAreEquivalent(operand1, operand2)) {
return false;
}
final PsiType type1 = expression1.getTypeElement().getType();
final PsiType type2 = expression2.getTypeElement().getType();
GrTypeElement typeElement1 = expression1.getTypeElement();
GrTypeElement typeElement2 = expression2.getTypeElement();
if (typeElement1 == null || typeElement2 == null) return false;
final PsiType type1 = typeElement1.getType();
final PsiType type2 = typeElement2.getType();
return typesAreEquivalent(type1, type2);
}
@@ -561,7 +562,7 @@ public class EquivalenceChecker {
return typesAreEquivalent(type1, type2);
}
private static boolean safecastExpressionsAreEquivalent(GrSafeCastExpression expression1,
private static boolean safeCastExpressionsAreEquivalent(GrSafeCastExpression expression1,
GrSafeCastExpression expression2) {
final GrExpression operand1 = expression1.getOperand();
final GrExpression operand2 = expression2.getOperand();
@@ -591,7 +592,7 @@ public class EquivalenceChecker {
return argumentListsAreEquivalent(methodExp1.getArgumentList(), methodExp2.getArgumentList());
}
private static boolean argumentListsAreEquivalent(GrArgumentList list1, GrArgumentList list2) {
private static boolean argumentListsAreEquivalent(@Nullable GrArgumentList list1, @Nullable GrArgumentList list2) {
if (list1 == null && list2 == null) {
return true;
}
@@ -773,12 +774,6 @@ public class EquivalenceChecker {
}
private static int getExpressionType(@Nullable GrExpression exp) {
if (exp instanceof GrThisReferenceExpression) {
return THIS_EXPRESSION;
}
if (exp instanceof GrSuperReferenceExpression) {
return SUPER_EXPRESSION;
}
if (exp instanceof GrArrayDeclaration) {
return ARRAY_LITERAL_EXPRESSION;
}
@@ -830,7 +825,7 @@ public class EquivalenceChecker {
if (exp instanceof GrClosableBlock) {
return CLOSABLE_BLOCK_EXPRESSION;
}
return -1; // Type of expression can be defined in thirdparty plugins. See issue #IDEA-59846
return -1; // Type of expression can be defined in third party plugins. See issue #IDEA-59846
}
private static int getStatementType(@Nullable GrStatement statement) {
@@ -880,6 +875,6 @@ public class EquivalenceChecker {
return ASSERT_STATEMENT;
}
return -1; // Type of expression can be defined in thirdparty plugins. See issue #IDEA-59846
return -1; // Type of expression can be defined in third party plugins. See issue #IDEA-59846
}
}
@@ -41,8 +41,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
@@ -124,7 +122,10 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
//javaText.append("System.out.println(java.util.Arrays.toString(new Exception().getStackTrace()));\n");
//javaText.append("System.out.println(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(" + s + ":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), |.+com\\\\.springsource\\\\.loaded\\\\.).+\")\n");
javaText.append("if (java.util.Arrays.toString(new Exception().getStackTrace()).matches(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(" + s + ":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), $OR$.+com\\\\.springsource\\\\.loaded\\\\.).+\")) {\n");
javaText.append(
"if (java.util.Arrays.toString(new Exception().getStackTrace()).matches(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(")
.append(s)
.append(":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), $OR$.+com\\\\.springsource\\\\.loaded\\\\.).+\")) {\n");
javaText.append(" |thiz0 = thiz;\n");
javaText.append(" } else {\n");
javaText.append(" |thiz0 = this;\n");
@@ -144,9 +145,8 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
javaText.append("final java.lang.ClassLoader |parentLoader = |clazz.getClassLoader();\n" +
" final groovy.lang.GroovyClassLoader |loader = new groovy.lang.GroovyClassLoader(|parentLoader);\n" +
" final java.lang.Class |c = |loader.parseClass(");
javaText.append("\"" + IMPORTS + "class DUMMY" + new Random().nextInt(239) + " { " +
"public groovy.lang.Closure " +
EVAL_NAME + " = {" + TEXT + "}}\"");
javaText.append("\"" + IMPORTS + "class DUMMY").append(new Random().nextInt(239)).append(" { ").append("public groovy.lang.Closure ")
.append(EVAL_NAME).append(" = {").append(TEXT).append("}}\"");
javaText.append(", \"DUMMY.groovy\");\n" +
" int |i;\n" +
" java.lang.reflect.Field[] |fields = |c.getFields();\n" +
@@ -197,6 +197,16 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
super.visitReferenceExpression(referenceExpression);
PsiElement resolved = referenceExpression.resolve();
if (PsiUtil.isThisReference(referenceExpression)) {
replaceWithReference(referenceExpression, closure == null ? "delegate" : "owner");
return;
}
if (PsiUtil.isSuperReference(referenceExpression)) {
replaceWithReference(referenceExpression, closure == null ? "delegate" : "owner");
return;
}
if (resolved instanceof PsiMethod && "getDelegate".equals(((PsiMethod) resolved).getName()) && closure != null) {
replaceWithReference(referenceExpression, "owner");
return;
@@ -235,18 +245,6 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
}
@Override
public void visitThisExpression(final GrThisReferenceExpression thisExpression) {
super.visitThisExpression(thisExpression);
replaceWithReference(thisExpression, closure == null ? "delegate" : "owner");
}
@Override
public void visitSuperExpression(final GrSuperReferenceExpression superExpression) {
super.visitSuperExpression(superExpression);
replaceWithReference(superExpression, closure == null ? "delegate" : "owner");
}
private void replaceWithReference(GrExpression expr, final String exprText) {
replacements.put(expr, exprText);
}
@@ -29,7 +29,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
/**
@@ -77,9 +76,6 @@ public class GroovyEditorTextProvider implements EditorTextProvider {
}
}
if (parent instanceof GrThisReferenceExpression) {
return parent;
}
return null;
}
@@ -381,7 +381,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
final GrConstructorInvocation invocation = (GrConstructorInvocation)statements[0];
if (invocation.isThisCall() == processThisRefs &&
invocation.getManager().areElementsEquivalent(invocation.resolveMethod(), searchedConstructor) &&
!consumer.process(invocation.getThisOrSuperKeyword())) {
!consumer.process(invocation.getInvokedExpression())) {
return false;
}
}
@@ -97,7 +97,7 @@ public class DemorgansLawIntention extends MutablyNamedIntention {
private static String convertLeafExpression(GrExpression condition) {
if (BoolUtils.isNegation(condition)) {
final GrExpression negated = BoolUtils.getNegated(condition);
if (ParenthesesUtils.getPrecendence(negated) >
if (ParenthesesUtils.getPrecedence(negated) >
ParenthesesUtils.OR_PRECEDENCE) {
return '(' + negated.getText() + ')';
}
@@ -112,7 +112,7 @@ public class DemorgansLawIntention extends MutablyNamedIntention {
final GrExpression rhs = binaryExpression.getRightOperand();
assert rhs != null;
return lhs.getText() + negatedComparison + rhs.getText();
} else if (ParenthesesUtils.getPrecendence(condition) >
} else if (ParenthesesUtils.getPrecedence(condition) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + condition.getText() + ')';
} else {
@@ -48,7 +48,7 @@ public class MergeIfAndIntention extends Intention {
final GrExpression childCondition = childStatement.getCondition();
final String childConditionText;
if (ParenthesesUtils.getPrecendence(childCondition)
if (ParenthesesUtils.getPrecedence(childCondition)
> ParenthesesUtils.AND_PRECEDENCE) {
childConditionText = '(' + childCondition.getText() + ')';
} else {
@@ -57,7 +57,7 @@ public class MergeIfAndIntention extends Intention {
final GrExpression parentCondition = parentStatement.getCondition();
final String parentConditionText;
if (ParenthesesUtils.getPrecendence(parentCondition)
if (ParenthesesUtils.getPrecedence(parentCondition)
> ParenthesesUtils.AND_PRECEDENCE) {
parentConditionText = '(' + parentCondition.getText() + ')';
} else {
@@ -93,7 +93,7 @@ public class SimplifyTernaryOperatorIntention extends Intention {
@NotNull
private static String getStringToPutIntoAndExpression(GrExpression expression) {
String expressionText = expression.getText();
if (ParenthesesUtils.AND_PRECEDENCE < ParenthesesUtils.getPrecendence(expression)) {
if (ParenthesesUtils.AND_PRECEDENCE < ParenthesesUtils.getPrecedence(expression)) {
expressionText = "(" + expressionText + ")";
}
return expressionText;
@@ -102,7 +102,7 @@ public class SimplifyTernaryOperatorIntention extends Intention {
@NotNull
private static String getStringToPutIntoOrExpression(GrExpression expression) {
String expressionText = expression.getText();
if (ParenthesesUtils.OR_PRECEDENCE < ParenthesesUtils.getPrecendence(expression)) {
if (ParenthesesUtils.OR_PRECEDENCE < ParenthesesUtils.getPrecedence(expression)) {
expressionText = "(" + expressionText + ")";
}
return expressionText;
@@ -33,10 +33,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnState
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.ArrayList;
@@ -112,7 +112,7 @@ public class ConvertGStringToStringIntention extends Intention {
}
private static String prepareExpression(GrExpression expr) {
if (expr instanceof GrThisSuperReferenceExpression) return expr.getText();
if (PsiUtil.isThisOrSuperRef(expr)) return expr.getText();
String text = expr.getText();
final PsiType type = expr.getType();
@@ -19,8 +19,10 @@ import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@@ -100,7 +102,7 @@ public class BoolUtils {
final GrExpression rhs = binaryExpression.getRightOperand();
assert rhs != null;
return lhs.getText() + negatedComparison + rhs.getText();
} else if (ParenthesesUtils.getPrecendence(condition) >
} else if (ParenthesesUtils.getPrecedence(condition) >
ParenthesesUtils.PREFIX_PRECEDENCE) {
return "!(" + condition.getText() + ')';
} else {
@@ -82,18 +82,16 @@ public class ParenthesesUtils {
s_binaryOperatorPrecedence.put(GroovyTokenTypes.mCOMPARE_TO, EQUALITY_PRECEDENCE);
}
public static int getPrecendence(GrExpression expression) {
if (expression instanceof GrThisReferenceExpression ||
expression instanceof GrLiteral ||
expression instanceof GrSuperReferenceExpression ) {
public static int getPrecedence(GrExpression expression) {
if (expression instanceof GrLiteral) {
return LITERAL_PRECEDENCE;
}
if (expression instanceof GrReferenceExpression) {
final GrReferenceExpression referenceExpression =
(GrReferenceExpression) expression;
final GrReferenceExpression referenceExpression = (GrReferenceExpression)expression;
if (referenceExpression.getQualifierExpression() != null) {
return METHOD_CALL_PRECEDENCE;
} else {
}
else {
return LITERAL_PRECEDENCE;
}
}
@@ -105,11 +103,10 @@ public class ParenthesesUtils {
return TYPE_CAST_PRECEDENCE;
}
if (expression instanceof GrUnaryExpression) {
return ((GrUnaryExpression)expression).isPostfix()?POSTFIX_PRECEDENCE:PREFIX_PRECEDENCE;
return ((GrUnaryExpression)expression).isPostfix() ? POSTFIX_PRECEDENCE : PREFIX_PRECEDENCE;
}
if (expression instanceof GrBinaryExpression) {
final GrBinaryExpression binaryExpression =
(GrBinaryExpression) expression;
final GrBinaryExpression binaryExpression = (GrBinaryExpression) expression;
final IElementType sign = binaryExpression.getOperationTokenType();
return precedenceForBinaryOperator(sign);
}
@@ -28,11 +28,14 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrReferenceElementImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
* @author Max Medvedev
@@ -63,7 +66,7 @@ public class GrReferenceAdjuster {
if (element instanceof GrQualifiedReference<?> && ((GrQualifiedReference)element).resolve() instanceof PsiClass) {
result = shortenReferenceInner((GrQualifiedReference<?>)element, addImports, incomplete);
}
else if (element instanceof GrReferenceExpression && ((GrReferenceExpression)element).getQualifier() instanceof GrThisSuperReferenceExpression) {
else if (element instanceof GrReferenceExpression && PsiUtil.isSuperReference(((GrReferenceExpression)element).getQualifier())) {
result = shortenReferenceInner((GrReferenceExpression)element, addImports, incomplete);
}
@@ -81,7 +84,7 @@ public class GrReferenceAdjuster {
private static <Qualifier extends PsiElement> boolean shortenReferenceInner(GrQualifiedReference<Qualifier> ref, boolean addImports, boolean incomplete) {
final Qualifier qualifier = ref.getQualifier();
if (qualifier == null || qualifier instanceof GrSuperReferenceExpression || cannotShortenInContext(ref)) {
if (qualifier == null || PsiUtil.isSuperReference(qualifier) || cannotShortenInContext(ref)) {
return false;
}
@@ -173,7 +176,7 @@ public class GrReferenceAdjuster {
}
if (qualifier instanceof GrExpression) {
if (qualifier instanceof GrThisReferenceExpression) return true;
if (qualifier instanceof GrReferenceExpression && PsiUtil.isThisReference(qualifier)) return true;
if (qualifier instanceof GrReferenceExpression && seemsToBeQualifiedClassName((GrExpression)qualifier)) {
final PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass || resolved instanceof PsiPackage) return true;
@@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.Map;
@@ -67,16 +68,20 @@ public class GroovyChangeUtilSupport implements TreeCopyHandler {
public void encodeInformation(final TreeElement element, final ASTNode original, final Map<Object, Object> encodingState) {
if (original instanceof CompositeElement) {
if (original.getElementType() == GroovyElementTypes.REFERENCE_ELEMENT || original.getElementType() == GroovyElementTypes.REFERENCE_EXPRESSION) {
final GroovyResolveResult result = ((GrReferenceElement)original.getPsi()).advancedResolve();
if (result != null) {
final PsiElement target = result.getElement();
if (original.getElementType() == GroovyElementTypes.REFERENCE_ELEMENT ||
original.getElementType() == GroovyElementTypes.REFERENCE_EXPRESSION) {
PsiElement psi = original.getPsi();
if (!PsiUtil.isThisOrSuperRef(psi)) {
final GroovyResolveResult result = ((GrReferenceElement)psi).advancedResolve();
if (result != null) {
final PsiElement target = result.getElement();
if (target instanceof PsiClass ||
(target instanceof PsiMethod || target instanceof PsiField) &&
((PsiMember) target).hasModifierProperty(PsiModifier.STATIC) &&
result.getCurrentFileResolveContext() instanceof GrImportStatement) {
element.putCopyableUserData(REFERENCED_MEMBER_KEY, (PsiMember) target);
if (target instanceof PsiClass ||
(target instanceof PsiMethod || target instanceof PsiField) &&
((PsiMember)target).hasModifierProperty(PsiModifier.STATIC) &&
result.getCurrentFileResolveContext() instanceof GrImportStatement) {
element.putCopyableUserData(REFERENCED_MEMBER_KEY, (PsiMember)target);
}
}
}
}
@@ -235,8 +235,6 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy
GroovyElementType SPREAD_ARGUMENT = new GroovyElementType("Spread argument");
GroovyElementType ARGUMENT_LABEL = new GroovyElementType("Argument label");
GroovyElementType REFERENCE_EXPRESSION = new GroovyElementType("Reference expressions");
GroovyElementType THIS_REFERENCE_EXPRESSION = new GroovyElementType("This reference expressions");
GroovyElementType SUPER_REFERENCE_EXPRESSION = new GroovyElementType("Super reference expressions");
GroovyElementType NEW_EXPRESSION = new GroovyElementType("New expressions");
@@ -232,8 +232,6 @@ public class GroovyPsiCreator implements GroovyElementTypes {
if (elem == REGEX) return new GrRegexImpl(node);
if (elem == GSTRING_INJECTION) return new GrStringInjectionImpl(node);
if (elem == REFERENCE_EXPRESSION) return new GrReferenceExpressionImpl(node);
if (elem == THIS_REFERENCE_EXPRESSION) return new GrThisReferenceExpressionImpl(node);
if (elem == SUPER_REFERENCE_EXPRESSION) return new GrSuperReferenceExpressionImpl(node);
if (elem == PARENTHESIZED_EXPRESSION) return new GrParenthesizedExpressionImpl(node);
if (elem == NEW_EXPRESSION) return new GrNewExpressionImpl(node);
if (elem == ANONYMOUS_CLASS_DEFINITION) return new GrAnonymousClassDefinitionImpl(node);
@@ -42,7 +42,7 @@ public class AnnotationArguments implements GroovyElementTypes {
return;
}
if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) {
if (checkIdentAndAssign(builder)) {
parsePairs(builder, parser);
}
else {
@@ -60,6 +60,11 @@ public class AnnotationArguments implements GroovyElementTypes {
annArgs.done(ANNOTATION_ARGUMENTS);
}
private static boolean checkIdentAndAssign(PsiBuilder builder) {
//def is valid name identifier
return ParserUtils.lookAhead(builder, mIDENT, mASSIGN) || ParserUtils.lookAhead(builder, kDEF, mASSIGN);
}
/*
* annotationMemberValueInitializer ::= conditionalExpression | annotation
*/
@@ -114,8 +119,10 @@ public class AnnotationArguments implements GroovyElementTypes {
private static boolean parsePair(PsiBuilder builder, GroovyParser parser) {
PsiBuilder.Marker marker = builder.mark();
if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) {
ParserUtils.getToken(builder, mIDENT);
if (checkIdentAndAssign(builder)) {
if (!ParserUtils.getToken(builder, mIDENT)) {
ParserUtils.getToken(builder, kDEF);
}
ParserUtils.getToken(builder, mASSIGN);
ParserUtils.getToken(builder, mNLS);
}
@@ -70,13 +70,13 @@ public class ConstructorBody implements GroovyElementTypes {
if (ParserUtils.lookAhead(builder, kTHIS, mLPAREN)) {
final PsiBuilder.Marker marker = builder.mark();
ParserUtils.getToken(builder, kTHIS);
marker.done(THIS_REFERENCE_EXPRESSION);
marker.done(REFERENCE_EXPRESSION);
result = true;
}
if (ParserUtils.lookAhead(builder, kSUPER, mLPAREN)) {
final PsiBuilder.Marker marker = builder.mark();
ParserUtils.getToken(builder, kSUPER);
marker.done(SUPER_REFERENCE_EXPRESSION);
marker.done(REFERENCE_EXPRESSION);
result = true;
}
@@ -41,7 +41,7 @@ import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expres
public class PathExpression implements GroovyElementTypes {
public static boolean parse(PsiBuilder builder, GroovyParser parser) {
return parsePathExprQualifierForExprStatement(builder, parser) != PathExpression.Result.WRONG_WAY;
return parsePathExprQualifierForExprStatement(builder, parser) != WRONG_WAY;
}
public enum Result {INVOKED_EXPR, METHOD_CALL, WRONG_WAY, LITERAL}
@@ -70,10 +70,10 @@ public class PathExpression implements GroovyElementTypes {
PsiBuilder.Marker argsMarker = builder.mark();
argsMarker.done(ARGUMENTS);
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, newMarker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
else {
result = pathElementParse(builder, newMarker, parser, qualifierType, INVOKED_EXPR);
result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR);
}
}
else {
@@ -102,10 +102,9 @@ public class PathExpression implements GroovyElementTypes {
private static final TokenSet DOTS = TokenSet.create(mSPREAD_DOT, mOPTIONAL_DOT, mMEMBER_POINTER, mDOT);
private static Result pathElementParse(PsiBuilder builder,
PsiBuilder.Marker marker,
GroovyParser parser,
IElementType qualifierType,
Result result) {
PsiBuilder.Marker marker,
GroovyParser parser,
Result result) {
GroovyElementType res;
@@ -117,12 +116,7 @@ public class PathExpression implements GroovyElementTypes {
ParserUtils.getToken(builder, DOTS);
ParserUtils.getToken(builder, mNLS);
TypeArguments.parseTypeArguments(builder, true);
if (kTHIS.equals(builder.getTokenType()) || kSUPER.equals(builder.getTokenType())) {
res = parseThisSuperExpression(builder, qualifierType);
}
else {
res = namePartParse(builder, parser);
}
res = namePartParse(builder, parser);
if (!res.equals(WRONGWAY)) {
PsiBuilder.Marker newMarker = marker.precede();
marker.done(res);
@@ -130,10 +124,10 @@ public class PathExpression implements GroovyElementTypes {
PsiBuilder.Marker argsMarker = builder.mark();
argsMarker.done(ARGUMENTS);
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, newMarker, parser, res, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
else {
result = pathElementParse(builder, newMarker, parser, res, INVOKED_EXPR);
result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR);
}
}
else {
@@ -145,12 +139,12 @@ public class PathExpression implements GroovyElementTypes {
PrimaryExpression.methodCallArgsParse(builder, parser);
if (checkForLCurly(builder)) {
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, marker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, marker, parser, METHOD_CALL);
}
else {
PsiBuilder.Marker newMarker = marker.precede();
marker.done(PATH_METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
}
else if (checkForLCurly(builder)) {
@@ -158,12 +152,12 @@ public class PathExpression implements GroovyElementTypes {
appendedBlockParse(builder, parser);
if (checkForLCurly(builder)) {
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, marker, parser, qualifierType, METHOD_CALL);
result = pathElementParse(builder, marker, parser, METHOD_CALL);
}
else {
PsiBuilder.Marker newMarker = marker.precede();
marker.done(PATH_METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, PATH_METHOD_CALL, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
}
else if (checkForArrayAccess(builder)) {
@@ -174,10 +168,10 @@ public class PathExpression implements GroovyElementTypes {
PsiBuilder.Marker argsMarker = builder.mark();
argsMarker.done(ARGUMENTS);
ParserUtils.getToken(builder, mNLS);
result = pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY, METHOD_CALL);
result = pathElementParse(builder, newMarker, parser, METHOD_CALL);
}
else {
result = pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY, INVOKED_EXPR);
result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR);
}
}
else {
@@ -196,23 +190,6 @@ public class PathExpression implements GroovyElementTypes {
!ParserUtils.lookAhead(builder, mLBRACK, mNLS, mCOLON);
}
private static GroovyElementType parseThisSuperExpression(PsiBuilder builder, IElementType qualifierType) {
if (qualifierType != REFERENCE_EXPRESSION) {
return WRONGWAY;
}
final IElementType tokenType = builder.getTokenType();
builder.advanceLexer();
final GroovyElementType type;
if (kTHIS.equals(tokenType)) {
type = THIS_REFERENCE_EXPRESSION;
}
else {
type = SUPER_REFERENCE_EXPRESSION;
}
return type;
}
/**
* Property selector parsing
*
@@ -47,21 +47,13 @@ public class PrimaryExpression implements GroovyElementTypes {
ParserUtils.eatElement(builder, BUILT_IN_TYPE_EXPRESSION);
return BUILT_IN_TYPE_EXPRESSION;
}
if (kTHIS == tokenType) {
ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION);
return THIS_REFERENCE_EXPRESSION;
}
if (kSUPER == tokenType) {
ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION);
return SUPER_REFERENCE_EXPRESSION;
}
if (kNEW == tokenType) {
PsiBuilder.Marker marker = builder.mark();
final GroovyElementType type = newExprParse(builder, parser);
marker.done(type);
return type;
}
if (mIDENT == tokenType) {
if (mIDENT == tokenType || kSUPER == tokenType || kTHIS == tokenType) {
ParserUtils.eatElement(builder, REFERENCE_EXPRESSION);
return REFERENCE_EXPRESSION;
}
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilder.Marker;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
@@ -60,18 +61,13 @@ public class StringConstructorExpression implements GroovyElementTypes {
final Marker injection = builder.mark();
ParserUtils.getToken(builder, mDOLLAR);
ParserUtils.getToken(builder, mSTAR);
if (mIDENT.equals(builder.getTokenType())) {
IElementType tokenType = builder.getTokenType();
if (mIDENT == tokenType || kTHIS==tokenType || kSUPER==tokenType) {
PathExpression.parse(builder, parser);
}
else if (mLCURLY.equals(builder.getTokenType())) {
else if (mLCURLY == tokenType) {
OpenOrClosableBlock.parseClosableBlock(builder, parser);
}
else if (kTHIS.equals(builder.getTokenType())) {
ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION);
}
else if (kSUPER.equals(builder.getTokenType())) {
ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION);
}
else {
ParserUtils.wrapError(builder, GroovyBundle.message("identifier.or.block.expected"));
}
@@ -184,18 +184,6 @@ public abstract class GroovyElementVisitor {
visitExpression(referenceExpression);
}
public void visitThisExpression(GrThisReferenceExpression thisExpression) {
visitThisSuperReferenceExpression(thisExpression);
}
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
visitThisSuperReferenceExpression(superExpression);
}
public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expression) {
visitExpression(expression);
}
public void visitCastExpression(GrTypeCastExpression typeCastExpression) {
visitExpression(typeCastExpression);
}
@@ -37,7 +37,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArg
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
@@ -62,7 +65,7 @@ public abstract class GroovyPsiElementFactory implements JVMElementFactory {
public abstract GrCodeReferenceElement createCodeReferenceElementFromText(String text);
public abstract GrThisReferenceExpression createThisExpression(PsiManager manager, PsiClass psiClass);
public abstract GrReferenceExpression createThisExpression(PsiManager manager, PsiClass psiClass);
public abstract GrBlockStatement createBlockStatementFromText(String text, @Nullable PsiElement context);
@@ -27,14 +27,15 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
public final class SpreadState {
public static final Key<SpreadState> SPREAD_STATE = Key.create("Spread state");
private final PsiType containerType;
@Nullable private final PsiType containerType;
@Nullable private final SpreadState innerState;
public SpreadState(PsiType type, @Nullable SpreadState state) {
public SpreadState(@Nullable PsiType type, @Nullable SpreadState state) {
containerType = type;
innerState = state;
}
@Nullable
public PsiType getContainerType() {
return containerType;
}
@@ -48,7 +49,8 @@ public final class SpreadState {
return new SpreadState(type, state);
}
public static PsiType apply(PsiType item, @Nullable SpreadState state, Project project) {
@Nullable
public static PsiType apply(@Nullable PsiType item, @Nullable SpreadState state, Project project) {
if (state == null) return item;
return apply(TypesUtil.createSimilarCollection(state.getContainerType(), project, item), state.getInnerState(), project);
}
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
/**
* User: Dmitry.Krasilschikov
@@ -31,7 +31,7 @@ public interface GrConstructorInvocation extends GrStatement, GrConstructorCall
boolean isThisCall();
GrThisSuperReferenceExpression getThisOrSuperKeyword();
GrReferenceExpression getInvokedExpression();
@Nullable
PsiClass getDelegatedClass();
@@ -15,11 +15,20 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
/**
* @author Maxim.Medvedev
*/
public interface GrThisSuperReferenceExpression extends GrExpression, PsiPolyVariantReference, GrQualifiedReference<GrReferenceExpression> {
@NotNull
@Override
PsiElement getReferenceNameElement();
@NotNull
@Override
String getReferenceName();
}
@@ -671,7 +671,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
}
@Override
public GrThisReferenceExpression createThisExpression(PsiManager manager, @Nullable PsiClass psiClass) {
public GrReferenceExpression createThisExpression(PsiManager manager, @Nullable PsiClass psiClass) {
final String text;
if (psiClass == null) {
text = "this";
@@ -679,8 +679,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
else {
text = psiClass.getQualifiedName() + ".this";
}
final GroovyFileImpl dummy = createDummyFile(text);
return (GrThisReferenceExpression)dummy.getStatements()[0];
return createReferenceExpressionFromText(text);
}
@Override
@@ -499,7 +499,7 @@ public class PsiImplUtil {
}
}
public static <T extends PsiElement> void setQualifier(GrQualifiedReference<T> ref, T newQualifier) {
public static <T extends PsiElement> void setQualifier(@NotNull GrQualifiedReference<T> ref, @Nullable T newQualifier) {
final T oldQualifier = ref.getQualifier();
final ASTNode node = ref.getNode();
final PsiElement refNameElement = ref.getReferenceNameElement();
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,7 +64,13 @@ public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implemen
@Nullable
public PsiElement getNameIdentifierGroovy() {
return findChildByType(GroovyTokenTypes.mIDENT);
PsiElement child = getFirstChild();
if (child == null) return null;
IElementType type = child.getNode().getElementType();
if (type == GroovyTokenTypes.mIDENT || type == GroovyTokenTypes.kDEF) return child;
return null;
}
public PsiIdentifier getNameIdentifier() {
@@ -17,16 +17,16 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements;
import com.intellij.lang.ASTNode;
import com.intellij.psi.*;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrCallImpl;
@@ -52,18 +52,25 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
}
public boolean isSuperCall() {
return findChildByType(GroovyElementTypes.SUPER_REFERENCE_EXPRESSION) != null;
return getKeywordType() == GroovyTokenTypes.kSUPER;
}
public boolean isThisCall() {
return findChildByType(GroovyElementTypes.THIS_REFERENCE_EXPRESSION) != null;
return getKeywordType() == GroovyTokenTypes.kTHIS;
}
private static final TokenSet THIS_OR_SUPER_SET =
TokenSet.create(GroovyElementTypes.THIS_REFERENCE_EXPRESSION, GroovyElementTypes.SUPER_REFERENCE_EXPRESSION);
@Nullable
private IElementType getKeywordType() {
GrReferenceExpression keyword = getInvokedExpression();
PsiElement refElement = keyword.getReferenceNameElement();
if (refElement == null) return null;
public GrThisSuperReferenceExpression getThisOrSuperKeyword() {
return (GrThisSuperReferenceExpression)findNotNullChildByType(THIS_OR_SUPER_SET);
return refElement.getNode().getElementType();
}
public GrReferenceExpression getInvokedExpression() {
return findNotNullChildByClass(GrReferenceExpression.class);
}
@NotNull
@@ -75,7 +82,8 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
PsiSubstitutor substitutor;
if (isThisCall()) {
substitutor = PsiSubstitutor.EMPTY;
} else {
}
else {
PsiClass enclosing = PsiUtil.getContextClass(this);
assert enclosing != null;
substitutor = TypeConversionUtil.getSuperClassSubstitutor(clazz, enclosing, PsiSubstitutor.EMPTY);
@@ -85,7 +93,7 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
incompleteCode, false);
final ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
clazz.processDeclarations(processor, state, null, this);
ResolveUtil.processNonCodeMembers(thisType, processor, getThisOrSuperKeyword(), state);
ResolveUtil.processNonCodeMembers(thisType, processor, getInvokedExpression(), state);
return processor.getCandidates();
}
@@ -118,11 +126,6 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
return null;
}
@NotNull
public String getCanonicalText() {
return getText(); //TODO
}
@NotNull
@Override
public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) {
@@ -46,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
@@ -133,8 +132,8 @@ public class CompleteReferenceExpression {
if (refExpr.getDotTokenType() != GroovyTokenTypes.mSPREAD_DOT) {
getVariantsFromQualifier(refExpr, processor, qualifier);
if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName()) ||
qualifier instanceof GrThisReferenceExpression) {
if (qualifier instanceof GrReferenceExpression &&
("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || PsiUtil.isThisReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier))) {
processIfJavaLangClass(refExpr, processor, qualifier.getType());
}
}
@@ -261,7 +260,7 @@ public class CompleteReferenceExpression {
}
else {
getVariantsFromQualifierType(refExpr, processor, qualifierType, project);
if (qualifier instanceof GrReferenceExpression) {
if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass) { ////omitted .class
GlobalSearchScope scope = refExpr.getResolveScope();
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.Pair;
@@ -43,6 +44,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.codeInsight.GrReassignedLocalVarsChecker;
import org.jetbrains.plugins.groovy.codeInsight.GroovyTargetElementEvaluator;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
@@ -81,6 +83,8 @@ import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mMEMBER_P
*/
public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpression> implements GrReferenceExpression {
private static final Logger LOG = Logger.getInstance(GrReferenceExpressionImpl.class);
public GrReferenceExpressionImpl(@NotNull ASTNode node) {
super(node);
}
@@ -145,9 +149,25 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
private GroovyResolveResult[] resolveTypeOrPropertyInner() {
PsiElement nameElement = getReferenceNameElement();
String name = getReferenceName();
if (name == null) return GroovyResolveResult.EMPTY_ARRAY;
if (name == null || nameElement == null) return GroovyResolveResult.EMPTY_ARRAY;
IElementType nameType = nameElement.getNode().getElementType();
if (nameType == GroovyTokenTypes.kTHIS) {
ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
if (GrReferenceResolveUtil.resolveThisExpression(this, results)) {
return results.toArray(new GroovyResolveResult[results.size()]);
}
}
else if (nameType == GroovyTokenTypes.kSUPER) {
ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
if (GrReferenceResolveUtil.resolveSuperExpression(this, results)) {
return results.toArray(new GroovyResolveResult[results.size()]);
}
}
EnumSet<ClassHint.ResolveKind> kinds = getParent() instanceof GrReferenceExpression
? ResolverProcessor.RESOLVE_KINDS_CLASS_PACKAGE
@@ -213,11 +233,12 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return GroovyResolveResult.EMPTY_ARRAY;
}
private boolean containsLocalVar(GroovyResolveResult[] fieldCandidates) {
private static boolean containsLocalVar(GroovyResolveResult[] fieldCandidates) {
boolean preferVar = false;
if (fieldCandidates.length > 0) {
for (GroovyResolveResult candidate : fieldCandidates) {
PsiElement element = candidate.getElement();
LOG.assertTrue(element != null, candidate);
if (GroovyRefactoringUtil.isLocalVariable(element)) {
preferVar = true;
break;
@@ -335,7 +356,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return doResolveByShape(allVariants, upToArgument);
}
assert upToArgument == null;
LOG.assertTrue(upToArgument == null);
return TypeInferenceHelper.getCurrentContext().getCachedValue(this, new NullableComputable<Pair<Boolean, GroovyResolveResult[]>>() {
@Override
@@ -347,7 +368,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
private Pair<Boolean, GroovyResolveResult[]> doResolveByShape(boolean allVariants, @Nullable GrExpression upToArgument) {
final String name = getReferenceName();
assert name != null;
LOG.assertTrue(name != null);
final MethodResolverProcessor shapeProcessor = createMethodProcessor(allVariants, name, true, upToArgument);
processMethods(shapeProcessor);
@@ -359,7 +380,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
private static void assertAllAreValid(GroovyResolveResult[] candidates) {
for (GroovyResolveResult candidate : candidates) {
final PsiElement element = candidate.getElement();
assert element == null || element.isValid();
LOG.assertTrue(element == null || element.isValid());
}
}
@@ -425,6 +446,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
newElementName = name;
}
}
if (PsiUtil.isThisOrSuperRef(this)) return this;
return handleElementRenameSimple(newElementName);
}
@@ -530,7 +552,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (resolved instanceof PsiClass) {
final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
if (getParent() instanceof GrReferenceExpression) {
if (getParent() instanceof GrReferenceExpression || PsiUtil.isSuperReference(this) || PsiUtil.isInstanceThisRef(this)) {
return factory.createType((PsiClass)resolved);
}
else {
@@ -611,7 +633,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Nullable
public PsiType fun(GrReferenceExpressionImpl refExpr) {
PsiType result = GrReassignedLocalVarsChecker.checkReassignedVar(refExpr, true);
if (result!=null) return result;
if (result != null) return result;
final PsiElement resolved = refExpr.resolve();
final PsiType inferred = getInferredTypes(refExpr, resolved);
@@ -620,7 +642,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (nominal == null) {
//inside nested closure we could still try to infer from variable initializer. Not sound, but makes sense
if (resolved instanceof GrVariable) {
assert resolved.isValid();
LOG.assertTrue(resolved.isValid());
return ((GrVariable)resolved).getTypeGroovy();
}
}
@@ -639,7 +661,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
@Nullable
private static PsiType getInferredTypes(GrReferenceExpressionImpl refExpr, PsiElement resolved) {
private static PsiType getInferredTypes(GrReferenceExpressionImpl refExpr, @Nullable PsiElement resolved) {
final GrExpression qualifier = refExpr.getQualifier();
if (qualifier == null && !(resolved instanceof PsiClass)) {
return TypeInferenceHelper.getCurrentContext().getVariableType(refExpr);
@@ -683,7 +705,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
ASTNode node = nameElement.getNode();
ASTNode newNameNode = GroovyPsiElementFactory.getInstance(getProject()).createReferenceNameFromText(name).getNode();
assert newNameNode != null && node != null;
LOG.assertTrue(newNameNode != null && node != null);
node.getTreeParent().replaceChild(node, newNameNode);
return this;
@@ -19,21 +19,24 @@ import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -41,6 +44,8 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.CompletionProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
import java.util.List;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mSPREAD_DOT;
/**
@@ -84,8 +89,8 @@ public class GrReferenceResolveUtil {
if (!processQualifier(processor, qualifier, place)) return false;
}
if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName()) ||
qualifier instanceof GrThisReferenceExpression) {
if (qualifier instanceof GrReferenceExpression &&
("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || PsiUtil.isThisReference(qualifier))) {
if (!processIfJavaLangClass(processor, qualifier.getType(), qualifier, place)) return false;
}
}
@@ -105,7 +110,7 @@ public class GrReferenceResolveUtil {
}
private static boolean processIfJavaLangClass(ResolverProcessor processor,
PsiType type,
@Nullable PsiType type,
GroovyPsiElement resolveContext,
GrReferenceExpression place) {
if (!(type instanceof PsiClassType)) return true;
@@ -163,7 +168,7 @@ public class GrReferenceResolveUtil {
}
else {
if (!processQualifierType(processor, qualifierType, state, place)) return false;
if (qualifier instanceof GrReferenceExpression) {
if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
if (resolved instanceof PsiClass) { //omitted .class
PsiClass javaLangClass = PsiUtil.getJavaLangClass(resolved, place.getResolveScope());
@@ -266,4 +271,66 @@ public class GrReferenceResolveUtil {
return TypesUtil.getJavaLangObject(ref);
}
public static boolean resolveThisExpression(GrReferenceExpression ref, List<GroovyResolveResult> results) {
GrExpression qualifier = ref.getQualifier();
if (qualifier == null) {
final PsiElement parent = ref.getParent();
if (parent instanceof GrConstructorInvocation) {
GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false);
ContainerUtil.addAll(results, res);
return true;
}
PsiClass aClass = PsiUtil.getContextClass(ref);
if (aClass == null) return false;
results.add(new GroovyResolveResultImpl(aClass, null, null, PsiSubstitutor.EMPTY, true, true));
return true;
}
else {
if (!(qualifier instanceof GrReferenceExpression)) return false;
GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
PsiElement resolved = result.getElement();
if (!(resolved instanceof PsiClass)) return false;
if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false;
results.add(result);
return true;
}
}
public static boolean resolveSuperExpression(GrReferenceExpression ref, List<GroovyResolveResult> results) {
GrExpression qualifier = ref.getQualifier();
PsiClass aClass;
if (qualifier == null) {
final PsiElement parent = ref.getParent();
if (parent instanceof GrConstructorInvocation) {
GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false);
ContainerUtil.addAll(results, res);
return true;
}
aClass = PsiUtil.getContextClass(ref);
if (aClass == null) return false;
}
else {
if (!(qualifier instanceof GrReferenceExpression)) return false;
GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
PsiElement resolved = result.getElement();
if (!(resolved instanceof PsiClass)) return false;
if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false;
aClass = (PsiClass)resolved;
}
PsiClass superClass = aClass.getSuperClass();
if (superClass == null) return true; //no super class, but the reference is definitely super-reference
PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
results.add(new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true));
return true;
}
}
@@ -76,7 +76,6 @@ public class GrSuperReferenceExpressionImpl extends GrThisSuperReferenceExpressi
}
public void accept(GroovyElementVisitor visitor) {
visitor.visitSuperExpression(this);
}
public String toString() {
@@ -78,7 +78,6 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio
}
public void accept(GroovyElementVisitor visitor) {
visitor.visitThisExpression(this);
}
public String toString() {
@@ -11,14 +11,15 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
/**
* @author Maxim.Medvedev
@@ -40,6 +41,7 @@ public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImp
PsiImplUtil.setQualifier(this, newQualifier);
}
@NotNull
@Override
public PsiElement getReferenceNameElement() {
return getLastChild();
@@ -52,7 +54,7 @@ public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImp
@Override
public TextRange getRangeInElement() {
final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyElementTypes.kTHIS, GroovyElementTypes.kSUPER));
final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyTokenTypes.kTHIS, GroovyTokenTypes.kSUPER));
return TextRange.from(token.getStartOffsetInParent(), token.getTextLength());
}
@@ -52,7 +52,10 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.util.LightCacheKey;
import java.util.*;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import static com.intellij.psi.CommonClassNames.*;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
@@ -716,7 +719,7 @@ public class TypesUtil {
}
@Nullable
public static PsiClassType createSimilarCollection(PsiType collection, Project project, PsiType... itemType) {
public static PsiClassType createSimilarCollection(@Nullable PsiType collection, Project project, PsiType... itemType) {
if (InheritanceUtil.isInheritor(collection, "java.util.SortedSet")) {
return createCollection(project, "java.util.SortedSet", itemType);
}
@@ -376,8 +376,17 @@ public class PsiUtil {
}
}
}
}
else if (isThisOrSuperRef(qualifier)) {
//static members may be invoked from this.<...>
final boolean isInStatic = isInStaticContext((GrReferenceExpression)qualifier);
if (isThisReference(qualifier) && isInStatic) {
return member.hasModifierProperty(PsiModifier.STATIC);
}
return !isStatic || !filterStaticAfterInstanceQualifier || CodeInsightSettings.getInstance().SHOW_STATIC_AFTER_INSTANCE;
}
PsiElement qualifierResolved = ((GrReferenceExpression)qualifier).resolve();
if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) { //static context
if (member instanceof PsiClass) {
@@ -412,14 +421,6 @@ public class PsiUtil {
return false;
}
}
else if (qualifier instanceof GrThisReferenceExpression && ((GrThisReferenceExpression)qualifier).getQualifier() == null) {
//static members may be invoked from this.<...>
final boolean isInStatic = isInStaticContext((GrThisReferenceExpression)qualifier);
if (containingClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(containingClass.getQualifiedName())) {
return !filterStaticAfterInstanceQualifier || !member.hasModifierProperty(PsiModifier.STATIC) || CodeInsightSettings.getInstance().SHOW_STATIC_AFTER_INSTANCE;
}
else if (isInStatic) return member.hasModifierProperty(PsiModifier.STATIC);
}
//instance context
if (member instanceof PsiClass) {
@@ -517,24 +518,31 @@ public class PsiUtil {
}
public static boolean isInStaticContext(GrQualifiedReference refExpression) {
return isInStaticContext(refExpression, null);
PsiClass targetClass = null;
if (isThisReference(refExpression) && refExpression.getQualifier() != null) {
targetClass = (PsiClass)((GrReferenceExpression)refExpression.getQualifier()).resolve();
}
return isInStaticContext(refExpression, targetClass);
}
public static boolean isInStaticContext(GrQualifiedReference refExpression, @Nullable PsiClass targetClass) {
if (refExpression.getQualifier() != null) {
PsiElement qualifier = refExpression.getQualifier();
if (qualifier instanceof GrReferenceExpression) return ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass;
PsiElement qualifier = refExpression.getQualifier();
if (qualifier != null && !isThisOrSuperRef(refExpression)) {
return qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass;
}
else {
PsiElement run = refExpression;
while (run != null && run != targetClass) {
if (targetClass == null && run instanceof PsiClass) return false;
if (run instanceof PsiModifierListOwner && ((PsiModifierListOwner)run).hasModifierProperty(PsiModifier.STATIC)) return true;
run = run.getParent();
}
if (isSuperReference(refExpression)) return false;
//this reference should be checked as all other refs
PsiElement run = refExpression;
while (run != null && run != targetClass) {
if (targetClass == null && run instanceof PsiClass) return false;
if (run instanceof PsiModifierListOwner && ((PsiModifierListOwner)run).hasModifierProperty(PsiModifier.STATIC)) return true;
run = run.getParent();
}
return false;
}
public static Iterable<PsiClass> iterateSupers(final @NotNull PsiClass psiClass, final boolean includeSelf) {
@@ -661,7 +669,7 @@ public class PsiUtil {
return true;
}
if ((expr instanceof GrThisReferenceExpression || expr instanceof GrSuperReferenceExpression) &&
if ((isThisOrSuperRef(expr)) &&
GroovyConfigUtils.getInstance().isVersionAtLeast(expr, GroovyConfigUtils.GROOVY1_8)) {
return true;
}
@@ -864,7 +872,7 @@ public class PsiUtil {
public static boolean hasEnclosingInstanceInScope(@NotNull PsiClass clazz, @Nullable PsiElement scope, boolean isSuperClassAccepted) {
PsiElement place = scope;
while (place != null && place != clazz && !(place instanceof PsiFile)) {
while (place != null && place != clazz && !(place instanceof PsiFile && place.isPhysical())) {
if (place instanceof PsiClass) {
if (isSuperClassAccepted) {
if (InheritanceUtil.isInheritorOrSelf((PsiClass)place, clazz, true)) return true;
@@ -874,8 +882,9 @@ public class PsiUtil {
}
}
if (place instanceof PsiModifierListOwner && ((PsiModifierListOwner)place).hasModifierProperty(PsiModifier.STATIC)) return false;
place = place.getParent();
place = place.getContext();
}
if (clazz instanceof GroovyScriptClass) return place == clazz.getContainingFile();
return place == clazz;
}
@@ -951,7 +960,7 @@ public class PsiUtil {
public static boolean isMethodUsage(PsiElement element) {
if (element instanceof GrEnumConstant) return true;
if (!(element instanceof GrReferenceElement || element instanceof GrThisSuperReferenceExpression)) return false;
if (!(element instanceof GrReferenceElement)) return false;
PsiElement parent = element.getParent();
if (parent instanceof GrCall) {
return true;
@@ -1184,7 +1193,7 @@ public class PsiUtil {
return null;
}
@Nullable
public static GrCall getCallByNamedParameter(GrNamedArgument namedArgument) {
PsiElement parent = namedArgument.getParent();
@@ -1282,7 +1291,7 @@ public class PsiUtil {
@NotNull
public static ResolveResult getAccessObjectClass(GrExpression expression) {
if (expression instanceof GrSuperReferenceExpression || expression instanceof GrThisReferenceExpression) return GroovyResolveResult.EMPTY_RESULT;
if (isThisOrSuperRef(expression)) return GroovyResolveResult.EMPTY_RESULT;
PsiType type = expression.getType();
if (type instanceof PsiClassType) {
return ((PsiClassType)type).resolveGenerics();
@@ -1373,4 +1382,60 @@ public class PsiUtil {
if (type instanceof PsiArrayType) return ((PsiArrayType)type).getComponentType();
return com.intellij.psi.util.PsiUtil.extractIterableTypeParameter(type, true);
}
public static boolean isThisReference(@Nullable PsiElement expression) {
if (!(expression instanceof GrReferenceExpression)) return false;
GrReferenceExpression ref = (GrReferenceExpression)expression;
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement == null) return false;
IElementType type = nameElement.getNode().getElementType();
if (type != GroovyTokenTypes.kTHIS) return false;
GrExpression qualifier = ref.getQualifier();
if (qualifier == null) {
return true;
}
else {
PsiElement resolved = ref.resolve();
return resolved instanceof PsiClass && hasEnclosingInstanceInScope((PsiClass)resolved, ref, false);
}
}
public static boolean isSuperReference(@Nullable PsiElement expression) {
if (!(expression instanceof GrReferenceExpression)) return false;
GrReferenceExpression ref = (GrReferenceExpression)expression;
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement == null) return false;
IElementType type = nameElement.getNode().getElementType();
if (type != GroovyTokenTypes.kSUPER) return false;
GrExpression qualifier = ref.getQualifier();
if (qualifier == null) {
return true;
}
else {
PsiElement resolved = ref.resolve();
return resolved instanceof PsiClass && hasEnclosingInstanceInScope(((PsiClass)resolved), ref, true);
}
}
public static boolean isThisOrSuperRef(@Nullable PsiElement qualifier) {
return qualifier instanceof GrReferenceExpression && (isThisReference(qualifier) || isSuperReference(qualifier));
}
public static boolean isInstanceThisRef(GrExpression qualifier) {
if (isThisReference(qualifier)) {
GrReferenceExpression ref = (GrReferenceExpression)qualifier;
PsiElement resolved = ref.resolve();
if (resolved == null) return false;
return hasEnclosingInstanceInScope((PsiClass)resolved, qualifier, false);
}
return false;
}
}
@@ -49,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
@@ -575,7 +574,6 @@ public class ResolveUtil {
public static boolean mayBeKeyOfMap(GrReferenceExpression ref) {
final GrExpression qualifier = getSelfOrWithQualifier(ref);
if (qualifier == null) return false;
if (qualifier instanceof GrThisSuperReferenceExpression) return false;
if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass) return false;
return InheritanceUtil.isInheritor(qualifier.getType(), CommonClassNames.JAVA_UTIL_MAP);
}
@@ -24,8 +24,8 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
* @author Maxim.Medvedev
@@ -45,8 +45,8 @@ public class GroovyChangeContextUtil {
public static void encodeContextInfo(PsiElement element, PsiElement scope) {
if (!(element instanceof GroovyPsiElement)) return;
if (element instanceof GrThisReferenceExpression) {
GrThisReferenceExpression thisExpr = (GrThisReferenceExpression)element;
if (PsiUtil.isThisReference(element)) {
GrReferenceExpression thisExpr = (GrReferenceExpression)element;
final PsiClass containingClass = PsiTreeUtil.getParentOfType(thisExpr, PsiClass.class);
element.putCopyableUserData(KEY_ENCODED, KEY_ENCODED);
thisExpr.putCopyableUserData(QUALIFIER_CLASS_KEY, containingClass);
@@ -94,7 +94,7 @@ public class GroovyChangeContextUtil {
if (element.getCopyableUserData(KEY_ENCODED) != null) {
element.putCopyableUserData(KEY_ENCODED, null);
final PsiManager manager = element.getManager();
if (element instanceof GrThisReferenceExpression) {
if (PsiUtil.isThisReference(element)) {
final PsiClass thisQualClass = element.getCopyableUserData(QUALIFIER_CLASS_KEY);
element.putCopyableUserData(QUALIFIER_CLASS_KEY, null);
if (thisAccessExpr != null && !manager.areElementsEquivalent(thisClass, thisQualClass)) {
@@ -28,10 +28,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.ArrayList;
import java.util.Collections;
@@ -94,13 +93,13 @@ public class GroovyNameSuggestionUtil {
}
private static void generateNameByExpr(GrExpression expr, Set<String> possibleNames, NameValidator validator, boolean forStaticVariable) {
if (expr instanceof GrThisReferenceExpression) {
possibleNames.add(validator.validateName("thisInstance", true));
}
if (expr instanceof GrSuperReferenceExpression) {
possibleNames.add(validator.validateName("superInstance", true));
}
if (expr instanceof GrReferenceExpression && ((GrReferenceExpression) expr).getName() != null) {
if (PsiUtil.isThisReference(expr)) {
possibleNames.add(validator.validateName("thisInstance", true));
}
if (PsiUtil.isSuperReference(expr)) {
possibleNames.add(validator.validateName("superInstance", true));
}
GrReferenceExpression refExpr = (GrReferenceExpression) expr;
String name = refExpr.getName();
if (name != null && name.toUpperCase().equals(name)) {
@@ -196,7 +196,7 @@ public abstract class GroovyRefactoringUtil {
});
}
public static boolean isLocalVariable(PsiElement variable) {
public static boolean isLocalVariable(@Nullable PsiElement variable) {
return variable instanceof GrVariable && !(variable instanceof GrField || variable instanceof GrParameter);
}
@@ -460,7 +460,7 @@ public abstract class GroovyRefactoringUtil {
int result = EXPR_COPY_SAFE;
if (element == null) return result;
if (element instanceof GrThisReferenceExpression || element instanceof GrSuperReferenceExpression || element instanceof GrNamedElement) {
if (element instanceof GrNamedElement) {
return EXPR_COPY_SAFE;
}
@@ -449,7 +449,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
GrConstructorInvocation invocation =
GroovyPsiElementFactory.getInstance(constructor.getProject()).createConstructorInvocation("super()");
invocation = (GrConstructorInvocation)block.addStatementBefore(invocation, getFirstStatement(block));
processMethodUsage(invocation.getThisOrSuperKeyword(), changeInfo,
processMethodUsage(invocation.getInvokedExpression(), changeInfo,
changeInfo.isParameterSetOrOrderChanged() || changeInfo.isParameterNamesChanged(),
changeInfo.isExceptionSetChanged(), GrClosureSignatureUtil.ArgInfo.<PsiElement>empty_array(), substitutor);
}
@@ -44,7 +44,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClaus
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
@@ -163,7 +163,7 @@ public class CodeBlockGenerator extends Generator {
GenerationUtil.writeStatement(builder, context, invocation, new StatementWriter() {
@Override
public void writeStatement(StringBuilder builder, ExpressionContext context) {
final GrThisSuperReferenceExpression thisOrSuperKeyword = invocation.getThisOrSuperKeyword();
final GrReferenceExpression thisOrSuperKeyword = invocation.getInvokedExpression();
final GrArgumentList argumentList = invocation.getArgumentList();
final GroovyResolveResult resolveResult = invocation.advancedResolve();
if (thisOrSuperKeyword.getQualifier() == null) {
@@ -59,6 +59,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightLocalVariable;
@@ -436,13 +437,16 @@ public class ExpressionGenerator extends Generator {
else if (resolved == null || resolved instanceof GrLightLocalVariable) {
//write unresolved reference assignment via setter GroovyObject.setProperty(String name, Object value)
final GrExpression qualifier = ((GrReferenceExpression)realLValue).getQualifier();
final PsiType type = qualifier != null ? qualifier.getType() : factory.createExpressionFromText("this", expression).getType();
final PsiType type = GrReferenceResolveUtil.getQualifierType((GrReferenceExpression)realLValue);
final GrExpression[] args = new GrExpression[2];
args[0] = factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\"");
args[1] = getRValue(expression);
final PsiElement method = PsiImplUtil
.extractUniqueElement(ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType()));
final GrExpression[] args = {
factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\""),
getRValue(expression)
};
GroovyResolveResult[] candidates = type != null
? ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType())
: GroovyResolveResult.EMPTY_ARRAY;
final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
if (method instanceof PsiMethod) {
writeAssignmentWithSetter(qualifier, (PsiMethod)method, args, GrNamedArgument.EMPTY_ARRAY, EMPTY_ARRAY, PsiSubstitutor.EMPTY,
@@ -870,6 +874,16 @@ public class ExpressionGenerator extends Generator {
@Override
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
GrExpression qualifier = referenceExpression.getQualifier();
if (!context.isInAnonymousContext() && qualifier != null) {
qualifier.accept(this);
}
builder.append(referenceExpression.getReferenceName());
return;
}
final GrExpression qualifier = referenceExpression.getQualifier();
final GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
@@ -967,7 +981,19 @@ public class ExpressionGenerator extends Generator {
builder.append(refName);
}
else {
builder.append("getProperty(\"").append(refName).append("\")");
PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope());
PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(referenceExpression);
GroovyResolveResult[] candidates = qualifierType != null
? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression,
stringType)
: GroovyResolveResult.EMPTY_ARRAY;
final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
if (method != null) {
builder.append("getProperty(\"").append(refName).append("\")");
}
else {
builder.append(refName);
}
}
}
else {
@@ -1010,15 +1036,6 @@ public class ExpressionGenerator extends Generator {
return name;
}
@Override
public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expr) {
GrReferenceExpression qualifier = expr.getQualifier();
if (!context.isInAnonymousContext() && qualifier != null) {
qualifier.accept(this);
}
builder.append(expr.getReferenceName());
}
@Override
public void visitCastExpression(GrTypeCastExpression typeCastExpression) {
final GrTypeElement typeElement = typeCastExpression.getCastTypeElement();
@@ -47,10 +47,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.refactoring.extract.ExtractUtil;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.AnySupers;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.FieldConflictsResolver;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrExpressionWrapper;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterSettings;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.Collection;
@@ -96,7 +96,7 @@ public class ExtractClosureFromMethodProcessor extends ExtractClosureProcessorBa
for (GrStatement statement : statements) {
statement.accept(anySupers);
}
if (anySupers.isResult()) {
if (anySupers.containsSupers()) {
for (UsageInfo usageInfo : usagesIn) {
if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) {
if (!PsiTreeUtil.isAncestor(myMethod.getContainingClass(), usageInfo.getElement(), false)) {
@@ -23,7 +23,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
@@ -40,7 +39,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
@@ -51,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
@@ -63,6 +60,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.refactoring.NameValidator;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.Collection;
@@ -107,14 +105,9 @@ public class GroovyMethodInliner implements InlineHandler.Inliner {
}
}
}
final Ref<Boolean> hasSuper = new Ref<Boolean>(false);
info.expression.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
hasSuper.set(true);
}
});
if (hasSuper.get()) {
AnySupers visitor = new AnySupers();
info.expression.accept(visitor);
if (visitor.containsSupers()) {
conflicts.putValue(info.expression, GroovyRefactoringBundle.message("super.reference.is.used"));
}
}
@@ -104,7 +104,7 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
public static boolean expressionIsIncorrect(GrExpression expression, boolean acceptVoidCalls) {
if (expression instanceof GrParenthesizedExpression) return true;
if (expression instanceof GrSuperReferenceExpression) return true;
if (PsiUtil.isSuperReference(expression)) return true;
if (expression instanceof GrAssignmentExpression) return true;
if (expression instanceof GrReferenceExpression && expression.getParent() instanceof GrCall) {
final GroovyResolveResult resolveResult = ((GrReferenceExpression)expression).advancedResolve();
@@ -30,7 +30,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.ArrayList;
@@ -130,8 +129,7 @@ public class FieldConflictsResolver {
LOG.assertTrue(parentClass != null);
expressionFromText = factory.createReferenceExpressionFromText("A.this." + member.getName());
//noinspection ConstantConditions
((GrThisReferenceExpression)expressionFromText.getQualifier()).getQualifier().replace(
factory.createReferenceElementForClass(parentClass));
((GrReferenceExpression)expressionFromText.getQualifier()).getQualifier().replace(factory.createReferenceElementForClass(parentClass));
}
else {
expressionFromText = (GrReferenceExpression)factory.createExpressionFromText("this." + member.getName());
@@ -69,6 +69,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.FieldConflictsResolver;
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.OldReferencesResolver;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.BitSet;
@@ -125,7 +126,7 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess
if (expression != null && toSearchFor instanceof PsiMember) {
final AnySupers anySupers = new AnySupers();
expression.accept(anySupers);
if (anySupers.isResult()) {
if (anySupers.containsSupers()) {
final PsiElement containingClass = PsiUtil.getFileOrClassContext(toReplaceIn);
for (UsageInfo usageInfo : usagesIn) {
if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) {
@@ -123,7 +123,7 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me
if (scopes.size() == 0) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("there.is.no.method.or.closure"));
}
else if (scopes.size() == 1) {
else if (scopes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
final GrParametersOwner owner = scopes.get(0);
final PsiElement toSearchFor;
if (owner instanceof GrMethod) {
@@ -42,6 +42,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.refactoring.util.AnySupers;
import java.util.ArrayList;
import java.util.Collection;
@@ -97,7 +98,7 @@ public class GrIntroduceParameterProcessor extends BaseRefactoringProcessor impl
if (mySettings.getExpression() != null && !toReplaceIn.hasModifierProperty(PsiModifier.PRIVATE)) {
final AnySupers anySupers = new AnySupers();
mySettings.getExpression().accept(anySupers);
if (anySupers.isResult()) {
if (anySupers.containsSupers()) {
for (UsageInfo usageInfo : usagesIn) {
if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) {
if (!PsiTreeUtil.isAncestor(toReplaceIn.getContainingClass(), usageInfo.getElement(), false)) {
@@ -52,7 +52,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
@@ -390,7 +389,7 @@ public class GroovyIntroduceParameterUtil {
public void visitReferenceExpression(GrReferenceExpression ref) {
super.visitReferenceExpression(ref);
final GrExpression qualifier = ref.getQualifier();
if (qualifier != null && !(qualifier instanceof GrThisReferenceExpression)) return;
if (!PsiUtil.isThisReference(qualifier)) return;
final PsiElement resolved = ref.resolve();
if (!(resolved instanceof PsiField)) return;
@@ -29,6 +29,7 @@ import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
@@ -147,6 +148,13 @@ public class OldReferencesResolver {
PsiElement newExpr = expr; // references continue being resolved in the children of newExpr
if (oldExpr instanceof GrReferenceExpression) {
if (isThisReferenceToContainingClass(oldExpr) || isSimpleSuperReference(oldExpr)) {
if (myInstanceRef != null) {
newExpr.replace(getInstanceRef(factory));
}
return;
}
final GrReferenceExpression oldRef = (GrReferenceExpression)oldExpr;
newExpr = newExpr.replace(decodeReferenceExpression((GrReferenceExpression)newExpr, oldRef));
//newExpr = ((GrReferenceExpression)newExpr).getReferenceNameElement();
@@ -208,12 +216,6 @@ public class OldReferencesResolver {
}
}
}
else if (isThisReferenceToContainingClass(oldExpr) || isSimpleSuperReference(oldExpr)) {
if (myInstanceRef != null) {
newExpr.replace(getInstanceRef(factory));
}
return;
}
else {
PsiClass refClass = oldExpr.getCopyableUserData(REF_CLASS_KEY);
if (refClass != null && refClass.isValid()) {
@@ -302,13 +304,22 @@ public class OldReferencesResolver {
}
private static boolean isSimpleSuperReference(PsiElement oldExpr) {
return oldExpr instanceof GrSuperReferenceExpression && ((GrSuperReferenceExpression)oldExpr).getQualifier() == null;
if (oldExpr instanceof GrReferenceExpression) {
GrReferenceExpression ref = (GrReferenceExpression)oldExpr;
if (ref.getQualifier() == null) {
PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement != null) {
return nameElement.getNode().getElementType() == GroovyTokenTypes.kSUPER;
}
}
}
return false;
}
private boolean isThisReferenceToContainingClass(PsiElement oldExpr) {
if (!(oldExpr instanceof GrThisReferenceExpression)) return false;
if (!(oldExpr instanceof GrReferenceExpression && PsiUtil.isThisReference(oldExpr))) return false;
final GrReferenceExpression qualifier = ((GrThisReferenceExpression)oldExpr).getQualifier();
final GrReferenceExpression qualifier = (GrReferenceExpression)((GrReferenceExpression)oldExpr).getQualifier();
if (qualifier == null) return true;
final PsiClass contextClass = PsiUtil.getContextClass(myToReplaceIn);
@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
package org.jetbrains.plugins.groovy.refactoring.util;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
* @author Medvedev Max
@@ -25,12 +26,14 @@ public class AnySupers extends GroovyRecursiveElementVisitor {
boolean myContainsSupers = false;
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
super.visitSuperExpression(superExpression);
myContainsSupers = true;
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
super.visitReferenceExpression(referenceExpression);
if (PsiUtil.isSuperReference(referenceExpression)) {
myContainsSupers = true;
}
}
public boolean isResult() {
public boolean containsSupers() {
return myContainsSupers;
}
}
@@ -1,75 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection;
import org.jetbrains.plugins.groovy.util.TestUtils;
/**
* @author peter
*/
@SuppressWarnings({"JUnitTestClassNamingConvention"})
public class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase {
private static final DefaultLightProjectDescriptor DESCRIPTOR_1_6 = new DefaultLightProjectDescriptor() {
@Override
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel();
final VirtualFile groovyJar =
JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_6LibraryName() + "!/");
modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES);
modifiableModel.commit();
}
};
@Override
protected String getBasePath() {
return TestUtils.getTestDataPath() + "highlighting/";
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return DESCRIPTOR_1_6;
}
private void doTest(LocalInspectionTool... tools) {
myFixture.enableInspections(tools);
myFixture.testHighlighting(true, false, false, getTestName(false) + ".groovy");
}
public void testInnerEnum() throws Exception {doTest();}
public void testSuperWithNotEnclosingClass() throws Throwable {doTest();}
public void testThisWithWrongQualifier() throws Throwable {doTest();}
public void testImplicitEnumCoercion1_6() {
doTest(new GroovyAssignabilityCheckInspection());
}
public void testSlashyStrings() {doTest();}
public void testDiamonds() {doTest();}
}
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.highlighting
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.ContentEntry
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.vfs.JarFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.jetbrains.annotations.NotNull
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
import org.jetbrains.plugins.groovy.util.TestUtils
/**
* @author peter
*/
@SuppressWarnings(["JUnitTestClassNamingConvention"])
public class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase {
@NotNull
final LightProjectDescriptor projectDescriptor = new DefaultLightProjectDescriptor() {
@Override
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
final Library.ModifiableModel modifiableModel = model.moduleLibraryTable.createLibrary("GROOVY").modifiableModel
final VirtualFile groovyJar = JarFileSystem.instance.refreshAndFindFileByPath("$TestUtils.mockGroovy1_6LibraryName!/")
modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES)
modifiableModel.commit()
}
}
final String basePath = TestUtils.testDataPath + "highlighting/"
private void doTest(LocalInspectionTool... tools) {
myFixture.enableInspections(tools)
myFixture.testHighlighting(true, false, false, getTestName(false) + ".groovy")
}
public void testInnerEnum() { doTest() }
public void testSuperWithNotEnclosingClass() { doTest() }
public void _testThisWithWrongQualifier() { doTest() }
public void testImplicitEnumCoercion1_6() { doTest(new GroovyAssignabilityCheckInspection()) }
public void testSlashyStrings() { doTest() }
public void testDiamonds() { doTest() }
}
@@ -14,6 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.highlighting
import com.intellij.testFramework.IdeaTestUtil
import com.siyeh.ig.junit.JUnitAbstractTestClassNamingConventionInspection
import com.siyeh.ig.junit.JUnitTestClassNamingConventionInspection
@@ -21,18 +22,7 @@ import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilit
import org.jetbrains.plugins.groovy.codeInspection.confusing.GrUnusedIncDecInspection
import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection
//import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
//import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyResultOfAssignmentUsedInspection
//import org.jetbrains.plugins.groovy.codeInspection.bugs.*
//import org.jetbrains.plugins.groovy.codeInspection.confusing.*
//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection
//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection
//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryReturnInspection
//import org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMethodInspection
//import org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection
//import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
//import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection
//import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection
/**
* @author peter
*/
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package org.jetbrains.plugins.groovy.lang.parser
/**
* @author peter
*/
public class AnnotationsParsingTest extends GroovyParsingTestCase {
final String basePath = super.basePath + "annotations"
public void testAnn1() { doTest() }
public void testAnn2() { doTest() }
public void testAnn3() { doTest() }
public void testAnn4() { doTest() }
public void testAnn5() { doTest() }
public void testAnn6() { doTest() }
public void testAnn7() { doTest() }
public void testClassLiteral() { doTest() }
public void testImportAnn() { doTest() }
public void testPackageAnn() { doTest() }
public void testDefAttribute() {doTest()}
}
@@ -1,26 +0,0 @@
/*
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package org.jetbrains.plugins.groovy.lang.parser;
/**
* @author peter
*/
public class AnnotationsParsingTest extends GroovyParsingTestCase {
@Override
protected String getBasePath() {
return super.getBasePath() + "annotations";
}
public void testAnn1() throws Throwable { doTest(); }
public void testAnn2() throws Throwable { doTest(); }
public void testAnn3() throws Throwable { doTest(); }
public void testAnn4() throws Throwable { doTest(); }
public void testAnn5() throws Throwable { doTest(); }
public void testAnn6() throws Throwable { doTest(); }
public void testAnn7() throws Throwable { doTest(); }
public void testClassLiteral() throws Throwable { doTest(); }
public void testImportAnn() throws Throwable { doTest(); }
public void testPackageAnn() throws Throwable { doTest(); }
}
@@ -135,7 +135,8 @@ class B {
new B().fo<caret>o([''])
''')
def parameters = resolved.parameterList.parameters
assertInstanceOf(resolved, PsiMethod)
def parameters = (resolved as PsiMethod).parameterList.parameters
assertEquals 'java.util.List<java.lang.String>', parameters[0].type.canonicalText
}
@@ -150,6 +150,8 @@ public class TypeInferenceTest extends GroovyResolveTestCase {
public void testMethodCallInvokedOnArrayAccess() {
final GrReferenceExpression reference = (GrReferenceExpression)configureByFile("A.groovy");
assertNotNull(reference)
assertNotNull(reference.type)
assertEquals("java.lang.Integer", reference.type.canonicalText);
}
@@ -190,6 +190,10 @@ public class GrIntroduceParameterTest extends LightCodeInsightFixtureTestCase {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, "field <b><code>Test.i</code></b> is not accessible from method <b><code>XTest.n()</code></b>. Value for introduced parameter in that method call will be incorrect.");
}
public void testQualifiedThisSubstitution() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null);
}
public void testFieldAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
@@ -616,4 +616,30 @@ class Bar {
checkResult("def 'import'() {}")
}
}
void testConstructorAndSuper() {
myFixture.with {
configureByText(GroovyFileType.GROOVY_FILE_TYPE, '''\
class B<caret>ase {
def Base() {}
}
class Inheritor extends Base {
def Inheritor() {
super()
}
}
''')
renameElementAtCaret('Bassse')
checkResult('''\
class Bassse {
def Bassse() {}
}
class Inheritor extends Bassse {
def Inheritor() {
super()
}
}
''')
}
}
}
@@ -1,5 +1,5 @@
class X{
def foo() {
<error descr="'java.lang.String' is not an enclosing class">String.super</error>.toString()
<error descr="Qualified super is allowed only in nested/inner classes">String.super</error>.toString()
}
}
@@ -1,6 +1,6 @@
class X{
def foo(){
X x=new X();
<error descr="unknown class 'x'">x</error>.this.foo();
<error descr="Qualified this is allowed only in nested/inner classes">x.this</error>.foo();
}
}
@@ -0,0 +1,25 @@
@Foo(def = 4)
def a
-----
Groovy script
Variable definitions
Modifiers
Annotation
PsiElement(@)('@')
Reference element
PsiElement(identifier)('Foo')
Annotation arguments
PsiElement(()('(')
Annotation member value pair
PsiElement(def)('def')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('4')
PsiElement())(')')
PsiElement(new line)('\n')
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('a')
@@ -7,7 +7,7 @@ Groovy script
PsiWhiteSpace(' ')
Command arguments
Reference expression
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiElement(.)('.')
PsiElement(final)('final')
@@ -32,7 +32,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'super' reference expression
Reference expression
Reference expression
PsiElement(identifier)('X')
PsiElement(.)('.')
@@ -32,7 +32,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'super' reference expression
Reference expression
PsiElement(super)('super')
PsiElement(.)('.')
PsiElement(identifier)('foo')
@@ -32,7 +32,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'this' reference expression
Reference expression
Reference expression
PsiElement(identifier)('X')
PsiElement(.)('.')
@@ -34,7 +34,7 @@ Groovy script
PsiWhiteSpace('\n ')
Method call
Reference expression
'this' reference expression
Reference expression
PsiElement(this)('this')
PsiElement(.)('.')
PsiElement(identifier)('doo')

Some files were not shown because too many files have changed in this diff Show More