@Override public boolean execute(PsiElement element, ResolveState state) { if (element instanceof PsiMethod || element instanceof PsiField) { String propertyName; PsiType type; if (element instanceof PsiMethod) { PsiMethod method = (PsiMethod) element; if (!GroovyPropertyUtils.isSimplePropertySetter(method)) return true; propertyName = GroovyPropertyUtils.getPropertyNameBySetter(method); if (propertyName == null) return true; type = method.getParameterList().getParameters()[0].getType(); } else { type = ((PsiField) element).getType(); propertyName = ((PsiField) element).getName(); } if (((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC)) return true; if (myResult.containsKey(propertyName) || propertyName.equals(METACLASS)) return true; PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY); if (substitutor != null) { type = substitutor.substitute(type); } myResult.put(propertyName, new TypeCondition(type, element)); } return true; }
@Override public void getNamedArguments( @NotNull GrCall call, @Nullable PsiElement resolve, @Nullable String argumentName, boolean forCompletion, Map<String, ArgumentDescriptor> result) { if (!(call instanceof GrNewExpression)) return; if (resolve != null) { if (!(resolve instanceof PsiMethod)) return; PsiMethod method = (PsiMethod) resolve; if (!method.isConstructor()) return; } GrNewExpression newCall = (GrNewExpression) call; GrArgumentList argumentList = newCall.getArgumentList(); if (argumentList == null) return; GrExpression[] expressionArguments = argumentList.getExpressionArguments(); if (expressionArguments.length > 1 || (expressionArguments.length == 1 && !(expressionArguments[0] instanceof GrReferenceExpression))) { return; } for (GroovyResolveResult resolveResult : newCall.multiResolveClass()) { PsiElement element = resolveResult.getElement(); if (!(element instanceof PsiClass)) continue; PsiClass aClass = (PsiClass) element; if (!isClassHasConstructorWithMap(aClass)) continue; PsiClassType classType = JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass); processClass(call, classType, argumentName, result); } }
private static boolean isClassHasConstructorWithMap(PsiClass aClass) { PsiMethod[] constructors = aClass.getConstructors(); if (constructors.length == 0) return true; for (PsiMethod constructor : constructors) { PsiParameterList parameterList = constructor.getParameterList(); PsiParameter[] parameters = parameterList.getParameters(); if (parameters.length == 0) return true; final PsiParameter first = parameters[0]; if (InheritanceUtil.isInheritor(first.getType(), CommonClassNames.JAVA_UTIL_MAP)) return true; if (first instanceof GrParameter && ((GrParameter) first).getTypeGroovy() == null) return true; // if constructor has only optional parameters it can be used as default constructor with map // args if (!PsiUtil.isConstructorHasRequiredParameters(constructor)) return true; } return false; }