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 0635eaa45e28..2568d42cd89e 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 @@ -32,6 +32,7 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; import org.jetbrains.plugins.groovy.codeInspection.GroovyFix; import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; import org.jetbrains.plugins.groovy.findUsages.LiteralConstructorReference; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; @@ -459,12 +460,12 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { if (namedArguments.length == 0) return; - Map map = GroovyNamedArgumentProvider.getNamedArgumentsFromAllProviders(call, null, false); + Map map = GroovyNamedArgumentProvider.getNamedArgumentsFromAllProviders(call, null, false); for (GrNamedArgument namedArgument : namedArguments) { String labelName = namedArgument.getLabelName(); - GroovyNamedArgumentProvider.ArgumentDescriptor descriptor = map.get(labelName); + NamedArgumentDescriptor descriptor = map.get(labelName); if (descriptor == null) continue; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java index eae55b709bd7..aa50c31e3e34 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodDescriptor.java @@ -10,6 +10,9 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import static org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor.Priority; +import static org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor.*; + /** * @author Sergey Evdokimov */ @@ -92,7 +95,7 @@ public class GroovyMethodDescriptor extends AbstractExtensionPointBean { } @Nullable - public Map getArgumentsMap() { + public Map getArgumentsMap() { if (myArguments == null && namedArgs == null) { assert isNamedArgsShowFirst == null; return null; @@ -100,12 +103,12 @@ public class GroovyMethodDescriptor extends AbstractExtensionPointBean { assert namedArgsProvider == null; - Map res = - new HashMap(); + Map res = + new HashMap(); if (myArguments != null) { for (NamedArguments arguments : myArguments) { - GroovyNamedArgumentProvider.ArgumentDescriptor descriptor = getDescriptor(isNamedArgsShowFirst, arguments.isFirst, arguments.type); + NamedArgumentDescriptor descriptor = getDescriptor(isNamedArgsShowFirst, arguments.isFirst, arguments.type); assert !StringUtil.isEmptyOrSpaces(arguments.names); @@ -121,7 +124,7 @@ public class GroovyMethodDescriptor extends AbstractExtensionPointBean { } if (!StringUtil.isEmptyOrSpaces(namedArgs)) { - GroovyNamedArgumentProvider.ArgumentDescriptor descriptor = getDescriptor(isNamedArgsShowFirst, null, null); + NamedArgumentDescriptor descriptor = getDescriptor(isNamedArgsShowFirst, null, null); for (StringTokenizer st = new StringTokenizer(namedArgs, ATTR_NAMES_DELIMITER); st.hasMoreTokens(); ) { String name = st.nextToken(); @@ -134,9 +137,9 @@ public class GroovyMethodDescriptor extends AbstractExtensionPointBean { return res; } - private static GroovyNamedArgumentProvider.ArgumentDescriptor getDescriptor(@Nullable Boolean methodFirstFlag, - @Nullable Boolean attrFirstFlag, - @Nullable String type) { + private static NamedArgumentDescriptor getDescriptor(@Nullable Boolean methodFirstFlag, + @Nullable Boolean attrFirstFlag, + @Nullable String type) { Boolean objShowFirst = attrFirstFlag; if (objShowFirst == null) { objShowFirst = methodFirstFlag; @@ -145,13 +148,13 @@ public class GroovyMethodDescriptor extends AbstractExtensionPointBean { boolean showFirst = objShowFirst == null || objShowFirst; if (StringUtil.isEmptyOrSpaces(type)) { - return showFirst ? GroovyNamedArgumentProvider.TYPE_ANY : GroovyNamedArgumentProvider.TYPE_ANY_NOT_FIRST; + return showFirst ? SIMPLE_ON_TOP : SIMPLE_NORMAL; } - GroovyNamedArgumentProvider.ArgumentDescriptor descriptor = new GroovyNamedArgumentProvider.StringTypeCondition(type.trim()); + NamedArgumentDescriptor descriptor = new NamedArgumentDescriptor.StringTypeCondition(type.trim()); if (!showFirst) { - descriptor.setShowFirst(false); + descriptor.setPriority(Priority.NORMAL); } return descriptor; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java index c691f51215ef..5e9e399cb7d9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java @@ -27,7 +27,7 @@ public class GroovyMethodInfo { private final String myReturnTypeCalculatorClassName; private PairFunction myReturnTypeCalculatorInstance; - private final Map myNamedArguments; + private final Map myNamedArguments; private final String myNamedArgProviderClassName; private GroovyNamedArgumentProvider myNamedArgProviderInstance; @@ -185,7 +185,7 @@ public class GroovyMethodInfo { } @Nullable - public Map getNamedArguments() { + public Map getNamedArguments() { return myNamedArguments; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java index 89c85fb50482..8252b1d85371 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java @@ -16,21 +16,17 @@ package org.jetbrains.plugins.groovy.extensions; import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.psi.*; -import com.intellij.psi.util.PropertyUtil; -import com.intellij.util.ArrayUtil; -import com.intellij.util.IncorrectOperationException; +import com.intellij.psi.CommonClassNames; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; -import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import java.util.HashMap; import java.util.Map; @@ -43,27 +39,19 @@ public abstract class GroovyNamedArgumentProvider { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.intellij.groovy.namedArgumentProvider"); - public static final StringTypeCondition TYPE_STRING = new StringTypeCondition(CommonClassNames.JAVA_LANG_STRING); - public static final StringTypeCondition TYPE_MAP = new StringTypeCondition(CommonClassNames.JAVA_UTIL_MAP); - public static final StringTypeCondition TYPE_BOOL = new StringTypeCondition(CommonClassNames.JAVA_LANG_BOOLEAN); - public static final StringTypeCondition TYPE_CLASS = new StringTypeCondition(CommonClassNames.JAVA_LANG_CLASS); - public static final StringTypeCondition TYPE_INTEGER = new StringTypeCondition(CommonClassNames.JAVA_LANG_INTEGER); - public static final ArgumentDescriptor TYPE_ANY = new ArgumentDescriptor(); - public static final ArgumentDescriptor TYPE_ANY_NOT_FIRST = new ArgumentDescriptor().setShowFirst(false); - public abstract void getNamedArguments(@NotNull GrCall call, @Nullable PsiElement resolve, @Nullable String argumentName, boolean forCompletion, - Map result); + Map result); - public static Map getNamedArgumentsFromAllProviders(@NotNull GrCall call, + public static Map getNamedArgumentsFromAllProviders(@NotNull GrCall call, @Nullable String argumentName, boolean forCompletion) { - Map namedArguments = new HashMap() { + Map namedArguments = new HashMap() { @Override - public ArgumentDescriptor put(String key, ArgumentDescriptor value) { - ArgumentDescriptor oldValue = super.put(key, value); + public NamedArgumentDescriptor put(String key, NamedArgumentDescriptor value) { + NamedArgumentDescriptor oldValue = super.put(key, value); if (oldValue != null) { super.put(key, oldValue); } @@ -120,152 +108,4 @@ public abstract class GroovyNamedArgumentProvider { } return GroovyPsiManager.isInheritorCached(parameter.getType(), CommonClassNames.JAVA_UTIL_MAP); } - - public static class ArgumentDescriptor { - - private final PsiElement myNavigationElement; - - private boolean isShowFirst = true; - - public ArgumentDescriptor() { - this(null); - } - - public ArgumentDescriptor(@Nullable PsiElement navigationElement) { - this.myNavigationElement = navigationElement; - } - - public boolean isShowFirst() { - return isShowFirst; - } - - public ArgumentDescriptor setShowFirst(boolean showFirst) { - isShowFirst = showFirst; - return this; - } - - public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { - return true; - } - - @Nullable - public PsiPolyVariantReference createReference(@NotNull GrArgumentLabel element) { - final PsiElement navigationElement = getNavigationElement(); - if (navigationElement == null) return null; - - return new NamedArgumentReference(element, navigationElement); - } - - @Nullable - public PsiElement getNavigationElement() { - return myNavigationElement; - } - - public static class NamedArgumentReference extends PsiPolyVariantReferenceBase { - private final PsiElement myNavigationElement; - - public NamedArgumentReference(GrArgumentLabel element, @NotNull PsiElement navigationElement) { - super(element); - myNavigationElement = navigationElement; - } - - @Override - public PsiElement resolve() { - return myNavigationElement; - } - - @Override - public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { - if (element == myNavigationElement) return getElement(); - return super.bindToElement(element); - } - - @Override - public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - final PsiElement resolved = resolve(); - - if (resolved instanceof PsiMethod) { - final PsiMethod method = (PsiMethod) resolved; - final String oldName = getElement().getName(); - if (!method.getName().equals(oldName)) { //was property reference to accessor - if (PropertyUtil.isSimplePropertySetter(method)) { - final String newPropertyName = PropertyUtil.getPropertyName(newElementName); - if (newPropertyName != null) { - newElementName = newPropertyName; - } - } - } - } - - return super.handleElementRename(newElementName); - } - - @NotNull - @Override - public Object[] getVariants() { - return ArrayUtil.EMPTY_OBJECT_ARRAY; - } - - @NotNull - @Override - public ResolveResult[] multiResolve(boolean incompleteCode) { - return new ResolveResult[]{new GroovyResolveResultImpl(myNavigationElement, true)}; - } - } - } - - protected static class StringTypeCondition extends ArgumentDescriptor { - private final String myTypeName; - - public StringTypeCondition(String typeName) { - this(typeName, null); - } - - public StringTypeCondition(String typeName, @Nullable PsiElement navigationElement) { - super(navigationElement); - myTypeName = typeName; - } - - @Override - public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { - return GroovyPsiManager.isInheritorCached(type, myTypeName); - } - } - - protected static class StringArrayTypeCondition extends ArgumentDescriptor { - private final String[] myTypeNames; - - public StringArrayTypeCondition(String... typeNames) { - this(null, typeNames); - } - - public StringArrayTypeCondition(@Nullable PsiElement navigationElement, String... typeNames) { - super(navigationElement); - this.myTypeNames = typeNames; - } - - @Override - public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { - for (String typeName : myTypeNames) { - if (GroovyPsiManager.isInheritorCached(type, typeName)) { - return true; - } - } - return false; - } - } - - public static class TypeCondition extends ArgumentDescriptor { - private final PsiType myType; - - public TypeCondition(PsiType type, PsiElement navigationElement) { - super(navigationElement); - myType = type; - } - - @Override - public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { - return TypesUtil.isAssignable(myType, type, context); - } - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/NamedArgumentDescriptor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/NamedArgumentDescriptor.java new file mode 100644 index 000000000000..b25c0ac93200 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/NamedArgumentDescriptor.java @@ -0,0 +1,240 @@ +/* + * Copyright 2000-2011 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.extensions; + +import com.intellij.psi.*; +import com.intellij.psi.util.PropertyUtil; +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.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; + +/** +* @author Sergey Evdokimov +*/ +public class NamedArgumentDescriptor { + + public static final NamedArgumentDescriptor SIMPLE_ON_TOP = new UnmodifiableDescriptor(Priority.ALWAYS_ON_TOP); + public static final NamedArgumentDescriptor SIMPLE_AS_LOCAL_VAR = new UnmodifiableDescriptor(Priority.AS_LOCAL_VARIABLE); + public static final NamedArgumentDescriptor SIMPLE_NORMAL = new UnmodifiableDescriptor(Priority.NORMAL); + public static final NamedArgumentDescriptor SIMPLE_UNLIKELY = new UnmodifiableDescriptor(Priority.UNLIKELY); + + public static final StringTypeConditionWithPriority TYPE_STRING = new StringTypeConditionWithPriority(CommonClassNames.JAVA_LANG_STRING); + public static final StringTypeConditionWithPriority TYPE_MAP = new StringTypeConditionWithPriority(CommonClassNames.JAVA_UTIL_MAP); + public static final StringTypeConditionWithPriority TYPE_BOOL = new StringTypeConditionWithPriority(CommonClassNames.JAVA_LANG_BOOLEAN); + public static final StringTypeConditionWithPriority TYPE_CLASS = new StringTypeConditionWithPriority(CommonClassNames.JAVA_LANG_CLASS); + public static final StringTypeConditionWithPriority TYPE_INTEGER = new StringTypeConditionWithPriority(CommonClassNames.JAVA_LANG_INTEGER); + + private final PsiElement myNavigationElement; + + private Priority myPriority = Priority.ALWAYS_ON_TOP; + + public NamedArgumentDescriptor() { + this(null); + } + + public NamedArgumentDescriptor(@Nullable PsiElement navigationElement) { + this.myNavigationElement = navigationElement; + } + + @NotNull + public Priority getPriority() { + return myPriority; + } + + public NamedArgumentDescriptor setPriority(@NotNull Priority priority) { + myPriority = priority; + return this; + } + + public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { + return true; + } + + @Nullable + public PsiPolyVariantReference createReference(@NotNull GrArgumentLabel element) { + final PsiElement navigationElement = getNavigationElement(); + if (navigationElement == null) return null; + + return new NamedArgumentReference(element, navigationElement); + } + + @Nullable + public PsiElement getNavigationElement() { + return myNavigationElement; + } + + public static class NamedArgumentReference extends PsiPolyVariantReferenceBase { + private final PsiElement myNavigationElement; + + public NamedArgumentReference(GrArgumentLabel element, @NotNull PsiElement navigationElement) { + super(element); + myNavigationElement = navigationElement; + } + + @Override + public PsiElement resolve() { + return myNavigationElement; + } + + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + if (element == myNavigationElement) return getElement(); + return super.bindToElement(element); + } + + @Override + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + final PsiElement resolved = resolve(); + + if (resolved instanceof PsiMethod) { + final PsiMethod method = (PsiMethod) resolved; + final String oldName = getElement().getName(); + if (!method.getName().equals(oldName)) { //was property reference to accessor + if (PropertyUtil.isSimplePropertySetter(method)) { + final String newPropertyName = PropertyUtil.getPropertyName(newElementName); + if (newPropertyName != null) { + newElementName = newPropertyName; + } + } + } + } + + return super.handleElementRename(newElementName); + } + + @NotNull + @Override + public Object[] getVariants() { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + @NotNull + @Override + public ResolveResult[] multiResolve(boolean incompleteCode) { + return new ResolveResult[]{new GroovyResolveResultImpl(myNavigationElement, true)}; + } + } + + public static enum Priority { + ALWAYS_ON_TOP, + AS_LOCAL_VARIABLE, + NORMAL, + UNLIKELY + } + + private static class StringTypeConditionWithPriority extends StringTypeCondition { + + private StringTypeConditionWithPriority[] myInstances; + + public StringTypeConditionWithPriority(String typeName) { + this(typeName, Priority.ALWAYS_ON_TOP, new StringTypeConditionWithPriority[Priority.values().length]); + } + + private StringTypeConditionWithPriority(String typeName, Priority priority, StringTypeConditionWithPriority[] instances) { + super(typeName); + myInstances = instances; + super.setPriority(priority); + instances[priority.ordinal()] = this; + } + + public StringTypeConditionWithPriority withPriority(Priority priority) { + StringTypeConditionWithPriority res = myInstances[priority.ordinal()]; + if (res == null) { + res = new StringTypeConditionWithPriority(myTypeName, priority, myInstances); + } + + return res; + } + + @Override + public NamedArgumentDescriptor setPriority(@NotNull Priority priority) { + throw new UnsupportedOperationException("Use withPriority(priority)"); + } + } + + public static class StringTypeCondition extends NamedArgumentDescriptor { + protected final String myTypeName; + + public StringTypeCondition(String typeName) { + this(typeName, null); + } + + public StringTypeCondition(String typeName, @Nullable PsiElement navigationElement) { + super(navigationElement); + myTypeName = typeName; + } + + @Override + public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { + return GroovyPsiManager.isInheritorCached(type, myTypeName); + } + } + + public static class StringArrayTypeCondition extends NamedArgumentDescriptor { + private final String[] myTypeNames; + + public StringArrayTypeCondition(String... typeNames) { + this(null, typeNames); + } + + public StringArrayTypeCondition(@Nullable PsiElement navigationElement, String... typeNames) { + super(navigationElement); + this.myTypeNames = typeNames; + } + + @Override + public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { + for (String typeName : myTypeNames) { + if (GroovyPsiManager.isInheritorCached(type, typeName)) { + return true; + } + } + return false; + } + } + + public static class TypeCondition extends NamedArgumentDescriptor { + private final PsiType myType; + + public TypeCondition(@NotNull PsiType type, @Nullable PsiElement navigationElement) { + super(navigationElement); + myType = type; + } + + @Override + public boolean checkType(@NotNull PsiType type, @NotNull GroovyPsiElement context) { + return TypesUtil.isAssignable(myType, type, context); + } + } + + private static class UnmodifiableDescriptor extends NamedArgumentDescriptor { + public UnmodifiableDescriptor(Priority priority) { + super.setPriority(priority); + } + + @Override + public NamedArgumentDescriptor setPriority(@NotNull Priority priority) { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java index 4dfd8afe820d..1930fc665b11 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java @@ -23,7 +23,9 @@ import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.InheritanceUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; @@ -41,6 +43,7 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; import java.util.EnumSet; import java.util.Map; +import static org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor.*; import static org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint.ResolveKind.*; /** @@ -55,7 +58,7 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP @Nullable PsiElement resolve, @Nullable String argumentName, boolean forCompletion, - Map result) { + Map result) { if (!(call instanceof GrNewExpression)) return; if (resolve != null) { @@ -91,7 +94,7 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP public static void processClass(@NotNull GrCall call, PsiClassType type, @Nullable String argumentName, - Map result) { + Map result) { if (argumentName == null) { ResolveUtil.processAllDeclarations(type, new MyPsiScopeProcessor(result, call), ResolveState.initial(), call); } @@ -125,16 +128,16 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP private static class MyPsiScopeProcessor implements PsiScopeProcessor, NameHint, ClassHint, ElementClassHint { private final String myNameHint; - private final Map myResult; + private final Map myResult; private final EnumSet myResolveTargetKinds; - private MyPsiScopeProcessor(Map result, GroovyPsiElement context) { + private MyPsiScopeProcessor(Map result, GroovyPsiElement context) { myResolveTargetKinds = ResolverProcessor.RESOLVE_KINDS_METHOD_PROPERTY; myNameHint = null; myResult = result; } - private MyPsiScopeProcessor(@NotNull String propertyName, boolean findSetter, Map result, GroovyPsiElement context) { + private MyPsiScopeProcessor(@NotNull String propertyName, boolean findSetter, Map result, GroovyPsiElement context) { if (findSetter) { myResolveTargetKinds = ResolverProcessor.RESOLVE_KINDS_METHOD; myNameHint = GroovyPropertyUtils.getSetterName(propertyName); @@ -176,7 +179,7 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP type = substitutor.substitute(type); } - myResult.put(propertyName, new TypeCondition(type, element)); + myResult.put(propertyName, new NamedArgumentDescriptor.TypeCondition(type, element).setPriority(Priority.AS_LOCAL_VARIABLE)); } return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyMethodReturnNamedArgumentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyMethodReturnNamedArgumentProvider.java index b12c57a6839b..8281940ed2c4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyMethodReturnNamedArgumentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyMethodReturnNamedArgumentProvider.java @@ -22,6 +22,8 @@ import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import java.util.HashMap; @@ -36,18 +38,18 @@ public class GroovyMethodReturnNamedArgumentProvider extends GroovyNamedArgument @Nullable PsiElement resolve, @Nullable String argumentName, boolean forCompletion, - Map result) { + Map result) { if (!forCompletion || !(resolve instanceof PsiMethod)) return; PsiType returnType = ((PsiMethod)resolve).getReturnType(); if (!(returnType instanceof PsiClassType)) return; - Map map = new HashMap(); + Map map = new HashMap(); GroovyConstructorNamedArgumentProvider.processClass(call, (PsiClassType)returnType, argumentName, map); for (String name : map.keySet()) { - result.put(name, TYPE_ANY_NOT_FIRST); + result.put(name, NamedArgumentDescriptor.SIMPLE_UNLIKELY); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java index a9a0e95608d0..06d0675f0d11 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java @@ -19,6 +19,8 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrNamedArgumentSearchVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; @@ -36,7 +38,7 @@ public class GroovySourceCodeNamedArgumentProvider extends GroovyNamedArgumentPr @Nullable PsiElement resolve, @Nullable String argumentName, boolean forCompletion, - Map result) { + Map result) { if (!forCompletion) return; String[] namedParametersArray; @@ -55,7 +57,7 @@ public class GroovySourceCodeNamedArgumentProvider extends GroovyNamedArgumentPr } for (String parameter : namedParametersArray) { - result.put(parameter, TYPE_ANY); + result.put(parameter, NamedArgumentDescriptor.SIMPLE_ON_TOP); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java index ec3dbcac2184..7da500144091 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java @@ -25,6 +25,7 @@ import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyIcons; import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter; import org.jetbrains.plugins.groovy.lang.completion.handlers.NamedArgumentInsertHandler; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; @@ -88,9 +89,8 @@ class MapArgumentCompletionProvider extends CompletionProvider map = calcNamedArgumentsForCall(mapOrArgumentList); - boolean sure = !map.isEmpty(); - if (!sure) { + Map map = calcNamedArgumentsForCall(mapOrArgumentList); + if (map.isEmpty()) { map = findOtherNamedArgumentsInFile(mapOrArgumentList); } @@ -98,33 +98,32 @@ class MapArgumentCompletionProvider extends CompletionProvider entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { LookupElementBuilder lookup = LookupElementBuilder.create(entry.getValue(), entry.getKey()) .setInsertHandler(NamedArgumentInsertHandler.INSTANCE) .setTailText(":"); - if (sure) { - lookup = lookup.setIcon(GroovyIcons.DYNAMIC); - } else { - lookup = lookup.setItemTextForeground(DefaultHighlighter.MAP_KEY_COLOR); + if (entry.getValue().getPriority() == NamedArgumentDescriptor.Priority.UNLIKELY) { + lookup.setItemTextForeground(DefaultHighlighter.MAP_KEY_COLOR); } - + else { + lookup = lookup.setIcon(GroovyIcons.DYNAMIC); + } + result.addElement(lookup); } } - private static Map findOtherNamedArgumentsInFile(PsiElement mapOrArgumentList) { - final Map map = new HashMap(); + private static Map findOtherNamedArgumentsInFile(PsiElement mapOrArgumentList) { + final Map map = new HashMap(); mapOrArgumentList.getContainingFile().accept(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { if (element instanceof GrArgumentLabel) { final String name = ((GrArgumentLabel)element).getName(); if (GroovyNamesUtil.isIdentifier(name)) { - GroovyNamedArgumentProvider.ArgumentDescriptor descriptor = new GroovyNamedArgumentProvider.ArgumentDescriptor(); - descriptor.setShowFirst(false); - map.put(name, descriptor); + map.put(name, NamedArgumentDescriptor.SIMPLE_UNLIKELY); } } super.visitElement(element); @@ -148,7 +147,7 @@ class MapArgumentCompletionProvider extends CompletionProvider calcNamedArgumentsForCall(PsiElement mapOrArgumentList) { + private static Map calcNamedArgumentsForCall(PsiElement mapOrArgumentList) { PsiElement argumentList = mapOrArgumentList instanceof GrArgumentList ? mapOrArgumentList : mapOrArgumentList.getParent(); if (argumentList instanceof GrArgumentList) { if (mapOrArgumentList instanceof GrListOrMap) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java index 26c416e5e63d..73c2337382e5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java @@ -23,7 +23,7 @@ import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; +import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; 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.GrExpression; @@ -62,8 +62,15 @@ public class GrKindWeigher extends CompletionWeigher { final PsiElement qualifier = parent.getQualifier(); if (qualifier == null) { - if (o instanceof GroovyNamedArgumentProvider.ArgumentDescriptor) { - return ((GroovyNamedArgumentProvider.ArgumentDescriptor)o).isShowFirst() ? NotQualifiedKind.local : NotQualifiedKind.unknown; + if (o instanceof NamedArgumentDescriptor) { + switch (((NamedArgumentDescriptor)o).getPriority()) { + case ALWAYS_ON_TOP: + return NotQualifiedKind.onTop; + case AS_LOCAL_VARIABLE: + return NotQualifiedKind.local; + default: + return NotQualifiedKind.unknown; + } } if (o instanceof PsiVariable && !(o instanceof PsiField)) { return NotQualifiedKind.local; @@ -135,6 +142,7 @@ public class GrKindWeigher extends CompletionWeigher { member, currentClassMember, local, + onTop } private static enum QualifiedKind { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java index 44142dddea42..fa9ba5accff3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java @@ -27,6 +27,7 @@ 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.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; @@ -78,7 +79,7 @@ public class GrArgumentLabelImpl extends GroovyPsiElementImpl implements GrArgum String labelName = getName(); - GroovyNamedArgumentProvider.ArgumentDescriptor descr = + NamedArgumentDescriptor descr = GroovyNamedArgumentProvider.getNamedArgumentsFromAllProviders(call, labelName, false).get(labelName); if (descr != null) {