Codegen: Fix origin of overloaded methods generated for constructors with @JvmOverloads

Find Usages: Add tests for declarations annotated with @JvmOverloads
 #KT-8534 Fixed
This commit is contained in:
Alexey Sedunov
2015-10-28 12:28:44 +03:00
parent b9ed3b91be
commit 1de3faf3f5
12 changed files with 115 additions and 6 deletions
@@ -38,13 +38,15 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
* If all of the parameters of the specified constructor declare default values, * If all of the parameters of the specified constructor declare default values,
* generates a no-argument constructor that passes default values for all arguments. * generates a no-argument constructor that passes default values for all arguments.
*/ */
fun generateConstructorOverloadsIfNeeded( fun generatePrimaryConstructorOverloadsIfNeeded(
constructorDescriptor: ConstructorDescriptor, constructorDescriptor: ConstructorDescriptor,
classBuilder: ClassBuilder, classBuilder: ClassBuilder,
contextKind: OwnerKind, contextKind: OwnerKind,
classOrObject: KtClassOrObject classOrObject: KtClassOrObject
) { ) {
if (generateOverloadsIfNeeded(classOrObject, constructorDescriptor, constructorDescriptor, contextKind, classBuilder)) { val methodElement = classOrObject.getPrimaryConstructor() ?: classOrObject
if (generateOverloadsIfNeeded(methodElement, constructorDescriptor, constructorDescriptor, contextKind, classBuilder)) {
return return
} }
@@ -52,7 +54,7 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
return return
} }
generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject, contextKind, generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, methodElement, contextKind,
constructorDescriptor.countDefaultParameters()) constructorDescriptor.countDefaultParameters())
} }
@@ -957,7 +957,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION, functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
DefaultParameterValueLoader.DEFAULT, null); DefaultParameterValueLoader.DEFAULT, null);
new DefaultParameterValueSubstitutor(state).generateConstructorOverloadsIfNeeded(constructorDescriptor, v, kind, myClass); new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, kind, myClass);
if (isCompanionObject(descriptor)) { if (isCompanionObject(descriptor)) {
context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext); context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext);
@@ -969,8 +969,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor);
functionCodegen.generateMethod( functionCodegen.generateMethod(
JvmDeclarationOriginKt.OtherOrigin(descriptorToDeclaration(constructorDescriptor), constructorDescriptor), JvmDeclarationOriginKt.OtherOrigin(constructor, constructorDescriptor),
constructorDescriptor, constructorContext, constructorDescriptor, constructorContext,
new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) { new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) {
@Override @Override
@@ -984,7 +986,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
DefaultParameterValueLoader.DEFAULT, null); DefaultParameterValueLoader.DEFAULT, null);
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded( new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(
myClass, constructorDescriptor, constructorDescriptor, kind, v constructor, constructorDescriptor, constructorDescriptor, kind, v
); );
} }
@@ -0,0 +1,12 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction
// OPTIONS: usages
@file:JvmName("Foo")
@JvmOverloads
fun <caret>foo(
x: Int = 0,
y: Double = 0.0,
z: String = "0"
) {
}
@@ -0,0 +1,17 @@
class Usages {
void foo() {
Foo.foo();
}
void fooX() {
Foo.foo(1);
}
void fooXY() {
Foo.foo(1, 1.0);
}
void fooXYZ() {
Foo.foo(1, 1.0, "1");
}
}
@@ -0,0 +1,4 @@
Unclassified usage (11: 13) Foo.foo(1, 1.0);
Unclassified usage (15: 13) Foo.foo(1, 1.0, "1");
Unclassified usage (3: 13) Foo.foo();
Unclassified usage (7: 13) Foo.foo(1);
@@ -0,0 +1,7 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtPrimaryConstructor
// OPTIONS: usages
public class A @JvmOverloads <caret>constructor (
public val x: Int = 0,
public val y: Double = 0.0,
public val z: String = "0"
)
@@ -0,0 +1,17 @@
public class Usages {
void createA() {
new A();
}
void createAx() {
new A(1);
}
void createAxy() {
new A(1, 1.0);
}
void createAxyz() {
new A(1, 1.0, "1");
}
}
@@ -0,0 +1,4 @@
New instance creation (11: 13) new A(1, 1.0);
New instance creation (15: 13) new A(1, 1.0, "1");
New instance creation (3: 13) new A();
New instance creation (7: 13) new A(1);
@@ -0,0 +1,5 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtSecondaryConstructor
// OPTIONS: usages
public class A {
@JvmOverloads <caret>constructor(x: Int = 0, y: Double = 0.0, z: String = "0")
}
@@ -0,0 +1,17 @@
public class Usages {
void createA() {
new A();
}
void createAx() {
new A(1);
}
void createAxy() {
new A(1, 1.0);
}
void createAxyz() {
new A(1, 1.0, "1");
}
}
@@ -0,0 +1,4 @@
New instance creation (11: 13) new A(1, 1.0);
New instance creation (15: 13) new A(1, 1.0, "1");
New instance creation (3: 13) new A();
New instance creation (7: 13) new A(1);
@@ -558,6 +558,12 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("jvmOverloaded.0.kt")
public void testJvmOverloaded() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findFunctionUsages/jvmOverloaded.0.kt");
doTest(fileName);
}
@TestMetadata("kotlinInternalMethodUsages.0.kt") @TestMetadata("kotlinInternalMethodUsages.0.kt")
public void testKotlinInternalMethodUsages() throws Exception { public void testKotlinInternalMethodUsages() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinInternalMethodUsages.0.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findFunctionUsages/kotlinInternalMethodUsages.0.kt");
@@ -813,6 +819,12 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages"), Pattern.compile("^(.+)\\.0\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages"), Pattern.compile("^(.+)\\.0\\.kt$"), true);
} }
@TestMetadata("jvmOverloaded.0.kt")
public void testJvmOverloaded() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/jvmOverloaded.0.kt");
doTest(fileName);
}
@TestMetadata("missingName.0.kt") @TestMetadata("missingName.0.kt")
public void testMissingName() throws Exception { public void testMissingName() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/missingName.0.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/missingName.0.kt");
@@ -1005,6 +1017,12 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("jvmOverloaded.0.kt")
public void testJvmOverloaded() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findSecondaryConstructorUsages/jvmOverloaded.0.kt");
doTest(fileName);
}
@TestMetadata("secondaryConstructor.0.kt") @TestMetadata("secondaryConstructor.0.kt")
public void testSecondaryConstructor() throws Exception { public void testSecondaryConstructor() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findSecondaryConstructorUsages/secondaryConstructor.0.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findSecondaryConstructorUsages/secondaryConstructor.0.kt");