Provide priority for named arguments.

This commit is contained in:
Sergey Evdokimov
2011-10-21 19:32:26 +04:00
parent 965831f7e0
commit 1bef31ed5c
11 changed files with 313 additions and 214 deletions
@@ -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<String, GroovyNamedArgumentProvider.ArgumentDescriptor> map = GroovyNamedArgumentProvider.getNamedArgumentsFromAllProviders(call, null, false);
Map<String, NamedArgumentDescriptor> 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;
@@ -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<String, GroovyNamedArgumentProvider.ArgumentDescriptor> getArgumentsMap() {
public Map<String, NamedArgumentDescriptor> getArgumentsMap() {
if (myArguments == null && namedArgs == null) {
assert isNamedArgsShowFirst == null;
return null;
@@ -100,12 +103,12 @@ public class GroovyMethodDescriptor extends AbstractExtensionPointBean {
assert namedArgsProvider == null;
Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> res =
new HashMap<String, GroovyNamedArgumentProvider.ArgumentDescriptor>();
Map<String, NamedArgumentDescriptor> res =
new HashMap<String, NamedArgumentDescriptor>();
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;
@@ -27,7 +27,7 @@ public class GroovyMethodInfo {
private final String myReturnTypeCalculatorClassName;
private PairFunction<GrMethodCall, PsiMethod, PsiType> myReturnTypeCalculatorInstance;
private final Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> myNamedArguments;
private final Map<String, NamedArgumentDescriptor> myNamedArguments;
private final String myNamedArgProviderClassName;
private GroovyNamedArgumentProvider myNamedArgProviderInstance;
@@ -185,7 +185,7 @@ public class GroovyMethodInfo {
}
@Nullable
public Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> getNamedArguments() {
public Map<String, NamedArgumentDescriptor> getNamedArguments() {
return myNamedArguments;
}
@@ -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<GroovyNamedArgumentProvider> 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<String, ArgumentDescriptor> result);
Map<String, NamedArgumentDescriptor> result);
public static Map<String, ArgumentDescriptor> getNamedArgumentsFromAllProviders(@NotNull GrCall call,
public static Map<String, NamedArgumentDescriptor> getNamedArgumentsFromAllProviders(@NotNull GrCall call,
@Nullable String argumentName,
boolean forCompletion) {
Map<String, ArgumentDescriptor> namedArguments = new HashMap<String, ArgumentDescriptor>() {
Map<String, NamedArgumentDescriptor> namedArguments = new HashMap<String, NamedArgumentDescriptor>() {
@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<GrArgumentLabel> {
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);
}
}
}
@@ -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<GrArgumentLabel> {
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();
}
}
}
@@ -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<String, ArgumentDescriptor> result) {
Map<String, NamedArgumentDescriptor> 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<String, ArgumentDescriptor> result) {
Map<String, NamedArgumentDescriptor> 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<String, ArgumentDescriptor> myResult;
private final Map<String, NamedArgumentDescriptor> myResult;
private final EnumSet<ResolveKind> myResolveTargetKinds;
private MyPsiScopeProcessor(Map<String, ArgumentDescriptor> result, GroovyPsiElement context) {
private MyPsiScopeProcessor(Map<String, NamedArgumentDescriptor> result, GroovyPsiElement context) {
myResolveTargetKinds = ResolverProcessor.RESOLVE_KINDS_METHOD_PROPERTY;
myNameHint = null;
myResult = result;
}
private MyPsiScopeProcessor(@NotNull String propertyName, boolean findSetter, Map<String, ArgumentDescriptor> result, GroovyPsiElement context) {
private MyPsiScopeProcessor(@NotNull String propertyName, boolean findSetter, Map<String, NamedArgumentDescriptor> 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;
@@ -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<String, ArgumentDescriptor> result) {
Map<String, NamedArgumentDescriptor> result) {
if (!forCompletion || !(resolve instanceof PsiMethod)) return;
PsiType returnType = ((PsiMethod)resolve).getReturnType();
if (!(returnType instanceof PsiClassType)) return;
Map<String, ArgumentDescriptor> map = new HashMap<String, ArgumentDescriptor>();
Map<String, NamedArgumentDescriptor> map = new HashMap<String, NamedArgumentDescriptor>();
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);
}
}
}
@@ -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<String, ArgumentDescriptor> result) {
Map<String, NamedArgumentDescriptor> 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);
}
}
}
@@ -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<CompletionParamet
}
}
Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> map = calcNamedArgumentsForCall(mapOrArgumentList);
boolean sure = !map.isEmpty();
if (!sure) {
Map<String, NamedArgumentDescriptor> map = calcNamedArgumentsForCall(mapOrArgumentList);
if (map.isEmpty()) {
map = findOtherNamedArgumentsInFile(mapOrArgumentList);
}
@@ -98,33 +98,32 @@ class MapArgumentCompletionProvider extends CompletionProvider<CompletionParamet
map.remove(argument.getLabelName());
}
for (Map.Entry<String, GroovyNamedArgumentProvider.ArgumentDescriptor> entry : map.entrySet()) {
for (Map.Entry<String, NamedArgumentDescriptor> 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<String, GroovyNamedArgumentProvider.ArgumentDescriptor> findOtherNamedArgumentsInFile(PsiElement mapOrArgumentList) {
final Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> map = new HashMap<String, GroovyNamedArgumentProvider.ArgumentDescriptor>();
private static Map<String, NamedArgumentDescriptor> findOtherNamedArgumentsInFile(PsiElement mapOrArgumentList) {
final Map<String, NamedArgumentDescriptor> map = new HashMap<String, NamedArgumentDescriptor>();
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<CompletionParamet
return GrNamedArgument.EMPTY_ARRAY;
}
private static Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> calcNamedArgumentsForCall(PsiElement mapOrArgumentList) {
private static Map<String, NamedArgumentDescriptor> calcNamedArgumentsForCall(PsiElement mapOrArgumentList) {
PsiElement argumentList = mapOrArgumentList instanceof GrArgumentList ? mapOrArgumentList : mapOrArgumentList.getParent();
if (argumentList instanceof GrArgumentList) {
if (mapOrArgumentList instanceof GrListOrMap) {
@@ -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 {
@@ -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) {