private static void checkMethodApplicability(GroovyResolveResult methodResolveResult, PsiElement place, AnnotationHolder holder) {
final PsiElement element = methodResolveResult.getElement();
if (!(element instanceof PsiMethod)) return;
+
final PsiMethod method = (PsiMethod)element;
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(place, method.isConstructor(), true);
- if (argumentTypes != null &&
- !PsiUtil.isApplicable(argumentTypes, method, methodResolveResult.getSubstitutor(),
- methodResolveResult.getCurrentFileResolveContext() instanceof GrMethodCallExpression)) {
- PsiElement elementToHighlight = PsiUtil.getArgumentsElement(place);
- if (elementToHighlight == null) {
- elementToHighlight = place;
+ if ("call".equals(method.getName()) && place instanceof GrReferenceExpression) {
+ final GrExpression qualifierExpression = ((GrReferenceExpression)place).getQualifierExpression();
+ if (qualifierExpression != null) {
+ final PsiType type = qualifierExpression.getType();
+ if (type instanceof GrClosureType) {
+ if (!PsiUtil.isApplicable(argumentTypes, (GrClosureType)type, element.getManager())) {
+ highlightInapplicableMethodUsage(methodResolveResult, place, holder, method, argumentTypes);
+ return;
+ }
+ }
}
+ }
+ if (argumentTypes != null &&
+ !PsiUtil.isApplicable(argumentTypes, method, methodResolveResult.getSubstitutor(),
+ methodResolveResult.getCurrentFileResolveContext() instanceof GrMethodCallExpression)) {
+ highlightInapplicableMethodUsage(methodResolveResult, place, holder, method, argumentTypes);
+ }
+ }
- final String typesString = buildArgTypesList(argumentTypes);
- String message;
- final PsiClass containingClass = method.getContainingClass();
- if (containingClass != null) {
- final PsiClassType containingType = JavaPsiFacade.getInstance(method.getProject()).getElementFactory()
- .createType(containingClass, methodResolveResult.getSubstitutor());
- message = GroovyBundle.message("cannot.apply.method1", method.getName(), containingType.getInternalCanonicalText(), typesString);
- }
- else {
- message = GroovyBundle.message("cannot.apply.method.or.closure", method.getName(), typesString);
- }
- holder.createWarningAnnotation(elementToHighlight, message);
+ private static void highlightInapplicableMethodUsage(GroovyResolveResult methodResolveResult, PsiElement place, AnnotationHolder holder,
+ PsiMethod method, PsiType[] argumentTypes) {
+ PsiElement elementToHighlight = PsiUtil.getArgumentsElement(place);
+ if (elementToHighlight == null) {
+ elementToHighlight = place;
+ }
+
+ final String typesString = buildArgTypesList(argumentTypes);
+ String message;
+ final PsiClass containingClass = method.getContainingClass();
+ if (containingClass != null) {
+ final PsiClassType containingType = JavaPsiFacade.getInstance(method.getProject()).getElementFactory()
+ .createType(containingClass, methodResolveResult.getSubstitutor());
+ message = GroovyBundle.message("cannot.apply.method1", method.getName(), containingType.getInternalCanonicalText(), typesString);
+ }
+ else {
+ message = GroovyBundle.message("cannot.apply.method.or.closure", method.getName(), typesString);
}
+ holder.createWarningAnnotation(elementToHighlight, message);
}
public static boolean isDeclarationAssignment(GrReferenceExpression refExpr) {
return GroovyResolveResult.EMPTY_ARRAY;
}
- private void resolveImpl(GrReferenceExpressionImpl refExpr, ResolverProcessor processor) {
+ private static void resolveImpl(GrReferenceExpressionImpl refExpr, ResolverProcessor processor) {
GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null) {
ResolveUtil.treeWalkUp(refExpr, processor, true);
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableBase;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.params.GrParameterImpl;
public PsiElement getContext() {
return myClosure;
}
+
+ @Override
+ public boolean isOptional() {
+ return true;
+ }
+
+ @Override
+ public GrExpression getDefaultInitializer() {
+ return GroovyPsiElementFactory.getInstance(getProject()).createExpressionFromText("null");
+ }
}
import com.intellij.openapi.util.text.StringUtil;
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.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
/**
* @author ven
*/
-public class LightParameter extends LightVariableBase implements PsiParameter {
+public class LightParameter extends LightVariableBase implements GrParameter {
public static final LightParameter[] EMPTY_ARRAY = new LightParameter[0];
private final String myName;
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
- ((JavaElementVisitor) visitor).visitParameter(this);
+ ((JavaElementVisitor)visitor).visitParameter(this);
}
}
public String getName() {
return StringUtil.notNullize(myName);
}
+
+ public GrTypeElement getTypeElementGroovy() {
+ return null;
+ }
+
+ public GrExpression getDefaultInitializer() {
+ return null;
+ }
+
+ public boolean isOptional() {
+ return false;
+ }
+
+ public GrExpression getInitializerGroovy() {
+ return null;
+ }
+
+ public void setType(@Nullable PsiType type) throws IncorrectOperationException {
+ }
+
+ @NotNull
+ public PsiElement getNameIdentifierGroovy() {
+ return myNameIdentifier;
+ }
+
+ public PsiType getTypeGroovy() {
+ return getType();
+ }
+
+ public PsiType getDeclaredType() {
+ return getType();
+ }
+
+ public void accept(GroovyElementVisitor visitor) {
+ }
+
+ public void acceptChildren(GroovyElementVisitor visitor) {
+
+ }
}
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
}
return true;
- } else if (element instanceof PsiVariable) {
- if (element instanceof GrField && ((GrField) element).isProperty() ||
- isClosure((PsiVariable) element)) {
- return super.execute(element, state);
- } else {
- myInapplicableCandidates.add(new GroovyResolveResultImpl(element, myCurrentFileResolveContext, substitutor, isAccessible((PsiVariable)element), isStaticsOK((PsiVariable)element)));
+ }
+ else if (element instanceof PsiVariable) {
+ if (isApplicableClosure((PsiVariable)element)) {
+ myCandidates.add(new GroovyResolveResultImpl(element, myCurrentFileResolveContext, substitutor, isAccessible((PsiVariable)element),
+ isStaticsOK((PsiVariable)element)));
+ }
+ else {
+ myInapplicableCandidates.add(
+ new GroovyResolveResultImpl(element, myCurrentFileResolveContext, substitutor, isAccessible((PsiVariable)element),
+ isStaticsOK((PsiVariable)element)));
}
}
-
return true;
}
return substitutor;
}
- private static boolean isClosure(PsiVariable variable) {
+ private boolean isApplicableClosure(PsiVariable variable) {
if (variable instanceof GrVariable) {
- final PsiType type = ((GrVariable) variable).getTypeGroovy();
- return type != null && type.equalsToText(GrClosableBlock.GROOVY_LANG_CLOSURE);
+ final PsiType type = ((GrVariable)variable).getTypeGroovy();
+ if (type == null) return false;
+ if (type instanceof GrClosureType) {
+ return PsiUtil.isApplicable(myArgumentTypes, (GrClosureType)type, variable.getManager());
+ }
+ if (type.equalsToText(GrClosableBlock.GROOVY_LANG_CLOSURE)) return true;
}
return variable.getType().equalsToText(GrClosableBlock.GROOVY_LANG_CLOSURE);
}
return myArgumentTypes;
}
- public void setArgumentTypes(@Nullable PsiType[] argumentTypes) {
- myArgumentTypes = argumentTypes;
- }
-
@Override
public void handleEvent(Event event, Object associated) {
super.handleEvent(event, associated);
public void testMethodCallWithDefaultParameters() throws Exception {doTest();}
public void testClosureWithDefaultParameters() throws Exception {doTest();}
+ public void testClosureCallMethodWithInapplicableArguments() throws Exception {doTest();}
public void testOverlyLongMethodInspection() throws Exception {
doTest(new GroovyOverlyLongMethodInspection());
final PsiElement resolved = ref.resolve();
assertInstanceOf(resolved, PsiMethod.class);
}
+
+ public void testMethodVsField() throws Exception {
+ final PsiReference ref = configureByFile("methodVsField/A.groovy");
+ final PsiElement element = ref.resolve();
+ assertInstanceOf(element, PsiMethod.class);
+ }
}
--- /dev/null
+def foo={x, y->}
+
+print foo.call<warning descr="'call' in 'groovy.lang.Closure' cannot be applied to '(java.lang.Integer)'">(1)</warning>
+
+def bar={3}
+print bar.call()
+print bar.call(3)
\ No newline at end of file
--- /dev/null
+class Foo {
+
+
+ def bar = { 2}
+}
+
+class Bar extends Foo {
+ def bar(def it) { 3 }
+
+ public static void main(String[] args) {
+ def f = new Bar()
+
+
+ println f.ba<ref>r(3)
+ }
+
+}