diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java index 2520296bee44..7fb4c1c734b1 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java @@ -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 methodsToAdd = getExpandingMethods(candidateInfo); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrReflectedMethodImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrReflectedMethodImpl.java index c67c34c30cab..975e58450ed3 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrReflectedMethodImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrReflectedMethodImpl.java @@ -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 diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr23HighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr23HighlightingTest.groovy index af114c2eb513..d252a583dedb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr23HighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr23HighlightingTest.groovy @@ -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 implements GenericTrait {} class ConcreteClassGenericTrait implements GenericTrait {} ''') } + + void 'test abstract method with default parameters in abstract class'() { + testHighlighting '''\ +abstract class A { abstract foo(x, y = 3) } +class B extends A {} +''' + 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) } +class B implements A {} +''' + 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, '''\ +class C implements T {} +''' + 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; } +} +''' + 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 + } }