diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java index 5fea112a390b..0b531f5c0b9f 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java index 7788939afcc4..939e65112e77 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java @@ -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); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ResetFontSizeAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ResetFontSizeAction.java new file mode 100644 index 000000000000..62548b9c19fb --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ResetFontSizeAction.java @@ -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); + } + } +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 2f0cb90e6e6f..91cca6767251 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -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 diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index 3d6a3f547644..822c569937f8 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -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. diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index cd0ab21cc347..995dd9afa8e4 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -59,6 +59,7 @@ + diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index e52fb71106bd..5898d1ea879f 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -378,18 +378,52 @@ public abstract class UsefulTestCase extends TestCase { } public static void assertSameElements(Collection collection, Collection expected) { + assertSameElements(null, collection, expected); + } + + public static void assertSameElements(String message, Collection collection, Collection expected) { assertNotNull(collection); assertNotNull(expected); if (collection.size() != expected.size() || !new HashSet(expected).equals(new HashSet(collection))) { - Assert.assertEquals(toString(expected, "\n"), toString(collection, "\n")); - Assert.assertEquals(new HashSet(expected), new HashSet(collection)); + Assert.assertEquals(message, toString(expected, "\n"), toString(collection, "\n")); + Assert.assertEquals(message, new HashSet(expected), new HashSet(collection)); } } + + public void assertContainsOrdered(Collection collection, T... expected) { + assertContainsOrdered(collection, Arrays.asList(expected)); + } + + public void assertContainsOrdered(Collection collection, Collection expected) { + ArrayList copy = new ArrayList(collection); + copy.retainAll(expected); + assertOrderedEquals(toString(collection), copy, expected); + } + + public void assertContainsElements(Collection collection, T... expected) { + assertContainsElements(collection, Arrays.asList(expected)); + } + + public void assertContainsElements(Collection collection, Collection expected) { + ArrayList copy = new ArrayList(collection); + copy.retainAll(expected); + assertSameElements(toString(collection), copy, expected); + } public static String toString(Object[] collection, String separator) { return toString(Arrays.asList(collection), separator); } + public void assertDoesntContain(Collection collection, T... notExpected) { + assertDoesntContain(collection, Arrays.asList(notExpected)); + } + + public void assertDoesntContain(Collection collection, Collection notExpected) { + ArrayList copy = new ArrayList(collection); + copy.retainAll(notExpected); + assertEmpty(copy); + } + public static String toString(Collection collection, String separator) { List list = ContainerUtil.map2List(collection, new Function() { @Override diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index a9ccb62ac478..b3718f55cb5f 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -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 #ref 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 #ref 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=#ref 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=#ref#ref() 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 #ref from super class ''{0}'' accessed, while local variable access might be expected #loc ambiguous.field.access.hides.parameter.problem.descriptor=Field #ref from super class ''{0}'' accessed, while parameter access might be expected #loc ambiguous.field.access.hides.field.problem.descriptor=Field #ref 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 diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java index 27af75f92597..cfdd50433dfd 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java @@ -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); } } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html index fa42638c0f10..6500530e820b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html @@ -1,11 +1,11 @@ -Reports on any unnecessary qualification of this in the code. +Reports on any unnecessary qualification of this. Using a qualifier on this to disambiguate a code reference may easily become unnecessary via automatic refactorings, and should be deleted for clarity.

-Sample: -OuterClass.this.foo(); +For example: +

OuterClass.this.foo();

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html index 43c4cabafdc1..d2b583cc7172 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html @@ -5,10 +5,12 @@ Using this to disambiguate a code reference may easily become unnecessary via automatic refactorings, and is discouraged by many coding styles.

-Sample: -this.a=3; +For example: +

this.a = 3;

+Use the checkbox below to ignore assignments to fields. +

Powered by InspectionGadgets \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 7aee00157951..ea12ceb3ed2d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java index da3520067bcf..f134fa21b5ef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java index 68217b75294e..f96960beb51e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java @@ -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 } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index a0c9e87c6bbf..769eb76b0730 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -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 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")); + } } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java index 739f4b044543..371b7c58c38e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java @@ -58,6 +58,7 @@ public class GrReassignedLocalVarsChecker { return null; } + assert resolved != null; return getLeastUpperBoundByVar((GrVariable)resolved); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java index 8abe3a2aa44b..a28992a6ba40 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java @@ -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 diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java index 63e3f934aedf..cf497a0df039 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java index fc42963c8b3a..808131f1ac4c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java index 25c41a72ee67..f8f7105637c4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java @@ -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 { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java index 063cba59f6d4..02e9a6755261 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java index 639a2b259d84..4c9818edcfbc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java @@ -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); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java index 83a90b6d166c..33e84dfd9537 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java index 28622dd0f52d..695c480b7ee3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java index 8b5c637914b1..0d7bc5c20b5d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java index 55b3cecaa3e7..55e1daaf6775 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java index d2fca172ecda..f9a6975fcd1e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java @@ -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); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java index e39a99a645ab..2901bebb50df 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java index 3efc17894287..b8113d0cf8dd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java @@ -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); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java index 20e7380641f3..8db91c50fceb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java @@ -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 { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java index 22985a39e48e..8aebf825a629 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java @@ -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 } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java index 7f658f565e36..f7be975391fe 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java @@ -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); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java index 4a7bff3c3751..6e72bc9533d0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java index 092a0179445c..2628614ae01a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java @@ -381,7 +381,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase + 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 { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java index b49515c3eda8..0a2086c63d26 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java @@ -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 { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java index ad49289c47e8..477772a60073 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java index 1c51f7715440..6d0799f5c60b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java @@ -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(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java index a954c3e382ba..9608a67c8cc4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java @@ -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 { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java index 4c354de1c83a..e0e971704c93 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java @@ -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); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java index 0040d9dd6d20..f70bb124d849 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java @@ -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 boolean shortenReferenceInner(GrQualifiedReference 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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java index dfb5e0f0f2f8..176fbddbb5e0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java @@ -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 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); + } } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java index 425b8398908a..8d080a6d8f38 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java @@ -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"); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java index ecbecfc4f1f5..37dcc02bb3fe 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java @@ -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); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java index 4bb0a5a55b2f..c9c3773233e4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java @@ -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); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java index 1c6e6fc18712..30ddee8de3c5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java index feb2427e66eb..14fe82f7e05a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java @@ -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 * diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java index 8d284aa997b9..e2f6eab55964 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java index e4ac24ae22b7..57432c1d79e4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java @@ -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")); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java index ab15bfcb5bc6..967fff60b4ca 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java @@ -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); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java index a9eb766d1115..6b3a17c06965 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java @@ -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); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java index c5eec5f1c27d..891c61d6d763 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java @@ -27,14 +27,15 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt public final class SpreadState { public static final Key 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); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java index 19f049ea6fd1..922f5bbba76a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java @@ -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(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java index 2f240940954b..3284a9c75ad7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java @@ -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 { + @NotNull + @Override + PsiElement getReferenceNameElement(); + + @NotNull + @Override + String getReferenceName(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 4cb36793b0e8..2271338f4765 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -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 diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 0e0c1815b9b3..4c766a28ceac 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -499,7 +499,7 @@ public class PsiImplUtil { } } - public static void setQualifier(GrQualifiedReference ref, T newQualifier) { + public static void setQualifier(@NotNull GrQualifiedReference ref, @Nullable T newQualifier) { final T oldQualifier = ref.getQualifier(); final ASTNode node = ref.getNode(); final PsiElement refNameElement = ref.getReferenceNameElement(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java index bf084a6baf78..aa402bacbb95 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java @@ -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() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java index 611ddfd9c3ec..a591ed55c994 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java @@ -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) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java index 124fbd9f9994..f9a5b1c3ebd3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java @@ -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(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 0bde09c323aa..3b62d3cf674d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -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 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 results = new ArrayList(); + if (GrReferenceResolveUtil.resolveThisExpression(this, results)) { + return results.toArray(new GroovyResolveResult[results.size()]); + } + } + else if (nameType == GroovyTokenTypes.kSUPER) { + ArrayList results = new ArrayList(); + if (GrReferenceResolveUtil.resolveSuperExpression(this, results)) { + return results.toArray(new GroovyResolveResult[results.size()]); + } + } + EnumSet kinds = getParent() instanceof GrReferenceExpression ? ResolverProcessor.RESOLVE_KINDS_CLASS_PACKAGE @@ -213,11 +233,12 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl 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>() { @Override @@ -347,7 +368,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl 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 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 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; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java index 4d32c00f5a7d..61365ae5c007 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java @@ -76,7 +76,6 @@ public class GrSuperReferenceExpressionImpl extends GrThisSuperReferenceExpressi } public void accept(GroovyElementVisitor visitor) { - visitor.visitSuperExpression(this); } public String toString() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java index dbc5d6c81dc9..9e7a4ebeede3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java @@ -78,7 +78,6 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio } public void accept(GroovyElementVisitor visitor) { - visitor.visitThisExpression(this); } public String toString() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java index 73bf660b7c14..15e0ea7571b8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java @@ -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()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java index 1b974232bda8..2ad9ef29c14b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java @@ -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); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index d981a05bb719..23f75e30f470 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -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 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; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index eaa5f579cbf1..deb5acee0861 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -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); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java index 712bf183f0aa..83aeabdf0ea6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java @@ -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)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java index c23bd1bdf594..19dbd1bc2928 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java @@ -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 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)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java index b83555bf9b3f..512a239f81f6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java index fe4469a9f38f..657902baa56d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java @@ -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.empty_array(), substitutor); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java index d4de2c42e577..6badf51b5d3b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java @@ -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) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java index 9fff2760ea02..621dcf433952 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java @@ -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(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java index 3627c3b52566..6f6c08dbd4f0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java @@ -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)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java index c2811059540d..3f88bf883447 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java @@ -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 hasSuper = new Ref(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")); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java index 4e3dc84f7ba1..9a07f2b1eb5e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java @@ -104,7 +104,7 @@ public abstract class GrIntroduceHandlerBaseo(['']) ''') - def parameters = resolved.parameterList.parameters + assertInstanceOf(resolved, PsiMethod) + def parameters = (resolved as PsiMethod).parameterList.parameters assertEquals 'java.util.List', parameters[0].type.canonicalText } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy index 73dd4fdd2dfa..9581266c5499 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy @@ -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); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java index e143c274a388..a5efacf2f4bb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java @@ -190,6 +190,10 @@ public class GrIntroduceParameterTest extends LightCodeInsightFixtureTestCase { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, "field Test.i is not accessible from method XTest.n(). 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); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy index f53ac2d62f2b..bda23832691c 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy @@ -616,4 +616,30 @@ class Bar { checkResult("def 'import'() {}") } } + + void testConstructorAndSuper() { + myFixture.with { + configureByText(GroovyFileType.GROOVY_FILE_TYPE, '''\ +class Base { + def Base() {} +} +class Inheritor extends Base { + def Inheritor() { + super() + } +} +''') + renameElementAtCaret('Bassse') + checkResult('''\ +class Bassse { + def Bassse() {} +} +class Inheritor extends Bassse { + def Inheritor() { + super() + } +} +''') + } + } } diff --git a/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy b/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy index 275f3a1a0f73..7663247ad903 100644 --- a/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy +++ b/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy @@ -1,5 +1,5 @@ class X{ def foo() { - String.super.toString() + String.super.toString() } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy b/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy index a23fafece73a..04e89b5c7d6e 100644 --- a/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy +++ b/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy @@ -1,6 +1,6 @@ class X{ def foo(){ X x=new X(); - x.this.foo(); + x.this.foo(); } } \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/annotations/defAttribute.test b/plugins/groovy/testdata/parsing/groovy/annotations/defAttribute.test new file mode 100644 index 000000000000..4f193cc3b76a --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/annotations/defAttribute.test @@ -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') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test b/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test index 995e8b373e89..7f83251eae79 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test @@ -7,7 +7,7 @@ Groovy script PsiWhiteSpace(' ') Command arguments Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(final)('final') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test b/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test index b01bd613902d..19566887571b 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test @@ -32,7 +32,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'super' reference expression + Reference expression Reference expression PsiElement(identifier)('X') PsiElement(.)('.') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test b/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test index ee2cbdd35772..d0f8167d0be9 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test @@ -32,7 +32,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'super' reference expression + Reference expression PsiElement(super)('super') PsiElement(.)('.') PsiElement(identifier)('foo') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test b/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test index e163a558b800..65d2f390d8b4 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test @@ -32,7 +32,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'this' reference expression + Reference expression Reference expression PsiElement(identifier)('X') PsiElement(.)('.') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test b/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test index f8596b4da6ff..c784ae1d3506 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test @@ -34,7 +34,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(identifier)('doo') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test index 17b392c66fb5..40a8bf464ef4 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test @@ -32,7 +32,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test index b263c2526606..5a5ad21508a2 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test @@ -56,7 +56,7 @@ Groovy script PsiElement(;)(';') PsiWhiteSpace(' ') Method call - 'super' reference expression + Reference expression PsiElement(super)('super') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test index fb85bb8aaaca..4e93519e609a 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test @@ -53,7 +53,7 @@ Groovy script PsiWhiteSpace('\n ') Assignment expression Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(identifier)('value') @@ -90,7 +90,7 @@ Groovy script PsiElement(()('(') Additive expression Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(identifier)('value') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test index 0dccf897942e..8957bb76721c 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test @@ -34,7 +34,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'super' reference expression + Reference expression PsiElement(super)('super') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test index 3a7d3dfa2214..51ff31e0496c 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test @@ -32,7 +32,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test index 0dbc2d8ea427..3a81eb30921d 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test @@ -63,7 +63,7 @@ Groovy script Open block PsiElement({)('{') Method call - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test index 72e3ca82f323..6b71774722f6 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test @@ -39,7 +39,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test index c711c17da9ca..36a2c2dc5518 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test @@ -33,7 +33,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test index 8ecd734e6fb3..9fd9b58e4f3a 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test @@ -39,7 +39,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test index eea22f6ef80a..db38417f528c 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test @@ -43,7 +43,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test index f551a5148732..f1537c42f185 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test @@ -52,7 +52,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java index 31fe43caeb6c..28fa5574f185 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java @@ -1,5 +1,5 @@ public class Base extends groovy.lang.GroovyObjectSupport implements groovy.lang.GroovyObject { -public Base(java.lang.Object a) { +public Base(java.lang.Integer a) { } } public class Inheritor extends Base implements groovy.lang.GroovyObject { diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java index 34b1830d6ced..35e9c5a95f14 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java @@ -6,7 +6,7 @@ java.lang.String s = "a"; s.bar = 4; org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.bar = 5); org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, getProperty("bar")); -org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.getProperty("bar")); +org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.bar); } private static Value setProperty0(groovy.lang.GroovyObjectSupport propOwner, java.lang.String property, Value newValue) { diff --git a/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionAfter.groovy b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionAfter.groovy new file mode 100644 index 000000000000..01a70f6cbc26 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionAfter.groovy @@ -0,0 +1,2 @@ +final Upper.Foo foo = new Upper.Foo() +foo.abr(foo) \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionBefore.groovy b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionBefore.groovy new file mode 100644 index 000000000000..8a9bb09997b0 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionBefore.groovy @@ -0,0 +1 @@ +new Upper.Foo().abr() \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionMyClass.groovy b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionMyClass.groovy new file mode 100644 index 000000000000..bc1bb69d6b10 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionMyClass.groovy @@ -0,0 +1,9 @@ +class Upper { + class Foo { + def x = 4 + + def abr() { + print Foo.this.x + } + } +} \ No newline at end of file diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java index c1a2b112727a..37210de9ce84 100644 --- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java +++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java @@ -54,8 +54,11 @@ public interface MavenServerEmbedder extends Remote { @NotNull MavenServerExecutionResult execute(@NotNull File file, @NotNull Collection activeProfiles, - @NotNull List goals) throws RemoteException, - MavenServerProcessCanceledException; + @NotNull Collection inactiveProfiles, + @NotNull List goals, + @NotNull final List selectedProjects, + boolean alsoMake, + boolean alsoMakeDependents) throws RemoteException, MavenServerProcessCanceledException; void reset() throws RemoteException; diff --git a/plugins/maven/maven2-server-impl/lib-src/maven-embedder-1.1-SNAPSHOT-sources.jar b/plugins/maven/maven2-server-impl/lib-src/maven-embedder-1.1-SNAPSHOT-sources.jar deleted file mode 100644 index 041fce01bc86..000000000000 Binary files a/plugins/maven/maven2-server-impl/lib-src/maven-embedder-1.1-SNAPSHOT-sources.jar and /dev/null differ diff --git a/plugins/maven/maven2-server-impl/lib/maven-embedder-1.1-SNAPSHOT.jar b/plugins/maven/maven2-server-impl/lib/maven-embedder-1.1-SNAPSHOT.jar deleted file mode 100644 index c08b985459fb..000000000000 Binary files a/plugins/maven/maven2-server-impl/lib/maven-embedder-1.1-SNAPSHOT.jar and /dev/null differ diff --git a/plugins/maven/maven2-server-impl/maven2-server-impl.iml b/plugins/maven/maven2-server-impl/maven2-server-impl.iml index 364a132a931b..092e457efd1f 100644 --- a/plugins/maven/maven2-server-impl/maven2-server-impl.iml +++ b/plugins/maven/maven2-server-impl/maven2-server-impl.iml @@ -70,17 +70,6 @@ - - - - - - - - - - - diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java index 0bee080b8c84..cae29c345b98 100644 --- a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java @@ -327,13 +327,19 @@ public class Maven2ServerEmbedderImpl extends MavenRemoteObject implements Maven } @NotNull + @Override public MavenServerExecutionResult execute(@NotNull final File file, - @NotNull final Collection activeProfiles, - @NotNull final List goals) - throws MavenServerProcessCanceledException, RemoteException { + @NotNull final Collection activeProfiles, + @NotNull final Collection inactiveProfiles, + @NotNull final List goals, + @NotNull final List selectedProjects, + final boolean alsoMake, + final boolean alsoMakeDependents) throws RemoteException, MavenServerProcessCanceledException { return doExecute(new Executor() { public MavenServerExecutionResult execute() throws Exception { - MavenExecutionResult result = myImpl.execute(file, new ArrayList(activeProfiles), goals); + MavenExecutionResult result = myImpl + .execute(file, new ArrayList(activeProfiles), new ArrayList(inactiveProfiles), goals, selectedProjects, alsoMake, + alsoMakeDependents); return createExecutionResult(file, result, null); } }); diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/AbstractMavenLogger.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/AbstractMavenLogger.java new file mode 100644 index 000000000000..b166d1ea5d6b --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/AbstractMavenLogger.java @@ -0,0 +1,114 @@ +/* ========================================================================== + * Copyright 2006 Mevenide Team + * + * 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.maven.embedder; + +import org.codehaus.plexus.logging.Logger; + +public abstract class AbstractMavenLogger implements Logger { + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + private int myThreshold; + + private void doPrint(int level, String message, Throwable throwable) { + if (level < myThreshold) return; + + if (!message.endsWith(LINE_SEPARATOR)) { + message += LINE_SEPARATOR; + } + + printMessage(level, message, throwable); + } + + protected abstract void printMessage(int level, String message, Throwable throwable); + + public void debug(String string, Throwable throwable) { + doPrint(LEVEL_DEBUG, string, throwable); + } + + public void info(String string, Throwable throwable) { + doPrint(LEVEL_INFO, string, throwable); + } + + public void warn(String string, Throwable throwable) { + doPrint(LEVEL_WARN, string, throwable); + } + + public void error(String string, Throwable throwable) { + doPrint(LEVEL_ERROR, string, throwable); + } + + public void fatalError(String string, Throwable throwable) { + doPrint(LEVEL_FATAL, string, throwable); + } + + public void debug(String message) { + debug(message, null); + } + + public boolean isDebugEnabled() { + return getThreshold() <= LEVEL_DEBUG; + } + + public void info(String message) { + info(message, null); + } + + public boolean isInfoEnabled() { + return getThreshold() <= LEVEL_INFO; + } + + public void warn(String message) { + warn(message, null); + } + + public boolean isWarnEnabled() { + return getThreshold() <= LEVEL_WARN; + } + + public void error(String message) { + error(message, null); + } + + public boolean isErrorEnabled() { + return getThreshold() <= LEVEL_ERROR; + } + + public void fatalError(String message) { + fatalError(message, null); + } + + public boolean isFatalErrorEnabled() { + return getThreshold() <= LEVEL_FATAL; + } + + public void setThreshold(int threshold) { + this.myThreshold = threshold; + } + + public int getThreshold() { + return myThreshold; + } + + public Logger getChildLogger(String s) { + return null; + } + + public String getName() { + return toString(); + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/FieldAccessor.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/FieldAccessor.java new file mode 100644 index 000000000000..90255d1320df --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/FieldAccessor.java @@ -0,0 +1,54 @@ +/* + * 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.maven.embedder; + +import java.lang.reflect.Field; + +class FieldAccessor { + private volatile FIELD_TYPE myWagonManagerCache; + private final Class myHostClass; + private final Object myHost; + private final String myFieldName; + + public FieldAccessor(Class hostClass, T host, String fieldName) { + myHostClass = hostClass; + myHost = host; + myFieldName = fieldName; + } + + public FIELD_TYPE getField() { + if (myWagonManagerCache == null) { + Object value = getFieldValue(myHostClass, myFieldName, myHost); + //noinspection unchecked + myWagonManagerCache = (FIELD_TYPE)value; + } + return myWagonManagerCache; + } + + private Object getFieldValue(Class c, String fieldName, Object o) { + try { + Field f = c.getDeclaredField(fieldName); + f.setAccessible(true); + return f.get(o); + } + catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java new file mode 100644 index 000000000000..3926a3d1f030 --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java @@ -0,0 +1,596 @@ +/* + * 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.maven.embedder; + +import org.apache.maven.DefaultMaven; +import org.apache.maven.Maven; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.manager.DefaultWagonManager; +import org.apache.maven.artifact.manager.WagonManager; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; +import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; +import org.apache.maven.artifact.repository.DefaultArtifactRepository; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.artifact.resolver.*; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.ReactorManager; +import org.apache.maven.extension.ExtensionManager; +import org.apache.maven.model.Extension; +import org.apache.maven.model.Plugin; +import org.apache.maven.monitor.event.DefaultEventDispatcher; +import org.apache.maven.monitor.event.DefaultEventMonitor; +import org.apache.maven.monitor.event.EventDispatcher; +import org.apache.maven.plugin.PluginManager; +import org.apache.maven.profiles.DefaultProfileManager; +import org.apache.maven.profiles.ProfileManager; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectBuilder; +import org.apache.maven.project.ProjectBuilderConfiguration; +import org.apache.maven.project.interpolation.ModelInterpolationException; +import org.apache.maven.settings.*; +import org.codehaus.classworlds.ClassWorld; +import org.codehaus.plexus.DefaultPlexusContainer; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.PlexusContainerException; +import org.codehaus.plexus.component.repository.ComponentDescriptor; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.codehaus.plexus.logging.BaseLoggerManager; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.jetbrains.annotations.NotNull; +import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; +import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; + +public class MavenEmbedder { + private static final String PROP_MAVEN_HOME = "maven.home"; + + private final DefaultPlexusContainer myContainer; + private final Settings mySettings; + private final Logger myLogger; + private final MavenEmbedderSettings myEmbedderSettings; + private final ArtifactRepository myLocalRepository; + + private MavenEmbedder(@NotNull DefaultPlexusContainer container, + @NotNull Settings settings, + @NotNull Logger logger, + @NotNull MavenEmbedderSettings embedderSettings) { + myContainer = container; + mySettings = settings; + myLogger = logger; + myEmbedderSettings = embedderSettings; + myLocalRepository = createLocalRepository(embedderSettings); + + loadSettings(); + } + + private void loadSettings() { + // copied from DefaultMaven.resolveParameters + // copied because using original code spoils something in the container and configuration are get messed and not picked up. + WagonManager wagonManager = getComponent(WagonManager.class); + + wagonManager.setOnline(!mySettings.isOffline()); + + if (wagonManager instanceof DefaultWagonManager) { + ((DefaultWagonManager)wagonManager).setHttpUserAgent("Apache-Maven/2.2"); + } + + Proxy proxy = mySettings.getActiveProxy(); + if (proxy != null && proxy.getHost() != null) { + String pass = decrypt(proxy.getPassword()); + wagonManager.addProxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(), proxy.getUsername(), pass, proxy.getNonProxyHosts()); + } + + for (Object each : mySettings.getServers()) { + Server server = (Server)each; + + String passWord = decrypt(server.getPassword()); + String passPhrase = decrypt(server.getPassphrase()); + + wagonManager.addAuthenticationInfo(server.getId(), server.getUsername(), passWord, server.getPrivateKey(), passPhrase); + + wagonManager.addPermissionInfo(server.getId(), server.getFilePermissions(), server.getDirectoryPermissions()); + + if (server.getConfiguration() != null) { + wagonManager.addConfiguration(server.getId(), (Xpp3Dom)server.getConfiguration()); + } + } + + for (Object each : mySettings.getMirrors()) { + Mirror mirror = (Mirror)each; + if (mirror.getUrl() == null) continue; + wagonManager.addMirror(mirror.getId(), mirror.getMirrorOf(), mirror.getUrl()); + } + // end copied from DefaultMaven.resolveParameters + } + + private String decrypt(String pass) { + try { + pass = getComponent(SecDispatcher.class, "maven").decrypt(pass); + } + catch (SecDispatcherException e) { + MavenEmbedderLog.LOG.warn(e); + } + return pass; + } + + private ArtifactRepository createLocalRepository(MavenEmbedderSettings generalSettings) { + ArtifactRepositoryLayout layout = getComponent(ArtifactRepositoryLayout.class, "default"); + ArtifactRepositoryFactory factory = getComponent(ArtifactRepositoryFactory.class); + + String url = mySettings.getLocalRepository(); + if (!url.startsWith("file:")) url = "file://" + url; + + ArtifactRepository localRepository = new DefaultArtifactRepository("local", url, layout); + + boolean snapshotPolicySet = mySettings.isOffline(); + if (!snapshotPolicySet && generalSettings.getSnapshotUpdatePolicy() == MavenEmbedderSettings.UpdatePolicy.ALWAYS_UPDATE) { + factory.setGlobalUpdatePolicy(ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS); + } + factory.setGlobalChecksumPolicy(ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN); + + return localRepository; + } + + @NotNull + public ArtifactRepository getLocalRepository() { + return myLocalRepository; + } + + @NotNull + public File getLocalRepositoryFile() { + return new File(myLocalRepository.getBasedir()); + } + + public Settings getSettings() { + return mySettings; + } + + @NotNull + public MavenExecutionResult resolveProject(@NotNull final File file, @NotNull final List activeProfiles) { + return resolveProject(file, activeProfiles, Collections.emptyList()); + } + + @NotNull + public MavenExecutionResult resolveProject(@NotNull final File file, + @NotNull final List activeProfiles, + List listeners) { + MavenExecutionRequest request = createRequest(file, activeProfiles, Collections.emptyList(), Collections.emptyList()); + ProjectBuilderConfiguration config = request.getProjectBuilderConfiguration(); + + request.getGlobalProfileManager().loadSettingsProfiles(mySettings); + + ProfileManager globalProfileManager = request.getGlobalProfileManager(); + globalProfileManager.loadSettingsProfiles(request.getSettings()); + + List exceptions = new ArrayList(); + MavenProject project = null; + try { + // copied from DefaultMavenProjectBuilder.buildWithDependencies + MavenProjectBuilder builder = getComponent(MavenProjectBuilder.class); + project = builder.build(new File(file.getPath()), config); + builder.calculateConcreteState(project, config, false); + + // copied from DefaultLifecycleExecutor.execute + findExtensions(project); + // end copied from DefaultLifecycleExecutor.execute + + Artifact projectArtifact = project.getArtifact(); + Map managedVersions = project.getManagedVersionMap(); + ArtifactMetadataSource metadataSource = getComponent(ArtifactMetadataSource.class); + project.setDependencyArtifacts(project.createArtifacts(getComponent(ArtifactFactory.class), null, null)); + + ArtifactResolver resolver = getComponent(ArtifactResolver.class); + ArtifactResolutionResult result = resolver + .resolveTransitively(project.getDependencyArtifacts(), projectArtifact, managedVersions, myLocalRepository, + project.getRemoteArtifactRepositories(), metadataSource, null, listeners); + project.setArtifacts(result.getArtifacts()); + // end copied from DefaultMavenProjectBuilder.buildWithDependencies + } + catch (Exception e) { + return handleException(e); + } + + return new MavenExecutionResult(project, exceptions); + } + + private void findExtensions(MavenProject project) { + // end copied from DefaultLifecycleExecutor.findExtensions + ExtensionManager extensionManager = getComponent(ExtensionManager.class); + for (Object each : project.getBuildExtensions()) { + try { + extensionManager.addExtension((Extension)each, project, myLocalRepository); + } + catch (PlexusContainerException e) { + MavenEmbedderLog.LOG.error(e); + } + catch (ArtifactResolutionException e) { + MavenEmbedderLog.LOG.error(e); + } + catch (ArtifactNotFoundException e) { + MavenEmbedderLog.LOG.error(e); + } + } + extensionManager.registerWagons(); + + Map handlers = findArtifactTypeHandlers(project); + getComponent(ArtifactHandlerManager.class).addHandlers(handlers); + } + + @SuppressWarnings({"unchecked"}) + private Map findArtifactTypeHandlers(MavenProject project) { + // end copied from DefaultLifecycleExecutor.findExtensions + Map result = new HashMap(); + for (Object each : project.getBuildPlugins()) { + Plugin eachPlugin = (Plugin)each; + + if (eachPlugin.isExtensions()) { + try { + PluginManager pluginManager = getComponent(PluginManager.class); + pluginManager.verifyPlugin(eachPlugin, project, mySettings, myLocalRepository); + result.putAll(pluginManager.getPluginComponents(eachPlugin, ArtifactHandler.ROLE)); + } + catch (Exception e) { + MavenEmbedderLog.LOG.info(e); + continue; + } + + for (Object o : result.values()) { + ArtifactHandler handler = (ArtifactHandler)o; + if (project.getPackaging().equals(handler.getPackaging())) { + project.getArtifact().setArtifactHandler(handler); + } + } + } + } + return result; + } + + public void resolve(@NotNull final Artifact artifact, @NotNull final List repos) + throws ArtifactResolutionException, ArtifactNotFoundException { + getComponent(ArtifactResolver.class).resolve(artifact, repos, myLocalRepository); + } + + public Set resolveTransitively(@NotNull Set toResolve, @NotNull List repos) + throws ArtifactResolutionException, ArtifactNotFoundException { + Artifact project = getComponent(ArtifactFactory.class).createBuildArtifact("temp", "temp", "666", "pom"); + + return getComponent(ArtifactResolver.class) + .resolveTransitively(toResolve, project, Collections.EMPTY_MAP, myLocalRepository, repos, getComponent(ArtifactMetadataSource.class)) + .getArtifacts(); + } + + @NotNull + public MavenExecutionResult execute(@NotNull final File file, + @NotNull final List activeProfiles, + @NotNull final List inactiveProfiles, + @NotNull final List goals, + @NotNull final List selectedProjects, + boolean alsoMake, + boolean alsoMakeDependents) { + try { + MavenExecutionRequest request = createRequest(file, activeProfiles, inactiveProfiles, goals); + + if (!selectedProjects.isEmpty()) { + request.setRecursive(true); + request.setSelectedProjects(selectedProjects); + if (alsoMake && alsoMakeDependents) { + request.setMakeBehavior(ReactorManager.MAKE_BOTH_MODE); + } + else if (alsoMake) { + request.setMakeBehavior(ReactorManager.MAKE_MODE); + } + else if (alsoMakeDependents) { + request.setMakeBehavior(ReactorManager.MAKE_DEPENDENTS_MODE); + } + } + + Maven maven = getComponent(Maven.class); + Method method = maven.getClass().getDeclaredMethod("doExecute", MavenExecutionRequest.class, EventDispatcher.class); + method.setAccessible(true); + ReactorManager reactor = (ReactorManager)method.invoke(maven, request, request.getEventDispatcher()); + return new MavenExecutionResult(reactor.getTopLevelProject(), Collections.emptyList()); + } + catch (InvocationTargetException e) { + return handleException(e.getTargetException()); + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); // should never happen + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); // should never happen + } + } + + @NotNull + public MavenExecutionResult readProjectWithModules(@NotNull final File file, List activeProfiles, List inactiveProfiles) { + MavenExecutionRequest request = createRequest(file, activeProfiles, inactiveProfiles, Collections.emptyList()); + request.getGlobalProfileManager().loadSettingsProfiles(mySettings); + request.setRecursive(true); + + return readProject(request); + } + + @NotNull + private MavenExecutionResult readProject(@NotNull final MavenExecutionRequest request) { + ProfileManager globalProfileManager = request.getGlobalProfileManager(); + globalProfileManager.loadSettingsProfiles(request.getSettings()); + + MavenProject rootProject = null; + final List exceptions = new ArrayList(); + Object result = null; + try { + final File pomFile = new File(request.getPomFile()); + if (!pomFile.exists()) { + throw new FileNotFoundException("File doesn't exist: " + pomFile.getPath()); + } + + final Method getProjectsMethod = DefaultMaven.class.getDeclaredMethod("getProjects", MavenExecutionRequest.class); + getProjectsMethod.setAccessible(true); + Maven maven = getComponent(Maven.class); + result = getProjectsMethod.invoke(maven, request); + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + return handleException(e.getTargetException()); + } + catch (Exception e) { + return handleException(e); + } + + if (result != null) { + MavenProjectBuilder builder = getComponent(MavenProjectBuilder.class); + for (Object p : (List)result) { + MavenProject project = (MavenProject)p; + try { + builder.calculateConcreteState(project, request.getProjectBuilderConfiguration(), false); + } + catch (ModelInterpolationException e) { + exceptions.add(e); + } + + if (project.isExecutionRoot()) { + rootProject = project; + } + } + + if (rootProject == null && exceptions.isEmpty()) { + throw new RuntimeException("Could't build project for unknown reason"); + } + } + + return new MavenExecutionResult(rootProject, exceptions); + } + + @NotNull + public MavenExecutionResult readProject(@NotNull final File file, + @NotNull final List activeProfiles, + @NotNull final List inactiveProfiles) { + MavenExecutionRequest request = createRequest(file, activeProfiles, inactiveProfiles, Collections.emptyList()); + request.getGlobalProfileManager().loadSettingsProfiles(mySettings); + request.setRecursive(false); + + return readProject(request); + } + + private MavenExecutionRequest createRequest(File file, List activeProfiles, List inactiveProfiles, List goals) { + Properties executionProperties = myEmbedderSettings.getProperties(); + if (executionProperties == null) executionProperties = new Properties(); + + DefaultEventDispatcher dispatcher = new DefaultEventDispatcher(); + dispatcher.addEventMonitor(new DefaultEventMonitor(myLogger)); + + // subclassing because in DefaultMavenExecutionRequest field isRecursive is always false + MavenExecutionRequest result = new DefaultMavenExecutionRequest(myLocalRepository, mySettings, dispatcher, goals, file.getParent(), + createProfileManager(activeProfiles, inactiveProfiles, + executionProperties), executionProperties, + new Properties(), true) { + private boolean myIsRecursive; + + @Override + public boolean isRecursive() { + return myIsRecursive; + } + + @Override + public void setRecursive(final boolean recursive) { + myIsRecursive = recursive; + } + }; + + result.setPomFile(file.getPath()); + result.setRecursive(myEmbedderSettings.isRecursive()); + + return result; + } + + private MavenExecutionResult handleException(Throwable e) { + if (e instanceof RuntimeException) throw (RuntimeException)e; + if (e instanceof Error) throw (Error)e; + + return new MavenExecutionResult(null, Collections.singletonList((Exception)e)); + } + + private ProfileManager createProfileManager(List activeProfiles, List inactiveProfiles, Properties executionProperties) { + ProfileManager profileManager = new DefaultProfileManager(getContainer(), executionProperties); + profileManager.explicitlyActivate(activeProfiles); + profileManager.explicitlyDeactivate(inactiveProfiles); + return profileManager; + } + + @SuppressWarnings({"unchecked"}) + public T getComponent(Class clazz) { + try { + return (T)getContainer().lookup(clazz.getName()); + } + catch (ComponentLookupException e) { + throw new RuntimeException(e); + } + } + + @SuppressWarnings({"unchecked"}) + public T getComponent(Class clazz, String roleHint) { + try { + return (T)getContainer().lookup(clazz.getName(), roleHint); + } + catch (ComponentLookupException e) { + throw new RuntimeException(e); + } + } + + public PlexusContainer getContainer() { + return myContainer; + } + + public void release() { + releaseResolverThreadExecutor(); + myContainer.dispose(); + } + + private void releaseResolverThreadExecutor() { + ArtifactResolver resolver = getComponent(ArtifactResolver.class); + @SuppressWarnings({"unchecked"}) FieldAccessor pool = new FieldAccessor(DefaultArtifactResolver.class, resolver, "resolveArtifactPool"); + try { + final Object threadPool = pool.getField(); // an instance of a hidden copy of ThreadPoolExecutor + threadPool.getClass().getMethod("shutdown").invoke(threadPool); + } + catch (RuntimeException e) { + throw e; + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + @NotNull + public static MavenEmbedder create(@NotNull final MavenEmbedderSettings embedderSettings) { + @NotNull final Logger logger = getLogger(embedderSettings); + + DefaultPlexusContainer container = new DefaultPlexusContainer(); + container.setClassWorld(new ClassWorld("plexus.core", embedderSettings.getClass().getClassLoader())); + container.setLoggerManager(new BaseLoggerManager() { + @Override + protected Logger createLogger(final String s) { + return logger; + } + }); + + try { + container.initialize(); + container.start(); + } + catch (PlexusContainerException e) { + MavenEmbedderLog.LOG.error(e); + throw new RuntimeException(e); + } + + final PlexusComponentConfigurator configurator = embedderSettings.getConfigurator(); + if (configurator != null) { + configurator.configureComponents(container); + } + + File mavenHome = embedderSettings.getMavenHome(); + if (mavenHome != null) { + System.setProperty(PROP_MAVEN_HOME, mavenHome.getPath()); + } + + Settings nativeSettings = buildSettings(container, embedderSettings); + + return new MavenEmbedder(container, nativeSettings, logger, embedderSettings); + } + + @NotNull + private static Logger getLogger(@NotNull final MavenEmbedderSettings embedderSettings) { + final Logger logger = embedderSettings.getLogger(); + return logger != null ? logger : new NullMavenLogger(); + } + + public static Settings buildSettings(PlexusContainer container, MavenEmbedderSettings embedderSettings) { + File file = embedderSettings.getGlobalSettingsFile(); + if (file != null) { + System.setProperty(MavenSettingsBuilder.ALT_GLOBAL_SETTINGS_XML_LOCATION, file.getPath()); + } + + Settings settings = null; + + try { + MavenSettingsBuilder builder = (MavenSettingsBuilder)container.lookup(MavenSettingsBuilder.ROLE); + + File userSettingsFile = embedderSettings.getUserSettingsFile(); + if (userSettingsFile != null && userSettingsFile.exists() && !userSettingsFile.isDirectory()) { + settings = builder.buildSettings(userSettingsFile, false); + } + + if (settings == null) { + settings = builder.buildSettings(); + } + } + catch (ComponentLookupException e) { + MavenEmbedderLog.LOG.error(e); + } + catch (IOException e) { + MavenEmbedderLog.LOG.warn(e); + } + catch (XmlPullParserException e) { + MavenEmbedderLog.LOG.warn(e); + } + + if (settings == null) { + settings = new Settings(); + } + + if (embedderSettings.getLocalRepository() != null) { + settings.setLocalRepository(embedderSettings.getLocalRepository().getPath()); + } + if (settings.getLocalRepository() == null) { + settings.setLocalRepository(System.getProperty("user.home") + "/.m2/repository"); + } + + settings.setOffline(embedderSettings.isWorkOffline()); + settings.setInteractiveMode(false); + settings.setUsePluginRegistry(embedderSettings.isUsePluginRegistry()); + + RuntimeInfo runtimeInfo = new RuntimeInfo(settings); + runtimeInfo.setPluginUpdateOverride(embedderSettings.getPluginUpdatePolicy() == MavenEmbedderSettings.UpdatePolicy.ALWAYS_UPDATE); + settings.setRuntimeInfo(runtimeInfo); + + return settings; + } + + public static void setImplementation(PlexusContainer container, Class componentClass, Class implementationClass) { + ComponentDescriptor d = container.getComponentDescriptor(componentClass.getName()); + d.setImplementation(implementationClass.getName()); + } +} + diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLog.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLog.java new file mode 100644 index 000000000000..78cb538f928b --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLog.java @@ -0,0 +1,76 @@ +/* + * 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.maven.embedder; + +import org.jetbrains.annotations.NotNull; + +public class MavenEmbedderLog { + public static final MavenEmbedderLogger LOG = new MavenEmbedderLogger() { + public void debug(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.debug(msg); + } + + public void debug(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.debug(msg, e); + } + + public void debug(final Throwable e) { + if (ourDelegate != null) ourDelegate.debug(e); + } + + public void info(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.info(msg); + } + + public void info(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.info(msg, e); + } + + public void info(final Throwable e) { + if (ourDelegate != null) ourDelegate.info(e); + } + + public void warn(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.warn(msg); + } + + public void warn(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.warn(msg, e); + } + + public void warn(final Throwable e) { + if (ourDelegate != null) ourDelegate.warn(e); + } + + public void error(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.error(msg); + } + + public void error(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.error(msg, e); + } + + public void error(final Throwable e) { + if (ourDelegate != null) ourDelegate.error(e); + } + }; + + private static MavenEmbedderLogger ourDelegate = null; + + public void setLogger(@NotNull final MavenEmbedderLogger logger) { + ourDelegate = logger; + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLogger.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLogger.java new file mode 100644 index 000000000000..8205236b2b69 --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLogger.java @@ -0,0 +1,31 @@ +package org.jetbrains.maven.embedder; + +/** + * @author Sergey.Anchipolevsky + * Date: 27.01.2010 + */ +public interface MavenEmbedderLogger { + void debug(CharSequence msg); + + void debug(CharSequence msg, Throwable e); + + void debug(Throwable e); + + void info(CharSequence msg); + + void info(CharSequence msg, Throwable e); + + void info(Throwable e); + + void warn(CharSequence msg); + + void warn(CharSequence msg, Throwable e); + + void warn(Throwable e); + + void error(CharSequence msg); + + void error(CharSequence msg, Throwable e); + + void error(Throwable e); +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderSettings.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderSettings.java new file mode 100644 index 000000000000..0e9c51c3c083 --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderSettings.java @@ -0,0 +1,151 @@ +/* + * 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.maven.embedder; + +import org.codehaus.plexus.logging.Logger; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.Properties; + +public class MavenEmbedderSettings { + public enum UpdatePolicy { + ALWAYS_UPDATE, DO_NOT_UPDATE + } + + private boolean workOffline = false; + private boolean isRecursive = true; + private File mavenHome; + private File userSettingsFile; + private File globalSettingsFile; + private File localRepository; + private boolean usePluginRegistry = false; + private UpdatePolicy snapshotUpdatePolicy = UpdatePolicy.ALWAYS_UPDATE; + private UpdatePolicy pluginUpdatePolicy = UpdatePolicy.DO_NOT_UPDATE; + private Properties myProperties; + + @Nullable + private Logger myLogger; + @Nullable + private PlexusComponentConfigurator myConfigurator; + + public boolean isWorkOffline() { + return workOffline; + } + + public void setWorkOffline(boolean workOffline) { + this.workOffline = workOffline; + } + + public boolean isRecursive() { + return isRecursive; + } + + public void setRecursive(boolean recursive) { + isRecursive = recursive; + } + + @Nullable + public File getMavenHome() { + return mavenHome; + } + + public void setMavenHome(@Nullable File mavenHome) { + this.mavenHome = mavenHome; + } + + @Nullable + public File getUserSettingsFile() { + return userSettingsFile; + } + + public void setUserSettingsFile(@Nullable File userSettingsFile) { + this.userSettingsFile = userSettingsFile; + } + + @Nullable + public File getGlobalSettingsFile() { + return globalSettingsFile; + } + + public void setGlobalSettingsFile(@Nullable File globalSettingsFile) { + this.globalSettingsFile = globalSettingsFile; + } + + @Nullable + public File getLocalRepository() { + return localRepository; + } + + public void setLocalRepository(@Nullable File localRepository) { + this.localRepository = localRepository; + } + + public boolean isUsePluginRegistry() { + return usePluginRegistry; + } + + public void setUsePluginRegistry(boolean usePluginRegistry) { + this.usePluginRegistry = usePluginRegistry; + } + + @NotNull + public UpdatePolicy getPluginUpdatePolicy() { + return pluginUpdatePolicy; + } + + public void setPluginUpdatePolicy(@Nullable UpdatePolicy value) { + this.pluginUpdatePolicy = value; + } + + @NotNull + public UpdatePolicy getSnapshotUpdatePolicy() { + return snapshotUpdatePolicy; + } + + public void setSnapshotUpdatePolicy(@Nullable UpdatePolicy value) { + this.snapshotUpdatePolicy = value; + } + + @Nullable + public Properties getProperties() { + return myProperties; + } + + public void setProperties(@Nullable Properties properties) { + myProperties = properties; + } + + @Nullable + public Logger getLogger() { + return myLogger; + } + + public void setLogger(@Nullable final Logger logger) { + myLogger = logger; + } + + + public void setConfigurator(@Nullable final PlexusComponentConfigurator configurator) { + myConfigurator = configurator; + } + + @Nullable + public PlexusComponentConfigurator getConfigurator() { + return myConfigurator; + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenExecutionResult.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenExecutionResult.java new file mode 100644 index 000000000000..bef95fd1369d --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenExecutionResult.java @@ -0,0 +1,44 @@ +/* + * 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.maven.embedder; + +import org.apache.maven.project.MavenProject; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MavenExecutionResult { + private final MavenProject myMavenProject; + private final List myExceptions; + + public MavenExecutionResult(@Nullable MavenProject mavenProject, List exceptions) { + myMavenProject = mavenProject; + myExceptions = exceptions; + } + + @Nullable + public MavenProject getMavenProject() { + return myMavenProject; + } + + public List getExceptions() { + return myExceptions; + } + + public boolean hasExceptions() { + return !myExceptions.isEmpty(); + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/NullMavenLogger.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/NullMavenLogger.java new file mode 100644 index 000000000000..17aea9782d5f --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/NullMavenLogger.java @@ -0,0 +1,12 @@ +package org.jetbrains.maven.embedder; + +/** + * @author Sergey.Anchipolevsky + * Date: 28.01.2010 + */ +class NullMavenLogger extends AbstractMavenLogger { + @Override + protected void printMessage(final int level, final String message, final Throwable throwable) { + // do nothing + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/PlexusComponentConfigurator.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/PlexusComponentConfigurator.java new file mode 100644 index 000000000000..3dc69e083c5a --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/PlexusComponentConfigurator.java @@ -0,0 +1,13 @@ +package org.jetbrains.maven.embedder; + +import org.codehaus.plexus.PlexusContainer; +import org.jetbrains.annotations.NotNull; + +/** + * @author Sergey.Anchipolevsky + * Date: 21.09.2009 + */ +public interface PlexusComponentConfigurator { + void configureComponents(@NotNull PlexusContainer container); + +} diff --git a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java index f660a53c502d..c76a98c02d97 100644 --- a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java +++ b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java @@ -571,8 +571,13 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven @NotNull @Override - public MavenServerExecutionResult execute(@NotNull File file, @NotNull Collection activeProfiles, @NotNull List goals) - throws RemoteException, MavenServerProcessCanceledException { + public MavenServerExecutionResult execute(@NotNull File file, + @NotNull Collection activeProfiles, + @NotNull Collection inactiveProfiles, + @NotNull List goals, + @NotNull List selectedProjects, + boolean alsoMake, + boolean alsoMakeDependents) throws RemoteException, MavenServerProcessCanceledException { throw new UnsupportedOperationException(); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java index 96ed1cff0bcd..6a90cc88bbb7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java @@ -918,6 +918,33 @@ public class MavenProjectsTree { } } + public MavenProject findRootProject(@NotNull MavenProject project) { + readLock(); + try { + MavenProject rootProject = project; + while (true) { + MavenProject aggregator = myModuleToAggregatorMapping.get(project); + if (aggregator == null) { + return rootProject; + } + rootProject = aggregator; + } + } + finally { + readUnlock(); + } + } + + public boolean isRootProject(@NotNull MavenProject project) { + readLock(); + try { + return myModuleToAggregatorMapping.get(project) == null; + } + finally { + readUnlock(); + } + } + public List getModules(MavenProject aggregator) { readLock(); try { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java index 520c3d9c4f76..3686d6f7c0e7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java @@ -157,7 +157,26 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper() { @Override public MavenServerExecutionResult execute() throws RemoteException, MavenServerProcessCanceledException { - return getOrCreateWrappee().execute(new File(file.getPath()), activeProfiles, goals); + return getOrCreateWrappee() + .execute(new File(file.getPath()), activeProfiles, Collections.emptyList(), goals, Collections.emptyList(), false, + false); + } + }); + } + + @NotNull + public MavenServerExecutionResult execute(@NotNull final VirtualFile file, + @NotNull final Collection activeProfiles, + @NotNull final Collection inactiveProfiles, + @NotNull final List goals, + @NotNull final List selectedProjects, + final boolean alsoMake, + final boolean alsoMakeDependents) throws MavenProcessCanceledException { + return perform(new RetriableCancelable() { + @Override + public MavenServerExecutionResult execute() throws RemoteException, MavenServerProcessCanceledException { + return getOrCreateWrappee() + .execute(new File(file.getPath()), activeProfiles, inactiveProfiles, goals, selectedProjects, alsoMake, alsoMakeDependents); } }); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java index 5667f41a08e7..989ac869e27d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java @@ -9,7 +9,9 @@ import com.intellij.tasks.impl.BaseRepositoryImpl; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.Tag; import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -26,6 +28,8 @@ public class GenericWebRepository extends BaseRepositoryImpl { private String myTasksListURL = ""; private String myTaskPattern = ""; private String myLoginURL = ""; + private String myLoginMethodType = GenericWebRepositoryEditor.GET; + private String myGetTasksMethodType = GenericWebRepositoryEditor.GET; final static String SERVER_URL_PLACEHOLDER = "{serverUrl}"; final static String USERNAME_PLACEHOLDER = "{username}"; @@ -33,7 +37,10 @@ public class GenericWebRepository extends BaseRepositoryImpl { final static String ID_PLACEHOLDER = "{id}"; final static String SUMMARY_PLACEHOLDER = "{summary}"; final static String QUERY_PLACEHOLDER = "{query}"; + final static String MAX_COUNT_PLACEHOLDER = "{count}"; + //todo final static String DESCRIPTION_PLACEHOLDER = "{description}"; + //todo final static String PAGE_PLACEHOLDER = "{page}"; @SuppressWarnings({"UnusedDeclaration"}) @@ -49,6 +56,8 @@ public class GenericWebRepository extends BaseRepositoryImpl { myTasksListURL = other.getTasksListURL(); myTaskPattern = other.getTaskPattern(); myLoginURL = other.getLoginURL(); + myLoginMethodType = other.getLoginMethodType(); + myGetTasksMethodType = other.getGetTasksMethodType(); } @Override @@ -57,10 +66,16 @@ public class GenericWebRepository extends BaseRepositoryImpl { if (!isLoginAnonymously()) login(httpClient); - final GetMethod getMethod = new GetMethod(getFullTasksUrl(query != null ? query : "")); - httpClient.executeMethod(getMethod); - if (getMethod.getStatusCode() != 200) throw new Exception("Cannot get tasks: HTTP status code " + getMethod.getStatusCode()); - final String response = getMethod.getResponseBodyAsString(Integer.MAX_VALUE); + final List placeholders = getPlaceholders(myTaskPattern); + if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) { + throw new Exception("Incorrect Task Pattern"); + } + + //todo add possibility to select method type + final HttpMethod method = getTaskListsMethod(query != null ? query : "", max); + httpClient.executeMethod(method); + if (method.getStatusCode() != 200) throw new Exception("Cannot get tasks: HTTP status code " + method.getStatusCode()); + final String response = method.getResponseBodyAsString(); final String taskPatternWithoutPlaceholders = myTaskPattern.replaceAll("\\{.+?\\}", ""); Matcher matcher = Pattern @@ -68,11 +83,6 @@ public class GenericWebRepository extends BaseRepositoryImpl { Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ) .matcher(response); - final List placeholders = getPlaceholders(myTaskPattern); - if (matcher.groupCount() != 2 || !placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) { - throw new Exception("Incorrect Task Pattern"); - } - List tasks = new ArrayList(); while (matcher.find()) { final String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1); @@ -86,12 +96,42 @@ public class GenericWebRepository extends BaseRepositoryImpl { return tasks.toArray(new Task[tasks.size()]); } + private HttpMethod getTaskListsMethod(final String query, final int max) { + String requestUrl = getFullTasksUrl(query, max); + return GenericWebRepositoryEditor.GET.equals(myGetTasksMethodType) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl); + } + private void login(final HttpClient httpClient) throws Exception { - final GetMethod method = new GetMethod(getFullLoginUrl()); + final HttpMethod method = getLoginMethod(); httpClient.executeMethod(method); if (method.getStatusCode() != 200) throw new Exception("Cannot login: HTTP status code " + method.getStatusCode()); } + private HttpMethod getLoginMethod() { + String requestUrl = getFullLoginUrl(); + return GenericWebRepositoryEditor.GET.equals(myLoginMethodType) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl); + } + + private static HttpMethod getPostMethodFromURL(final String requestUrl) { + int n = requestUrl.indexOf('?'); + if (n == -1) { + return new PostMethod(requestUrl); + } + + PostMethod postMethod = new PostMethod(requestUrl.substring(0, n)); + n = requestUrl.indexOf('?'); + String[] requestParams = requestUrl.substring(n + 1).split("&"); + for (String requestParam : requestParams) { + String[] nv = requestParam.split("="); + if (nv.length == 1) { + postMethod.addParameter(nv[0], ""); + } else { + postMethod.addParameter(nv[0], nv[1]); + } + } + return postMethod; + } + private static List getPlaceholders(String value) { if (value == null) { return ContainerUtil.emptyList(); @@ -105,21 +145,18 @@ public class GenericWebRepository extends BaseRepositoryImpl { return vars; } - private String getFullTasksUrl(final String query) { + private String getFullTasksUrl(final String query, final int max) { return getTasksListURL() - .replaceAll(placeholder2regexp(SERVER_URL_PLACEHOLDER), getUrl()) - .replaceAll(placeholder2regexp(QUERY_PLACEHOLDER), query); + .replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl()) + .replaceAll(Pattern.quote(QUERY_PLACEHOLDER), encodeUrl(query)) + .replaceAll(Pattern.quote(MAX_COUNT_PLACEHOLDER), String.valueOf(max)); } private String getFullLoginUrl() { return getLoginURL() - .replaceAll(placeholder2regexp(SERVER_URL_PLACEHOLDER), getUrl()) - .replaceAll(placeholder2regexp(USERNAME_PLACEHOLDER), getUsername()) - .replaceAll(placeholder2regexp(PASSWORD_PLACEHOLDER), getPassword()); - } - - private static String placeholder2regexp(String placeholder) { - return placeholder.replaceAll("\\{", "\\\\{"); + .replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl()) + .replaceAll(Pattern.quote(USERNAME_PLACEHOLDER), encodeUrl(getUsername())) + .replaceAll(Pattern.quote(PASSWORD_PLACEHOLDER), encodeUrl(getPassword())); } @Nullable @@ -158,6 +195,8 @@ public class GenericWebRepository extends BaseRepositoryImpl { if (!Comparing.equal(getTasksListURL(), that.getTasksListURL())) return false; if (!Comparing.equal(getTaskPattern(), that.getTaskPattern())) return false; if (!Comparing.equal(getLoginURL(), that.getLoginURL())) return false; + if (!Comparing.equal(getLoginMethodType(), that.getLoginMethodType())) return false; + if (!Comparing.equal(getGetTasksMethodType(), that.getGetTasksMethodType())) return false; return true; } @@ -184,4 +223,20 @@ public class GenericWebRepository extends BaseRepositoryImpl { public void setLoginURL(final String loginURL) { myLoginURL = loginURL; } + + public void setLoginMethodType(final String loginMethodType) { + myLoginMethodType = loginMethodType; + } + + public void setGetTasksMethodType(final String getTasksMethodType) { + myGetTasksMethodType = getTasksMethodType; + } + + public String getLoginMethodType() { + return myLoginMethodType; + } + + public String getGetTasksMethodType() { + return myGetTasksMethodType; + } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java index 6e476417564f..ab9119779fc3 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java @@ -1,41 +1,52 @@ package com.intellij.tasks.generic; +import com.intellij.ide.highlighter.HtmlFileType; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; import com.intellij.tasks.config.BaseRepositoryEditor; import com.intellij.ui.TextFieldWithAutoCompletion; +import com.intellij.ui.TextFieldWithAutoCompletionContributor; import com.intellij.ui.components.JBLabel; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.FormBuilder; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; import static com.intellij.tasks.generic.GenericWebRepository.*; +import static com.intellij.ui.TextFieldWithAutoCompletion.StringsCompletionProvider; /** * User: Evgeny.Zakrevsky * Date: 10/4/12 */ public class GenericWebRepositoryEditor extends BaseRepositoryEditor { + public static final String POST = "POST"; + public static final String GET = "GET"; private JBLabel myTasksListURLLabel; private JBLabel myTaskPatternLabel; private TextFieldWithAutoCompletion myTasksListURLText; - private TextFieldWithAutoCompletion myTaskPatternText; + private Editor myTaskPatternText; private JBLabel myLoginURLLabel; private TextFieldWithAutoCompletion myLoginURLText; + private ComboBox myLoginMethodType; + private ComboBox myGetTasksMethodType; public GenericWebRepositoryEditor(final Project project, final GenericWebRepository repository, final Consumer changeListener) { super(project, repository, changeListener); - myUrlLabel.setText("{serverUrl}:"); - myUsernameLabel.setText("{username}:"); - myPasswordLabel.setText("{password}:"); + myUrlLabel.setText("Server URL"); } @Override @@ -43,13 +54,16 @@ public class GenericWebRepositoryEditor extends BaseRepositoryEditor completionList1 = ContainerUtil.newArrayList(SERVER_URL_PLACEHOLDER, QUERY_PLACEHOLDER, MAX_COUNT_PLACEHOLDER); + myTasksListURLText = TextFieldWithAutoCompletion.create(myProject, completionList1, null, false, myRepository.getTasksListURL()); installListener(myTasksListURLText.getDocument()); + myGetTasksMethodType = new ComboBox(new String[]{GET, POST}, -1); + myGetTasksMethodType.setSelectedItem(myRepository.getGetTasksMethodType()); + installListener(myGetTasksMethodType); + JPanel tasksPanel = new JPanel(new BorderLayout(UIUtil.DEFAULT_HGAP, UIUtil.DEFAULT_VGAP)); + tasksPanel.add(myTasksListURLText, BorderLayout.CENTER); + tasksPanel.add(myGetTasksMethodType, BorderLayout.EAST); myTaskPatternLabel = new JBLabel("Task Pattern:", SwingConstants.RIGHT); - myTaskPatternText = - TextFieldWithAutoCompletion - .create(myProject, ContainerUtil.newArrayList("({id}.+?)", "({summary}.+?)"), null, false, myRepository.getTaskPattern()); - installListener(myTaskPatternText.getDocument()); + final Document document = EditorFactory.getInstance().createDocument(myRepository.getTaskPattern()); + myTaskPatternText = EditorFactory.getInstance().createEditor(document, myProject, HtmlFileType.INSTANCE, false); + final ArrayList completionList2 = ContainerUtil.newArrayList("({id}.+?)", "({summary}.+?)"); + TextFieldWithAutoCompletionContributor + .installCompletion(document, myProject, new StringsCompletionProvider(completionList2, null), true); + installListener(document); + myTaskPatternText.getSettings().setLineMarkerAreaShown(false); + myTaskPatternText.getSettings().setFoldingOutlineShown(false); + //todo correct resizing + //todo completion + //todo completion without whitespace before cursor String useCompletionText = ". Use " + KeymapUtil @@ -79,25 +112,20 @@ public class GenericWebRepositoryEditor extends BaseRepositoryEditorAvailable placeholders: " + SERVER_URL_PLACEHOLDER + ", " + USERNAME_PLACEHOLDER + ", " + PASSWORD_PLACEHOLDER + + useCompletionText + "") + .addLabeledComponent(myTasksListURLLabel, tasksPanel) + .addTooltip( + "Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + MAX_COUNT_PLACEHOLDER + ", " + QUERY_PLACEHOLDER + + " (use for faster tasks search)" + useCompletionText + "") + .addLabeledComponent(myTaskPatternLabel, myTaskPatternText.getComponent()) + .addTooltip( + "Task pattern should be a regexp with two matching groups: ({id}.+?) and ({summary}.+?)" + useCompletionText + "") .getPanel(); } - @Override - public void dispose() { - super.dispose(); - if (myTasksListURLText != null && myTasksListURLText.getEditor() != null) - EditorFactory.getInstance().releaseEditor(myTasksListURLText.getEditor()); - if (myLoginURLText.getEditor() != null) EditorFactory.getInstance().releaseEditor(myLoginURLText.getEditor()); - if (myTaskPatternText.getEditor() != null) EditorFactory.getInstance().releaseEditor(myTaskPatternText.getEditor()); - } - @Override public void setAnchor(@Nullable final JComponent anchor) { super.setAnchor(anchor); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java index 4317bd459e4e..20ad197ab8f8 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java @@ -18,7 +18,7 @@ public class GenericWebRepositoryType extends BaseRepositoryType + +