Refactor ImplementationBodyCodegen.getTraitImplementations()
Make it static, extract a method which finds an implementation in a trait for a fake override
This commit is contained in:
@@ -1815,58 +1815,63 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
* Return pairs of descriptors. First is member of this that should be implemented by delegating to trait,
|
* Return pairs of descriptors. First is member of this that should be implemented by delegating to trait,
|
||||||
* second is member of trait that contain implementation.
|
* second is member of trait that contain implementation.
|
||||||
*/
|
*/
|
||||||
private List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> getTraitImplementations(@NotNull ClassDescriptor classDescriptor) {
|
@NotNull
|
||||||
List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> r = Lists.newArrayList();
|
private static List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> getTraitImplementations(@NotNull ClassDescriptor classDescriptor) {
|
||||||
|
List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> result = Lists.newArrayList();
|
||||||
|
|
||||||
for (DeclarationDescriptor decl : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
for (DeclarationDescriptor declaration : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||||
if (!(decl instanceof CallableMemberDescriptor)) {
|
if (!(declaration instanceof CallableMemberDescriptor)) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) decl;
|
CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) declaration;
|
||||||
if (callableMemberDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CallResolverUtil.isOrOverridesSynthesized(callableMemberDescriptor)) {
|
CallableMemberDescriptor implementation = findTraitImplementation(callableMemberDescriptor);
|
||||||
continue;
|
if (implementation != null) {
|
||||||
}
|
result.add(Pair.create(callableMemberDescriptor, implementation));
|
||||||
|
|
||||||
Collection<CallableMemberDescriptor> overriddenDeclarations =
|
|
||||||
OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor);
|
|
||||||
|
|
||||||
Collection<CallableMemberDescriptor> filteredOverriddenDeclarations =
|
|
||||||
OverridingUtil.filterOutOverridden(Sets.newLinkedHashSet(overriddenDeclarations));
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
CallableMemberDescriptor candidate = null;
|
|
||||||
|
|
||||||
for (CallableMemberDescriptor overriddenDeclaration : filteredOverriddenDeclarations) {
|
|
||||||
if (isTrait(overriddenDeclaration.getContainingDeclaration()) &&
|
|
||||||
overriddenDeclaration.getModality() != Modality.ABSTRACT) {
|
|
||||||
candidate = overriddenDeclaration;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (candidate == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert count == 1 : "Ambiguous overridden declaration: " + callableMemberDescriptor.getName();
|
|
||||||
|
|
||||||
|
|
||||||
Collection<JetType> superTypesOfSuperClass =
|
|
||||||
superClassType != null ? TypeUtils.getAllSupertypes(superClassType) : Collections.<JetType>emptySet();
|
|
||||||
ReceiverParameterDescriptor expectedThisObject = candidate.getExpectedThisObject();
|
|
||||||
assert expectedThisObject != null;
|
|
||||||
JetType candidateType = expectedThisObject.getType();
|
|
||||||
boolean implementedInSuperClass = superTypesOfSuperClass.contains(candidateType);
|
|
||||||
|
|
||||||
if (!implementedInSuperClass) {
|
|
||||||
r.add(Pair.create(callableMemberDescriptor, candidate));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r;
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a fake override descriptor, returns an overridden non-abstract descriptor whose container is a trait
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private static CallableMemberDescriptor findTraitImplementation(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
|
if (descriptor.getKind().isReal()) return null;
|
||||||
|
|
||||||
|
if (CallResolverUtil.isOrOverridesSynthesized(descriptor)) return null;
|
||||||
|
|
||||||
|
Collection<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(descriptor);
|
||||||
|
|
||||||
|
Collection<CallableMemberDescriptor> filteredOverriddenDeclarations =
|
||||||
|
OverridingUtil.filterOutOverridden(Sets.newLinkedHashSet(overriddenDeclarations));
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
CallableMemberDescriptor implementation = null;
|
||||||
|
|
||||||
|
for (CallableMemberDescriptor overriddenDeclaration : filteredOverriddenDeclarations) {
|
||||||
|
if (isTrait(overriddenDeclaration.getContainingDeclaration()) && overriddenDeclaration.getModality() != Modality.ABSTRACT) {
|
||||||
|
implementation = overriddenDeclaration;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (implementation == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert count == 1 : "Ambiguous overridden declaration: " + descriptor;
|
||||||
|
|
||||||
|
ClassDescriptor containingClass = (ClassDescriptor) descriptor.getContainingDeclaration();
|
||||||
|
for (JetType supertype : containingClass.getDefaultType().getConstructor().getSupertypes()) {
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
if (!isTrait(supertype.getConstructor().getDeclarationDescriptor()) &&
|
||||||
|
TypeUtils.getAllSupertypes(supertype).contains(implementation.getExpectedThisObject().getType())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implementation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addClassObjectPropertyToCopy(PropertyDescriptor descriptor, Object defaultValue) {
|
public void addClassObjectPropertyToCopy(PropertyDescriptor descriptor, Object defaultValue) {
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
trait A {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B : A
|
||||||
|
|
||||||
|
open class C : B()
|
||||||
|
|
||||||
|
class D : C()
|
||||||
|
|
||||||
|
// Implementation of foo() should only be generated into B
|
||||||
|
// 1 INVOKESTATIC A\$\$TImpl.foo
|
||||||
|
|
||||||
|
// Only two declarations should be present: in A and B
|
||||||
|
// 2 foo\(\)I
|
||||||
@@ -122,6 +122,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
doTest("compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt");
|
doTest("compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("traitImplGeneratedOnce.kt")
|
||||||
|
public void testTraitImplGeneratedOnce() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/bytecodeText/traitImplGeneratedOnce.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeText/constants")
|
@TestMetadata("compiler/testData/codegen/bytecodeText/constants")
|
||||||
public static class Constants extends AbstractBytecodeTextTest {
|
public static class Constants extends AbstractBytecodeTextTest {
|
||||||
public void testAllFilesPresentInConstants() throws Exception {
|
public void testAllFilesPresentInConstants() throws Exception {
|
||||||
|
|||||||
+73
-58
@@ -5075,6 +5075,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/traits")
|
@TestMetadata("compiler/testData/codegen/box/traits")
|
||||||
|
@InnerTestClasses({Traits.WithRequired.class})
|
||||||
public static class Traits extends AbstractBlackBoxCodegenTest {
|
public static class Traits extends AbstractBlackBoxCodegenTest {
|
||||||
public void testAllFilesPresentInTraits() throws Exception {
|
public void testAllFilesPresentInTraits() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box/traits"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box/traits"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
@@ -5110,11 +5111,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest("compiler/testData/codegen/box/traits/kt1936_1.kt");
|
doTest("compiler/testData/codegen/box/traits/kt1936_1.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("kt1936_2.kt")
|
|
||||||
public void testKt1936_2() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/kt1936_2.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("kt2260.kt")
|
@TestMetadata("kt2260.kt")
|
||||||
public void testKt2260() throws Exception {
|
public void testKt2260() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/traits/kt2260.kt");
|
doTest("compiler/testData/codegen/box/traits/kt2260.kt");
|
||||||
@@ -5130,26 +5126,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest("compiler/testData/codegen/box/traits/kt2541.kt");
|
doTest("compiler/testData/codegen/box/traits/kt2541.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("kt2963.kt")
|
|
||||||
public void testKt2963() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/kt2963.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("kt3315.kt")
|
@TestMetadata("kt3315.kt")
|
||||||
public void testKt3315() throws Exception {
|
public void testKt3315() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/traits/kt3315.kt");
|
doTest("compiler/testData/codegen/box/traits/kt3315.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("kt3413.kt")
|
|
||||||
public void testKt3413() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/kt3413.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("kt3429.kt")
|
|
||||||
public void testKt3429() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/kt3429.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("kt3500.kt")
|
@TestMetadata("kt3500.kt")
|
||||||
public void testKt3500() throws Exception {
|
public void testKt3500() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/traits/kt3500.kt");
|
doTest("compiler/testData/codegen/box/traits/kt3500.kt");
|
||||||
@@ -5160,51 +5141,85 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest("compiler/testData/codegen/box/traits/multiple.kt");
|
doTest("compiler/testData/codegen/box/traits/multiple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("simple.kt")
|
|
||||||
public void testSimple() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/simple.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("stdlib.kt")
|
@TestMetadata("stdlib.kt")
|
||||||
public void testStdlib() throws Exception {
|
public void testStdlib() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/traits/stdlib.kt");
|
doTest("compiler/testData/codegen/box/traits/stdlib.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("traitFuncCall.kt")
|
@TestMetadata("compiler/testData/codegen/box/traits/withRequired")
|
||||||
public void testTraitFuncCall() throws Exception {
|
public static class WithRequired extends AbstractBlackBoxCodegenTest {
|
||||||
doTest("compiler/testData/codegen/box/traits/traitFuncCall.kt");
|
public void testAllFilesPresentInWithRequired() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box/traits/withRequired"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("generic.kt")
|
||||||
|
public void testGeneric() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/generic.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericProperty.kt")
|
||||||
|
public void testGenericProperty() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/genericProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt1936_2.kt")
|
||||||
|
public void testKt1936_2() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/kt1936_2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt2963.kt")
|
||||||
|
public void testKt2963() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/kt2963.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt3413.kt")
|
||||||
|
public void testKt3413() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/kt3413.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt3429.kt")
|
||||||
|
public void testKt3429() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/kt3429.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("property.kt")
|
||||||
|
public void testProperty() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/property.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyViaBridge.kt")
|
||||||
|
public void testPropertyViaBridge() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/propertyViaBridge.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/simple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("super.kt")
|
||||||
|
public void testSuper() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/super.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("superViaBridge.kt")
|
||||||
|
public void testSuperViaBridge() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/superViaBridge.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("traitFuncCall.kt")
|
||||||
|
public void testTraitFuncCall() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/traits/withRequired/traitFuncCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("withRequired.kt")
|
public static Test innerSuite() {
|
||||||
public void testWithRequired() throws Exception {
|
TestSuite suite = new TestSuite("Traits");
|
||||||
doTest("compiler/testData/codegen/box/traits/withRequired.kt");
|
suite.addTestSuite(Traits.class);
|
||||||
|
suite.addTestSuite(WithRequired.class);
|
||||||
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("withRequiredGenericProperty.kt")
|
|
||||||
public void testWithRequiredGenericProperty() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/withRequiredGenericProperty.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("withRequiredProperty.kt")
|
|
||||||
public void testWithRequiredProperty() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/withRequiredProperty.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("withRequiredPropertyViaBridge.kt")
|
|
||||||
public void testWithRequiredPropertyViaBridge() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/withRequiredPropertyViaBridge.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("withRequiredSuper.kt")
|
|
||||||
public void testWithRequiredSuper() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/withRequiredSuper.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("withRequiredSuperViaBridge.kt")
|
|
||||||
public void testWithRequiredSuperViaBridge() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/traits/withRequiredSuperViaBridge.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/typeInfo")
|
@TestMetadata("compiler/testData/codegen/box/typeInfo")
|
||||||
@@ -5551,7 +5566,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
suite.addTestSuite(Strings.class);
|
suite.addTestSuite(Strings.class);
|
||||||
suite.addTestSuite(Super.class);
|
suite.addTestSuite(Super.class);
|
||||||
suite.addTestSuite(ToArray.class);
|
suite.addTestSuite(ToArray.class);
|
||||||
suite.addTestSuite(Traits.class);
|
suite.addTest(Traits.innerSuite());
|
||||||
suite.addTestSuite(TypeInfo.class);
|
suite.addTestSuite(TypeInfo.class);
|
||||||
suite.addTestSuite(TypeMapping.class);
|
suite.addTestSuite(TypeMapping.class);
|
||||||
suite.addTestSuite(UnaryOp.class);
|
suite.addTestSuite(UnaryOp.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user