From 4664f018c2ac289c9e42486ffd2fe9e92c0b4dc8 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sun, 7 Oct 2012 22:57:25 +0300 Subject: [PATCH] IDEA-89690 add information where a method comes from in method code completion popup for groovy --- .../psi/impl/light/LightMethodBuilder.java | 15 ++- .../psi/impl/light/LightVariableBase.java | 15 ++- .../psi/impl/light/LightVariableBuilder.java | 19 ++- .../originInfo/OriginInfoAwareElement.java | 26 +++++ .../originInfo/OriginInfoProvider.java | 66 +++++++++++ .../lookup/LookupElementBuilder.java | 6 + .../src/META-INF/LangExtensionPoints.xml | 1 + plugins/groovy/src/META-INF/plugin.xml | 13 ++- .../groovy/annotator/GroovyAnnotator.java | 2 +- .../GroovyAssignabilityCheckInspection.java | 2 +- .../AccessorMethodReferencesSearcher.java | 2 +- .../lang/completion/GroovyCompletionUtil.java | 7 ++ .../modifiers/GrModifierListImpl.java | 4 +- .../typedef/GrTypeDefinitionImpl.java | 2 +- .../impl/synthetic/GrAccessorMethodImpl.java | 3 +- .../synthetic/GrDynamicImplicitMethod.java | 9 +- .../synthetic/GrDynamicImplicitProperty.java | 2 + .../psi/impl/synthetic/GrGdkMethodImpl.java | 20 +++- .../impl/synthetic/GrLightMethodBuilder.java | 13 ++- .../impl/synthetic/GrLightModifierList.java | 2 +- .../impl/synthetic/GrUndefinedVariable.java | 108 ------------------ .../lang/psi/util/GroovyCommonClassNames.java | 2 + .../{ => ast}/AstTransformContributor.java | 7 +- .../resolve/ast/AutoCloneContributor.java | 5 +- .../ast/AutoExternalizeContributor.java | 3 +- .../ConstructorAnnotationsProcessor.java | 32 ++++-- .../lang/resolve/ast/DelegatedMethod.java | 20 +++- .../ast/DelegatedMethodsContributor.java | 4 +- .../GrInheritConstructorContributor.java | 21 ++-- .../{noncode => ast}/LoggingContributor.java | 39 +++---- .../GrCollectionTypeMembersProvider.java | 25 ++-- .../{ => noncode}/MixinMemberContributor.java | 15 ++- .../convertToJava/StubGenerator.java | 6 +- .../SwingBuilderNonCodeMemberContributor.java | 5 +- 34 files changed, 318 insertions(+), 203 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoAwareElement.java create mode 100644 platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoProvider.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrUndefinedVariable.java rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/{ => ast}/AstTransformContributor.java (94%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/{noncode => ast}/ConstructorAnnotationsProcessor.java (86%) rename java/java-psi-impl/src/com/intellij/psi/impl/light/LightMirrorMethod.java => plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethod.java (58%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/{noncode => ast}/GrInheritConstructorContributor.java (71%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/{noncode => ast}/LoggingContributor.java (53%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/{ => noncode}/MixinMemberContributor.java (90%) diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java b/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java index 9dbcd0795da0..e029c0314735 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightMethodBuilder.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl.light; +import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement; import com.intellij.lang.Language; import com.intellij.lang.java.JavaLanguage; import com.intellij.navigation.ItemPresentation; @@ -41,7 +42,7 @@ import java.util.List; /** * @author peter */ -public class LightMethodBuilder extends LightElement implements PsiMethod { +public class LightMethodBuilder extends LightElement implements PsiMethod, OriginInfoAwareElement { private final String myName; private Computable myReturnType; private final PsiModifierList myModifierList; @@ -52,6 +53,7 @@ public class LightMethodBuilder extends LightElement implements PsiMethod { private PsiClass myContainingClass; private boolean myConstructor; private String myMethodKind = "LightMethodBuilder"; + private String myOriginInfo = null; public LightMethodBuilder(PsiClass constructedClass, Language language) { this(constructedClass.getManager(), language, constructedClass.getName()); @@ -435,4 +437,15 @@ public class LightMethodBuilder extends LightElement implements PsiMethod { ((LightTypeParameterListBuilder)myTypeParameterList).addParameter(new LightTypeParameter(parameter)); return this; } + + @Nullable + @Override + public String getOriginInfo() { + return myOriginInfo; + } + + public void setOriginInfo(@Nullable String originInfo) { + myOriginInfo = originInfo; + } + } diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBase.java b/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBase.java index f6ac7ac500fa..6a580554fcdc 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBase.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBase.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl.light; +import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement; import com.intellij.lang.Language; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.util.text.StringUtil; @@ -25,18 +26,20 @@ import com.intellij.ui.RowIcon; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PlatformIcons; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; /** * @author ven */ -public abstract class LightVariableBase extends LightElement implements PsiVariable { +public abstract class LightVariableBase extends LightElement implements PsiVariable, OriginInfoAwareElement { protected PsiElement myScope; protected PsiIdentifier myNameIdentifier; protected PsiType myType; protected final PsiModifierList myModifierList; protected boolean myWritable; + private String myOriginInfo = null; public LightVariableBase(PsiManager manager, PsiIdentifier nameIdentifier, PsiType type, boolean writable, PsiElement scope) { this(manager, nameIdentifier, JavaLanguage.INSTANCE, type, writable, scope); @@ -154,4 +157,14 @@ public abstract class LightVariableBase extends LightElement implements PsiVaria public PsiType getTypeNoResolve() { return getType(); } + + @Nullable + @Override + public String getOriginInfo() { + return myOriginInfo; + } + + public void setOriginInfo(String originInfo) { + myOriginInfo = originInfo; + } } diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java b/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java index 5ed93005c5a2..93ea3327522b 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightVariableBuilder.java @@ -1,7 +1,8 @@ package com.intellij.psi.impl.light; +import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement; import com.intellij.lang.Language; -import com.intellij.lang.StdLanguages; +import com.intellij.lang.java.JavaLanguage; import com.intellij.navigation.NavigationItem; import com.intellij.psi.*; import com.intellij.psi.impl.ElementPresentationUtil; @@ -10,24 +11,26 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.PlatformIcons; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; /** * @author peter */ -public class LightVariableBuilder extends LightElement implements PsiVariable, NavigationItem { +public class LightVariableBuilder extends LightElement implements PsiVariable, NavigationItem, OriginInfoAwareElement { private final String myName; private final PsiType myType; private volatile LightModifierList myModifierList; private volatile Icon myBaseIcon = PlatformIcons.VARIABLE_ICON; + private String myOriginInfo; public LightVariableBuilder(@NotNull String name, @NotNull String type, @NotNull PsiElement navigationElement) { this(name, JavaPsiFacade.getElementFactory(navigationElement.getProject()).createTypeFromText(type, navigationElement), navigationElement); } public LightVariableBuilder(@NotNull String name, @NotNull PsiType type, @NotNull PsiElement navigationElement) { - this(navigationElement.getManager(), name, type, StdLanguages.JAVA); + this(navigationElement.getManager(), name, type, JavaLanguage.INSTANCE); setNavigationElement(navigationElement); } @@ -124,4 +127,14 @@ public class LightVariableBuilder extends LightE myBaseIcon = baseIcon; return (T)this; } + + @Nullable + @Override + public String getOriginInfo() { + return myOriginInfo; + } + + public void setOriginInfo(@Nullable String originInfo) { + myOriginInfo = originInfo; + } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoAwareElement.java b/platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoAwareElement.java new file mode 100644 index 000000000000..fbf56d05258c --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoAwareElement.java @@ -0,0 +1,26 @@ +/* + * 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.codeInsight.completion.originInfo; + +import org.jetbrains.annotations.Nullable; + +/** + * @author Max Medvedev + */ +public interface OriginInfoAwareElement { + @Nullable + String getOriginInfo(); +} diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoProvider.java b/platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoProvider.java new file mode 100644 index 000000000000..0d50c3a4a2cc --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/originInfo/OriginInfoProvider.java @@ -0,0 +1,66 @@ +/* + * 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.codeInsight.completion.originInfo; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Provides info for magic method or properties about their origin: + * original class, rule according to which the element was added, etc + * + * @see OriginInfoProvider#provideOriginInfo(com.intellij.psi.PsiElement) + * @see com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement + * + * + * @author Max Medvedev + */ +public abstract class OriginInfoProvider { + private static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.originInfoProvider"); + + @Nullable + public static String getOriginInfo(@Nullable PsiElement element) { + if (element == null) return null; + String info = _getOriginInfo(element); + if (info != null) info = "(" + info + ")"; + return info; + } + + @Nullable + private static String _getOriginInfo(@NotNull PsiElement element) { + if (element instanceof OriginInfoAwareElement) { + String info = ((OriginInfoAwareElement)element).getOriginInfo(); + if (info != null) return info; + } + + + for (OriginInfoProvider provider : EP_NAME.getExtensions()) { + String info = provider.provideOriginInfo(element); + if (info != null) return info; + } + + return null; + } + + /** + * @param element magic element + * @return info to show in completion tail text + */ + @Nullable + protected abstract String provideOriginInfo(@NotNull PsiElement element); +} diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java index 9b95c434dbb9..4641b615a848 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java @@ -292,6 +292,12 @@ public final class LookupElementBuilder extends LookupElement { myAllLookupStrings, myCaseSensitive); } + public LookupElementBuilder appendTailText(@NotNull String tailText, boolean grayed) { + final LookupElementPresentation presentation = copyPresentation(); + presentation.appendTailText(tailText, grayed); + return new LookupElementBuilder(myLookupString, myObject, myInsertHandler, null, presentation, myAllLookupStrings, myCaseSensitive); + } + public LookupElement withAutoCompletionPolicy(AutoCompletionPolicy policy) { return policy.applyPolicy(this); } diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 937ea57a09fd..936bbc58fe60 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -322,6 +322,7 @@ + diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 260e29c46a8d..5277e0d0a828 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -30,7 +30,7 @@ - + @@ -79,9 +79,8 @@ - - + @@ -92,11 +91,14 @@ + + - - + + + @@ -133,7 +135,6 @@ - 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 1ab2daa88197..08fb713113c0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -95,7 +95,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; -import org.jetbrains.plugins.groovy.lang.resolve.noncode.GrInheritConstructorContributor; +import org.jetbrains.plugins.groovy.lang.resolve.ast.GrInheritConstructorContributor; import org.jetbrains.plugins.groovy.lang.resolve.processors.PropertyResolverProcessor; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; 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 0fbbb192cfec..398220c0e270 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 @@ -77,8 +77,8 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; -import org.jetbrains.plugins.groovy.lang.resolve.MixinMemberContributor; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; +import org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor; import java.util.ArrayList; import java.util.List; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AccessorMethodReferencesSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AccessorMethodReferencesSearcher.java index 262b09c88981..e58cd3da214b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AccessorMethodReferencesSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AccessorMethodReferencesSearcher.java @@ -30,7 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGd import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; -import org.jetbrains.plugins.groovy.lang.resolve.MixinMemberContributor; +import org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor; /** * author ven diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java index 2e346ac1f8cc..29fca80becfb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java @@ -22,6 +22,7 @@ import com.intellij.codeInsight.completion.AllClassesGetter; import com.intellij.codeInsight.completion.JavaClassNameCompletionContributor; import com.intellij.codeInsight.completion.JavaCompletionUtil; import com.intellij.codeInsight.completion.PrefixMatcher; +import com.intellij.codeInsight.completion.originInfo.OriginInfoProvider; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.LookupItem; @@ -356,6 +357,12 @@ public class GroovyCompletionUtil { } builder = builder.withTailText(tailText, true); } + + String originInfo = OriginInfoProvider.getOriginInfo(element); + if (originInfo != null) { + builder = builder.appendTailText(originInfo, true); + } + return builder; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java index 4096e422f1e0..a2f1cab19433 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java @@ -43,7 +43,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition; import org.jetbrains.plugins.groovy.lang.psi.impl.GrStubElementBase; import org.jetbrains.plugins.groovy.lang.psi.stubs.GrModifierListStub; -import org.jetbrains.plugins.groovy.lang.resolve.noncode.ConstructorAnnotationsProcessor; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; /** * @autor: Dmitry.Krasilschikov @@ -164,7 +164,7 @@ public class GrModifierListImpl extends GrStubElementBase im } if (pParent instanceof GrTypeDefinition) { PsiModifierList pModifierList = ((GrTypeDefinition)pParent).getModifierList(); - if (pModifierList != null && pModifierList.findAnnotation(ConstructorAnnotationsProcessor.IMMUTABLE) != null) { + if (pModifierList != null && pModifierList.findAnnotation(GroovyCommonClassNames.GROOVY_LANG_IMMUTABLE) != null) { if (modifier.equals(GrModifier.FINAL)) return true; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java index 6ad8422f1090..4017b4c9002c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java @@ -73,7 +73,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub; import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; -import org.jetbrains.plugins.groovy.lang.resolve.AstTransformContributor; +import org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor; import org.jetbrains.plugins.groovy.runner.GroovyRunnerUtil; import org.jetbrains.plugins.groovy.util.LightCacheKey; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java index 3fbe8a1bf15a..fb4e9915cd1a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrAccessorMethodImpl.java @@ -78,6 +78,7 @@ public class GrAccessorMethodImpl extends LightMethodBuilder implements GrAccess setContainingClass(myProperty.getContainingClass()); setMethodKind("AccessorMethod"); + setOriginInfo("synthetic accessor for '"+myProperty.getName()+"'"); } @Nullable @@ -124,7 +125,6 @@ public class GrAccessorMethodImpl extends LightMethodBuilder implements GrAccess public static GrAccessorMethod createSetterMethod(GrField field) { if (field.isProperty() && !field.hasModifierProperty(PsiModifier.FINAL)) { String fieldName = field.getName(); - assert fieldName != null; String name = GroovyPropertyUtils.getSetterName(fieldName); final GrAccessorMethod setter = new GrAccessorMethodImpl(field, true, name); @@ -140,7 +140,6 @@ public class GrAccessorMethodImpl extends LightMethodBuilder implements GrAccess public static GrAccessorMethod[] createGetterMethods(GrField field) { if (field.isProperty()) { String fieldName = field.getName(); - assert fieldName != null; final PsiClass clazz = field.getContainingClass(); GrAccessorMethod getter1 = new GrAccessorMethodImpl(field, false, GroovyPropertyUtils.getGetterNameNonBoolean(fieldName)); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java index 5438d9fefb69..85728bfd94c5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic; +import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; @@ -56,7 +57,7 @@ import java.util.List; * User: Dmitry.Krasilschikov * Date: 21.02.2008 */ -public class GrDynamicImplicitMethod extends LightElement implements PsiMethod, GrDynamicImplicitElement { +public class GrDynamicImplicitMethod extends LightElement implements PsiMethod, GrDynamicImplicitElement, OriginInfoAwareElement { private final PsiManager myManager; private final GrMethod myMethod; @@ -72,6 +73,12 @@ public class GrDynamicImplicitMethod extends LightElement implements PsiMethod, myContainingClassName = containingClassName; } + @Nullable + @Override + public String getOriginInfo() { + return "dynamic method"; + } + public String[] getParameterTypes() { final PsiParameter[] psiParameters = getParameterList().getParameters(); List result = new ArrayList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitProperty.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitProperty.java index eeaa98ab6fcc..3adc5205e883 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitProperty.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitProperty.java @@ -60,6 +60,8 @@ public class GrDynamicImplicitProperty extends GrImplicitVariableImpl implements else { myNavigationalElement = navigationalElement; } + + setOriginInfo("dynamic property"); } @Nullable diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrGdkMethodImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrGdkMethodImpl.java index cc606bbc2c58..2d6de5782929 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrGdkMethodImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrGdkMethodImpl.java @@ -24,6 +24,7 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import icons.JetgroovyIcons; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; @@ -37,7 +38,7 @@ public class GrGdkMethodImpl extends LightMethodBuilder implements GrGdkMethod { private static Key> CACHED_NON_STATIC = Key.create("Cached instance gdk method"); private final PsiMethod myMethod; - private GrGdkMethodImpl(PsiMethod method, boolean isStatic) { + private GrGdkMethodImpl(PsiMethod method, boolean isStatic, String originInfo) { super(method.getManager(), GroovyFileType.GROOVY_LANGUAGE, method.getName()); myMethod = method; @@ -55,6 +56,16 @@ public class GrGdkMethodImpl extends LightMethodBuilder implements GrGdkMethod { setBaseIcon(JetgroovyIcons.Groovy.Method); setMethodKind("GrGdkMethod"); setNavigationElement(method); + + if (originInfo != null) { + setOriginInfo(originInfo); + } + else { + PsiClass aClass = method.getContainingClass(); + if (aClass != null && aClass.getName() != null) { + setOriginInfo(aClass.getName()); + } + } } @NotNull @@ -95,13 +106,18 @@ public class GrGdkMethodImpl extends LightMethodBuilder implements GrGdkMethod { @NotNull public static GrGdkMethod createGdkMethod(@NotNull final PsiMethod original, final boolean isStatic) { + return createGdkMethod(original, isStatic, null); + } + + @NotNull + public static GrGdkMethod createGdkMethod(@NotNull final PsiMethod original, final boolean isStatic, @Nullable final String originInfo) { final Key> cachedValueKey = isStatic ? CACHED_STATIC : CACHED_NON_STATIC; CachedValue cachedValue = original.getUserData(cachedValueKey); if (cachedValue == null) { cachedValue = CachedValuesManager.getManager(original.getProject()).createCachedValue(new CachedValueProvider() { @Override public Result compute() { - return Result.create(new GrGdkMethodImpl(original, isStatic), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + return Result.create(new GrGdkMethodImpl(original, isStatic, originInfo), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } }); original.putUserData(cachedValueKey, cachedValue); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightMethodBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightMethodBuilder.java index 92bf319c941d..aa8e74963df1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightMethodBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightMethodBuilder.java @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic; +import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement; import com.intellij.navigation.ItemPresentation; import com.intellij.psi.*; import com.intellij.psi.impl.ElementPresentationUtil; @@ -54,7 +55,7 @@ import java.util.Map; /** * @author Sergey Evdokimov */ -public class GrLightMethodBuilder extends LightElement implements GrMethod { +public class GrLightMethodBuilder extends LightElement implements GrMethod, OriginInfoAwareElement { protected String myName; private PsiType myReturnType = PsiType.VOID; private final GrLightModifierList myModifierList; @@ -67,6 +68,7 @@ public class GrLightMethodBuilder extends LightElement implements GrMethod { private Object myData; private boolean myConstructor; + private String myOriginInfo; public GrLightMethodBuilder(PsiManager manager, String name) { super(manager, GroovyFileType.GROOVY_LANGUAGE); @@ -462,4 +464,13 @@ public class GrLightMethodBuilder extends LightElement implements GrMethod { return this; } + @Nullable + @Override + public String getOriginInfo() { + return myOriginInfo; + } + + public void setOriginInfo(@Nullable String originInfo) { + myOriginInfo = originInfo; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java index 06cb885e210a..6a709ae6eca7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java @@ -65,7 +65,7 @@ public class GrLightModifierList extends LightElement implements GrModifierList myModifiers = modifiers; } - public void setModifiers(String[] modifiers) { + public void setModifiers(String... modifiers) { myModifiers = 0; for (String modifier : modifiers) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrUndefinedVariable.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrUndefinedVariable.java deleted file mode 100644 index d9fc352d7d9f..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrUndefinedVariable.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 org.jetbrains.plugins.groovy.lang.psi.impl.synthetic; - -import com.intellij.psi.*; -import com.intellij.psi.impl.light.LightVariableBase; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; -import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; - -*/ -/** - * @author Max Medvedev - *//* - -public class GrUndefinedVariable extends LightVariableBase implements GrVariable { - public GrUndefinedVariable(GrAssignmentExpression assignment) { - super(assignment.getManager(), new GrImplicitVariableImpl.GrLightIdentifier(assignment.getManager(), assignment.getLValue().getText()), - PsiType.getJavaLangObject(assignment.getManager(), assignment.getResolveScope()), true, assignment.get); - } - - @Nullable - @Override - public GrExpression getInitializerGroovy() { - //todo - return null; - } - - @Override - public void setType(@Nullable PsiType type) throws IncorrectOperationException { - //todo - - } - - @Nullable - @Override - public GrTypeElement getTypeElementGroovy() { - //todo - return null; - } - - @Nullable - @Override - public PsiType getTypeGroovy() { - //todo - return null; - } - - @Nullable - @Override - public PsiType getDeclaredType() { - //todo - return null; - } - - @Nullable - @Override - public GrModifierList getModifierList() { - //todo - return null; - } - - @NotNull - @Override - public PsiElement getNameIdentifierGroovy() { - //todo - return null; - } - - @Override - public void accept(GroovyElementVisitor visitor) { - //todo - - } - - @Override - public void acceptChildren(GroovyElementVisitor visitor) { - //todo - - } - - @Override - public String toString() { - //todo - return null; - } -} -*/ diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java index 6d05fc1a9797..32e85b636a4b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java @@ -55,6 +55,8 @@ public final class GroovyCommonClassNames { @NonNls public static final String GROOVY_TRANSFORM_TYPE_CHECKED = "groovy.transform.TypeChecked"; @NonNls public static final String GROOVY_TRANSFORM_TYPE_CHECKING_MODE = "groovy.transform.TypeCheckingMode"; @NonNls public static final String JAVA_LANG_CHAR_SEQUENCE = "java.lang.CharSequence"; + public static final String GROOVY_TRANSFORM_INHERIT_CONSTRUCTORS = "groovy.transform.InheritConstructors"; + public static final String GROOVY_LANG_IMMUTABLE = "groovy.lang.Immutable"; private GroovyCommonClassNames() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/AstTransformContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AstTransformContributor.java similarity index 94% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/AstTransformContributor.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AstTransformContributor.java index cae01df3ace6..b2ce9d8e6b0d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/AstTransformContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AstTransformContributor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.resolve; +package org.jetbrains.plugins.groovy.lang.resolve.ast; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.util.Computable; @@ -23,7 +23,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; /** * @author Max Medvedev diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoCloneContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoCloneContributor.java index f5259848482b..2d74477e5088 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoCloneContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoCloneContributor.java @@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import org.jetbrains.plugins.groovy.lang.resolve.AstTransformContributor; import java.util.Collection; @@ -35,9 +34,11 @@ public class AutoCloneContributor extends AstTransformContributor { public void collectMethods(@NotNull GrTypeDefinition clazz, Collection collector) { if (PsiImplUtil.getAnnotation(clazz, GroovyCommonClassNames.GROOVY_TRANSFORM_AUTO_CLONE) == null) return; - final LightMethodBuilder clone = new LightMethodBuilder(clazz.getManager(), "clone").addModifier(PsiModifier.PUBLIC); + final LightMethodBuilder clone = new LightMethodBuilder(clazz.getManager(), "clone"); + clone.addModifier(PsiModifier.PUBLIC); clone.setContainingClass(clazz); clone.addException(CloneNotSupportedException.class.getName()); + clone.setOriginInfo("created by @AutoClone"); collector.add(clone); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoExternalizeContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoExternalizeContributor.java index 88a3040a86d7..36f51decf6a3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoExternalizeContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/AutoExternalizeContributor.java @@ -24,7 +24,6 @@ import org.jetbrains.plugins.groovy.gpp.GppTypeConverter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import org.jetbrains.plugins.groovy.lang.resolve.AstTransformContributor; import java.io.IOException; import java.io.ObjectInput; @@ -44,11 +43,13 @@ public class AutoExternalizeContributor extends AstTransformContributor { write.setContainingClass(clazz); write.addParameter("out", ObjectOutput.class.getName()); write.addException(IOException.class.getName()); + write.setOriginInfo("created by @AutoExternalize"); collector.add(write); final LightMethodBuilder read = new LightMethodBuilder(clazz.getManager(), "readExternal"); read.setContainingClass(clazz); read.addParameter("oin", ObjectInput.class.getName()); + read.setOriginInfo("created by @AutoExternalize"); collector.add(read); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/ConstructorAnnotationsProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/ConstructorAnnotationsProcessor.java similarity index 86% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/ConstructorAnnotationsProcessor.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/ConstructorAnnotationsProcessor.java index c47507d29177..23ba65f78dd5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/ConstructorAnnotationsProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/ConstructorAnnotationsProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.resolve.noncode; +package org.jetbrains.plugins.groovy.lang.resolve.ast; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -24,20 +24,21 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter; -import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; -import org.jetbrains.plugins.groovy.lang.resolve.AstTransformContributor; import org.jetbrains.plugins.groovy.lang.resolve.CollectClassMembersUtil; -import java.util.*; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.*; /** * @author peter */ public class ConstructorAnnotationsProcessor extends AstTransformContributor { - public static final String IMMUTABLE = "groovy.lang.Immutable"; - @Override public void collectMethods(@NotNull GrTypeDefinition typeDefinition, Collection collector) { if (typeDefinition.getName() == null) return; @@ -45,10 +46,10 @@ public class ConstructorAnnotationsProcessor extends AstTransformContributor { PsiModifierList modifierList = typeDefinition.getModifierList(); if (modifierList == null) return; - final PsiAnnotation tupleConstructor = modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_TUPLE_CONSTRUCTOR); - final boolean immutable = modifierList.findAnnotation(IMMUTABLE) != null || - modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_IMMUTABLE) != null; - final PsiAnnotation canonical = modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_CANONICAL); + final PsiAnnotation tupleConstructor = modifierList.findAnnotation(GROOVY_TRANSFORM_TUPLE_CONSTRUCTOR); + final boolean immutable = modifierList.findAnnotation(GROOVY_LANG_IMMUTABLE) != null || + modifierList.findAnnotation(GROOVY_TRANSFORM_IMMUTABLE) != null; + final PsiAnnotation canonical = modifierList.findAnnotation(GROOVY_TRANSFORM_CANONICAL); if (!immutable && canonical == null && tupleConstructor == null) { return; } @@ -86,6 +87,15 @@ public class ConstructorAnnotationsProcessor extends AstTransformContributor { tupleConstructor != null ? PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeFields", false) : canonical == null, !immutable, excludes); + if (immutable) { + fieldsConstructor.setOriginInfo("created by @Immutable"); + } + else if (tupleConstructor != null) { + fieldsConstructor.setOriginInfo("created by @TupleConstructor"); + } + else /*if (canonical != null)*/ { + fieldsConstructor.setOriginInfo("created by @Canonical"); + } collector.add(fieldsConstructor.setContainingClass(typeDefinition)); @@ -97,7 +107,7 @@ public class ConstructorAnnotationsProcessor extends AstTransformContributor { boolean superFields, boolean superProperties, Set visited, Set excludes) { PsiClass parent = typeDefinition.getSuperClass(); - if (parent != null && visited.add(parent) && !GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT.equals(parent.getQualifiedName())) { + if (parent != null && visited.add(parent) && !GROOVY_OBJECT_SUPPORT.equals(parent.getQualifiedName())) { addParametersForSuper(parent, fieldsConstructor, superFields, superProperties, visited, excludes); addParameters(parent, fieldsConstructor, superProperties, superFields, true, excludes); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMirrorMethod.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethod.java similarity index 58% rename from java/java-psi-impl/src/com/intellij/psi/impl/light/LightMirrorMethod.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethod.java index 624f83aad099..48953a0ec695 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMirrorMethod.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethod.java @@ -13,19 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.psi.impl.light; +package org.jetbrains.plugins.groovy.lang.resolve.ast; +import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMirrorElement; +import com.intellij.psi.impl.light.LightMethod; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Max Medvedev */ -public class LightMirrorMethod extends LightMethod implements PsiMethod, PsiMirrorElement { +public class DelegatedMethod extends LightMethod implements PsiMethod, PsiMirrorElement, OriginInfoAwareElement { private PsiMethod myPrototype; - public LightMirrorMethod(@NotNull PsiMethod delegate, @NotNull PsiMethod prototype) { + public DelegatedMethod(@NotNull PsiMethod delegate, @NotNull PsiMethod prototype) { super(prototype.getManager(), delegate, delegate.getContainingClass()); myPrototype = prototype; } @@ -35,4 +39,14 @@ public class LightMirrorMethod extends LightMethod implements PsiMethod, PsiMirr public PsiMethod getPrototype() { return myPrototype; } + + @Nullable + @Override + public String getOriginInfo() { + PsiClass aClass = myPrototype.getContainingClass(); + if (aClass != null & aClass.getName() != null) { + return "delegated from " + aClass.getName(); + } + return null; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java index e2cc5a82d2be..87ea5c07501f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java @@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.lang.resolve.ast; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightMethodBuilder; -import com.intellij.psi.impl.light.LightMirrorMethod; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiUtil; @@ -38,7 +37,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import org.jetbrains.plugins.groovy.lang.resolve.AstTransformContributor; import java.util.*; @@ -300,6 +298,6 @@ public class DelegatedMethodsContributor extends AstTransformContributor { } builder.setBaseIcon(JetgroovyIcons.Groovy.Method); - return new LightMirrorMethod(builder, method); + return new DelegatedMethod(builder, method); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrInheritConstructorContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/GrInheritConstructorContributor.java similarity index 71% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrInheritConstructorContributor.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/GrInheritConstructorContributor.java index 6f2ff163e32b..e0de40a6208c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrInheritConstructorContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/GrInheritConstructorContributor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.resolve.noncode; +package org.jetbrains.plugins.groovy.lang.resolve.ast; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -21,7 +21,7 @@ import com.intellij.psi.util.TypeConversionUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder; -import org.jetbrains.plugins.groovy.lang.resolve.AstTransformContributor; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import java.util.Collection; @@ -29,7 +29,6 @@ import java.util.Collection; * @author Maxim.Medvedev */ public class GrInheritConstructorContributor extends AstTransformContributor { - public static final String INHERIT_CONSTRUCTOR_NAME = "groovy.transform.InheritConstructors"; @Override public void collectMethods(@NotNull GrTypeDefinition psiClass, Collection collector) { @@ -44,12 +43,16 @@ public class GrInheritConstructorContributor extends AstTransformContributor { final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, psiClass, PsiSubstitutor.EMPTY); for (PsiMethod constructor : superClass.getConstructors()) { - final GrLightMethodBuilder inheritedConstructor = - new GrLightMethodBuilder(psiClass.getManager(), psiClass.getName()).setContainingClass(psiClass); - inheritedConstructor.setConstructor(true).setNavigationElement(psiClass); + final GrLightMethodBuilder inheritedConstructor = new GrLightMethodBuilder(psiClass.getManager(), psiClass.getName()); + inheritedConstructor.setContainingClass(psiClass); + inheritedConstructor.setConstructor(true); + inheritedConstructor.setNavigationElement(psiClass); + inheritedConstructor.setOriginInfo("created by @InheritConstructors"); + for (PsiParameter parameter : constructor.getParameterList().getParameters()) { - inheritedConstructor - .addParameter(StringUtil.notNullize(parameter.getName()), superClassSubstitutor.substitute(parameter.getType()), false); + String name = StringUtil.notNullize(parameter.getName()); + PsiType type = superClassSubstitutor.substitute(parameter.getType()); + inheritedConstructor.addParameter(name, type, false); } if (psiClass.findCodeMethodsBySignature(inheritedConstructor, false).length == 0) { collector.add(inheritedConstructor); @@ -59,6 +62,6 @@ public class GrInheritConstructorContributor extends AstTransformContributor { public static boolean hasInheritConstructorsAnnotation(PsiClass psiClass) { final PsiModifierList modifierList = psiClass.getModifierList(); - return modifierList != null && modifierList.findAnnotation(INHERIT_CONSTRUCTOR_NAME) != null; + return modifierList != null && modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_INHERIT_CONSTRUCTORS) != null; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/LoggingContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/LoggingContributor.java similarity index 53% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/LoggingContributor.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/LoggingContributor.java index 176bb3916e15..1ca8c0902733 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/LoggingContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/LoggingContributor.java @@ -13,24 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.resolve.noncode; +package org.jetbrains.plugins.groovy.lang.resolve.ast; import com.google.common.collect.ImmutableMap; -import com.intellij.psi.*; -import com.intellij.psi.impl.light.LightFieldBuilder; -import com.intellij.psi.scope.PsiScopeProcessor; -import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.PsiModifier; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightField; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; -import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor; -import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; + +import java.util.Collection; /** * @author peter */ -public class LoggingContributor extends NonCodeMembersContributor { +public class LoggingContributor extends AstTransformContributor { private static final ImmutableMap ourLoggers = ImmutableMap.builder(). put("groovy.util.logging.Log", "java.util.logging.Logger"). put("groovy.util.logging.Commons", "org.apache.commons.logging.Log"). @@ -39,23 +39,20 @@ public class LoggingContributor extends NonCodeMembersContributor { build(); @Override - public void processDynamicElements(@NotNull PsiType qualifierType, - PsiClass psiClass, - PsiScopeProcessor processor, - GroovyPsiElement place, - ResolveState state) { - if (!(psiClass instanceof GrTypeDefinition) || !PsiTreeUtil.isAncestor(psiClass, place, true)) return; - - PsiModifierList modifierList = psiClass.getModifierList(); + public void collectFields(@NotNull GrTypeDefinition psiClass, Collection collector) { + GrModifierList modifierList = psiClass.getModifierList(); if (modifierList == null) return; - for (PsiAnnotation annotation : modifierList.getAnnotations()) { + + for (GrAnnotation annotation : modifierList.getAnnotations()) { String qname = annotation.getQualifiedName(); String logger = ourLoggers.get(qname); if (logger != null) { String fieldName = PsiUtil.getAnnoAttributeValue(annotation, "value", "log"); - LightFieldBuilder field = new LightFieldBuilder(fieldName, logger, annotation).setContainingClass(psiClass) - .setModifiers(PsiModifier.FINAL, PsiModifier.STATIC, PsiModifier.PRIVATE); - ResolveUtil.processElement(processor, field, state); + GrLightField field = new GrLightField(psiClass, fieldName, logger); + field.setNavigationElement(annotation); + field.getModifierList().setModifiers(PsiModifier.PRIVATE, PsiModifier.FINAL, PsiModifier.STATIC); + field.setOriginInfo("created by @" + annotation.getShortName()); + collector.add(field); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java index 0f1ab6b11e11..f915b73f4bfa 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java @@ -29,6 +29,8 @@ import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint; +import static com.intellij.psi.CommonClassNames.JAVA_UTIL_COLLECTION; + /** * @author Maxim.Medvedev */ @@ -36,7 +38,7 @@ public class GrCollectionTypeMembersProvider extends NonCodeMembersContributor { @Override public String getParentClassName() { - return CommonClassNames.JAVA_UTIL_COLLECTION; + return JAVA_UTIL_COLLECTION; } @Override @@ -48,31 +50,28 @@ public class GrCollectionTypeMembersProvider extends NonCodeMembersContributor { final PsiType collectionType = PsiUtil.extractIterableTypeParameter(qualifierType, true); if (collectionType == null) return; - final PsiScopeProcessor fieldSearcher = new FieldSearcher(processor, JavaPsiFacade.getInstance(place.getProject()).findClass(CommonClassNames.JAVA_UTIL_COLLECTION, place.getResolveScope())); + PsiClass collectionClass = JavaPsiFacade.getInstance(place.getProject()).findClass(JAVA_UTIL_COLLECTION, place.getResolveScope()); + final PsiScopeProcessor fieldSearcher = new FieldSearcher(processor, collectionClass); ResolveUtil.processAllDeclarations(collectionType, fieldSearcher, state, place); } private static class FieldSearcher extends DelegatingScopeProcessor implements ClassHint, ElementClassHint { - final PsiClass collectionClass; + final PsiClass myCollectionClass; public FieldSearcher(PsiScopeProcessor processor, PsiClass collectionClass) { super(processor); - this.collectionClass = collectionClass; + myCollectionClass = collectionClass; } @Override public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiField) { final PsiType type = ((PsiField)element).getType(); - final String typeText; - if (type instanceof PsiClassType) { - typeText = CommonClassNames.JAVA_UTIL_COLLECTION + "<" + type.getCanonicalText() + ">"; - } - else { - typeText = CommonClassNames.JAVA_UTIL_COLLECTION; - } - LightFieldBuilder lightField = new LightFieldBuilder(((PsiField)element).getName(), typeText, element).setContainingClass( - collectionClass); + final String typeText = + type instanceof PsiClassType ? JAVA_UTIL_COLLECTION + "<" + type.getCanonicalText() + ">" : JAVA_UTIL_COLLECTION; + LightFieldBuilder lightField = new LightFieldBuilder(((PsiField)element).getName(), typeText, element); + lightField.setContainingClass(myCollectionClass); + lightField.setOriginInfo("spread collection field"); return super.execute(lightField, state); } return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/MixinMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/MixinMemberContributor.java similarity index 90% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/MixinMemberContributor.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/MixinMemberContributor.java index de98c0d447a0..00c7f6b47980 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/MixinMemberContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/MixinMemberContributor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang.resolve; +package org.jetbrains.plugins.groovy.lang.resolve.noncode; import com.intellij.psi.*; import com.intellij.psi.scope.DelegatingScopeProcessor; @@ -29,6 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; +import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor; import java.util.ArrayList; import java.util.List; @@ -71,7 +72,9 @@ public class MixinMemberContributor extends NonCodeMembersContributor { @Override public boolean execute(@NotNull PsiElement element, ResolveState state) { if (isCategoryMethod(element, qualifierType, state.get(PsiSubstitutor.KEY))) { - return super.execute(GrGdkMethodImpl.createGdkMethod((PsiMethod)element, false), state); + PsiMethod method = (PsiMethod)element; + String originInfo = getOriginInfo(method); + return super.execute(GrGdkMethodImpl.createGdkMethod(method, false, originInfo), state); } else { return super.execute(element, state); @@ -83,6 +86,14 @@ public class MixinMemberContributor extends NonCodeMembersContributor { } } + private static String getOriginInfo(PsiMethod element) { + PsiClass aClass = element.getContainingClass(); + if (aClass != null && aClass.getName() != null) { + return "mixed in from " + aClass.getName(); + } + return "mixed in"; + } + private static List getAllMixins(PsiModifierList modifierList) { final ArrayList result = new ArrayList(); for (PsiAnnotation annotation : modifierList.getApplicableAnnotations()) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java index 767f9b3c731b..4c30a7cad993 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java @@ -20,7 +20,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightMethodBuilder; -import com.intellij.psi.impl.light.LightMirrorMethod; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.psi.util.PsiUtil; @@ -42,6 +41,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator; +import org.jetbrains.plugins.groovy.lang.resolve.ast.DelegatedMethod; import java.util.*; @@ -288,8 +288,8 @@ public class StubGenerator implements ClassItemGenerator { public Collection collectMethods(PsiClass typeDefinition, boolean classDef) { List methods = new ArrayList(); for (PsiMethod method : typeDefinition.getMethods()) { - if (method instanceof LightMirrorMethod) { - PsiMethod prototype = ((LightMirrorMethod)method).getPrototype(); + if (method instanceof DelegatedMethod) { + PsiMethod prototype = ((DelegatedMethod)method).getPrototype(); PsiClass aClass = prototype.getContainingClass(); if (prototype.hasModifierProperty(PsiModifier.FINAL) && aClass != null && typeDefinition.isInheritor(aClass, true)) { continue; //skip final super methods diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/swingBuilder/SwingBuilderNonCodeMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/swingBuilder/SwingBuilderNonCodeMemberContributor.java index 8df4f79aa08a..fbbdde9af879 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/swingBuilder/SwingBuilderNonCodeMemberContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/swingBuilder/SwingBuilderNonCodeMemberContributor.java @@ -35,7 +35,9 @@ import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; /** * @author Sergey Evdokimov @@ -70,6 +72,7 @@ public class SwingBuilderNonCodeMemberContributor extends NonCodeMembersContribu public MyMethodBuilder(PsiManager manager, String name) { super(manager, name); setMethodKind(METHOD_KIND); + setOriginInfo("SwingBuilder method"); } @NotNull