[groovy] support default parameters in abstract methods (IDEA-128293)

This commit is contained in:
Daniil Ovchinnikov
2016-03-10 19:59:22 +03:00
parent 50b3de99f1
commit 72a7eec0a4
3 changed files with 71 additions and 5 deletions
@@ -253,8 +253,13 @@ public class GrTypeDefinitionMembersCache {
protected void processTrait(@NotNull PsiClass trait, @NotNull PsiSubstitutor substitutor) {
if (trait instanceof GrTypeDefinition) {
for (GrMethod method : ((GrTypeDefinition)trait).getCodeMethods()) {
if (!method.getModifierList().hasExplicitModifier(PsiModifier.ABSTRACT)) {
addCandidate(method, substitutor);
GrReflectedMethod[] reflectedMethods = method.getReflectedMethods();
if (reflectedMethods.length == 0) {
addIfNotAbstract(substitutor, method);
} else {
for (GrReflectedMethod reflectedMethod : reflectedMethods) {
addIfNotAbstract(substitutor, reflectedMethod);
}
}
}
@@ -275,6 +280,12 @@ public class GrTypeDefinitionMembersCache {
}
}
}
private void addIfNotAbstract(@NotNull PsiSubstitutor substitutor, GrMethod method) {
if (!method.getModifierList().hasExplicitModifier(PsiModifier.ABSTRACT)) {
addCandidate(method, substitutor);
}
}
}.getResult();
for (CandidateInfo candidateInfo : concreteTraitMethods) {
List<GrMethod> methodsToAdd = getExpandingMethods(candidateInfo);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic;
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.LightReferenceListBuilder;
@@ -27,6 +28,7 @@ import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags;
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.blocks.GrCodeBlock;
@@ -108,6 +110,10 @@ public class GrReflectedMethodImpl extends LightMethodBuilder implements GrRefle
if (isCategoryMethod) {
myModifierList.addModifier(PsiModifier.STATIC);
}
if (mySkippedParameters.length != 0) {
myModifierList.removeModifier(GrModifierFlags.ABSTRACT_MASK);
}
}
private void initParameterList(GrParameter[] parameters, int optionalParams, PsiClassType categoryType) {
@@ -235,7 +241,7 @@ public class GrReflectedMethodImpl extends LightMethodBuilder implements GrRefle
@Override
public String toString() {
return "reflected method";
return getName() + " (" + StringUtil.join(getParameters(), f -> f.getType().getPresentableText() + " " + f.getName(), ", ") + ")";
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.lang.highlighting
import com.intellij.codeInspection.InspectionProfileEntry
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
@@ -411,4 +412,52 @@ class GenericClassGenericTrait<Y> implements GenericTrait<Y> {}
class ConcreteClassGenericTrait implements GenericTrait<String> {}
''')
}
void 'test abstract method with default parameters in abstract class'() {
testHighlighting '''\
abstract class A { abstract foo(x, y = 3) }
<error descr="Method 'foo' is not implemented">class B extends A</error> {}
'''
testHighlighting '''\
abstract class A { abstract foo(x, y = 3) }
class B extends A { def foo(x,y) {} }
'''
}
void 'test abstract method with default parameters in trait'() {
testHighlighting '''\
trait A { abstract foo(x, y = 3) }
<error descr="Method 'foo' is not implemented">class B implements A</error> {}
'''
testHighlighting '''\
trait A { abstract foo(x, y = 3) }
class B implements A { def foo(x,y) {} }
'''
}
void 'test abstract method with default parameters in trait from Java'() {
myFixture.addFileToProject 'test.groovy', 'trait T { abstract foo(x, y = 4) }'
myFixture.configureByText JavaFileType.INSTANCE, '''\
<error descr="Class 'C' must either be declared abstract or implement abstract method 'foo(Object)' in 'T'">class C implements T</error> {}
'''
myFixture.testHighlighting false, false, false
myFixture.configureByText JavaFileType.INSTANCE, '''\
<error descr="Class 'C' must either be declared abstract or implement abstract method 'foo(Object, Object)' in 'T'">class C implements T</error> {
public Object foo() { return null; }
public Object foo(Object x) { return null; }
}
'''
myFixture.testHighlighting false, false, false
myFixture.configureByText JavaFileType.INSTANCE, '''\
class C implements T {
public Object foo() { return null; }
public Object foo(Object x) { return null; }
public Object foo(Object x, Object y) { return null; }
}
'''
myFixture.testHighlighting false, false, false
}
}