Support named arguments for Java constructors annotated with KotlinSignature

This commit is contained in:
Alexander Udalov
2014-03-19 23:08:56 +04:00
parent d2dc54c14f
commit 7d311cdfa0
14 changed files with 189 additions and 43 deletions
@@ -0,0 +1,5 @@
package test;
public class genericConstructor<T extends Number> {
public genericConstructor(T number) {}
}
@@ -0,0 +1,9 @@
import test.genericConstructor
class Subclass : genericConstructor<Int>(42) {
}
fun box(): String {
Subclass()
return "OK"
}
@@ -0,0 +1,12 @@
// FILE: A.java
public @interface A {
int x();
String y();
}
// FILE: 1.kt
A(x = 1, y = "2")
fun test() {}
@@ -0,0 +1,9 @@
// FILE: A.java
public class A {
public A(int x, String y) {}
}
// FILE: 1.kt
val test = A(<!NAMED_ARGUMENTS_NOT_ALLOWED!>x<!> = 1, <!NAMED_ARGUMENTS_NOT_ALLOWED!>y<!> = "2")
@@ -0,0 +1,12 @@
// FILE: A.java
import kotlin.jvm.KotlinSignature;
public class A {
@KotlinSignature("fun A(x: Int, y: String)")
public A(int x, String y) {}
}
// FILE: 1.kt
val test = A(x = 1, y = "2")
@@ -4766,6 +4766,16 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/namedArguments"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/namedArguments"), Pattern.compile("^(.+)\\.kt$"), true);
} }
@TestMetadata("allowForJavaAnnotation.kt")
public void testAllowForJavaAnnotation() throws Exception {
doTest("compiler/testData/diagnostics/tests/namedArguments/allowForJavaAnnotation.kt");
}
@TestMetadata("disallowForJavaConstructor.kt")
public void testDisallowForJavaConstructor() throws Exception {
doTest("compiler/testData/diagnostics/tests/namedArguments/disallowForJavaConstructor.kt");
}
@TestMetadata("disallowForJavaMethods.kt") @TestMetadata("disallowForJavaMethods.kt")
public void testDisallowForJavaMethods() throws Exception { public void testDisallowForJavaMethods() throws Exception {
doTest("compiler/testData/diagnostics/tests/namedArguments/disallowForJavaMethods.kt"); doTest("compiler/testData/diagnostics/tests/namedArguments/disallowForJavaMethods.kt");
@@ -99,6 +99,11 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/testsWithStdLib/kotlinSignature"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/testsWithStdLib/kotlinSignature"), Pattern.compile("^(.+)\\.kt$"), true);
} }
@TestMetadata("constructorNamedArguments.kt")
public void testConstructorNamedArguments() throws Exception {
doTest("compiler/testData/diagnostics/testsWithStdLib/kotlinSignature/constructorNamedArguments.kt");
}
@TestMetadata("parameterNames.kt") @TestMetadata("parameterNames.kt")
public void testParameterNames() throws Exception { public void testParameterNames() throws Exception {
doTest("compiler/testData/diagnostics/testsWithStdLib/kotlinSignature/parameterNames.kt"); doTest("compiler/testData/diagnostics/testsWithStdLib/kotlinSignature/parameterNames.kt");
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all") @SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/boxWithJava") @TestMetadata("compiler/testData/codegen/boxWithJava")
@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.Annotations.class, BlackBoxWithJavaCodegenTestGenerated.CallableReference.class, BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.InnerClass.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.Sam.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class}) @InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.Annotations.class, BlackBoxWithJavaCodegenTestGenerated.CallableReference.class, BlackBoxWithJavaCodegenTestGenerated.Constructor.class, BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.InnerClass.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.Sam.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class})
public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBoxWithJava() throws Exception { public void testAllFilesPresentInBoxWithJava() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -88,6 +88,19 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
} }
@TestMetadata("compiler/testData/codegen/boxWithJava/constructor")
public static class Constructor extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInConstructor() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithJava/constructor"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("genericConstructor.kt")
public void testGenericConstructor() throws Exception {
doTestWithJava("compiler/testData/codegen/boxWithJava/constructor/genericConstructor.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxWithJava/enum") @TestMetadata("compiler/testData/codegen/boxWithJava/enum")
public static class Enum extends AbstractBlackBoxCodegenTest { public static class Enum extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInEnum() throws Exception { public void testAllFilesPresentInEnum() throws Exception {
@@ -552,6 +565,7 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
suite.addTestSuite(BlackBoxWithJavaCodegenTestGenerated.class); suite.addTestSuite(BlackBoxWithJavaCodegenTestGenerated.class);
suite.addTestSuite(Annotations.class); suite.addTestSuite(Annotations.class);
suite.addTestSuite(CallableReference.class); suite.addTestSuite(CallableReference.class);
suite.addTestSuite(Constructor.class);
suite.addTestSuite(Enum.class); suite.addTestSuite(Enum.class);
suite.addTestSuite(Functions.class); suite.addTestSuite(Functions.class);
suite.addTestSuite(InnerClass.class); suite.addTestSuite(InnerClass.class);
@@ -0,0 +1,68 @@
/*
* Copyright 2010-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.java.descriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
public class JavaConstructorDescriptor extends ConstructorDescriptorImpl {
private Boolean hasStableParameterNames;
public JavaConstructorDescriptor(
@NotNull ClassDescriptor containingDeclaration,
@NotNull Annotations annotations,
boolean isPrimary
) {
super(containingDeclaration, annotations, isPrimary);
}
private JavaConstructorDescriptor(
@NotNull ClassDescriptor containingDeclaration,
@NotNull JavaConstructorDescriptor original,
@NotNull Annotations annotations,
boolean isPrimary
) {
super(containingDeclaration, original, annotations, isPrimary);
}
@Override
public boolean hasStableParameterNames() {
assert hasStableParameterNames != null : "hasStableParameterNames was not set: " + this;
return hasStableParameterNames;
}
public void setHasStableParameterNames(boolean hasStableParameterNames) {
this.hasStableParameterNames = hasStableParameterNames;
}
@Override
protected JavaConstructorDescriptor createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind) {
if (kind != Kind.DECLARATION) {
throw new IllegalStateException("Attempt at creating a constructor that is not a declaration: \n" +
"copy from: " + this + "\n" +
"newOwner: " + newOwner + "\n" +
"kind: " + kind);
}
JavaConstructorDescriptor result =
new JavaConstructorDescriptor((ClassDescriptor) newOwner, this, Annotations.EMPTY /* TODO */, isPrimary);
result.setHasStableParameterNames(hasStableParameterNames());
return result;
}
}
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.descriptors.annotations.Annotations import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
import org.jetbrains.jet.lang.resolve.java.JavaVisibilities import org.jetbrains.jet.lang.resolve.java.JavaVisibilities
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaConstructorDescriptor
public class LazyJavaClassMemberScope( public class LazyJavaClassMemberScope(
c: LazyJavaResolverContextWithTypes, c: LazyJavaResolverContextWithTypes,
@@ -73,7 +74,7 @@ public class LazyJavaClassMemberScope(
} }
private fun resolveConstructor(constructor: JavaMethod, classDescriptor: ClassDescriptor, isStaticClass: Boolean): ConstructorDescriptor { private fun resolveConstructor(constructor: JavaMethod, classDescriptor: ClassDescriptor, isStaticClass: Boolean): ConstructorDescriptor {
val constructorDescriptor = ConstructorDescriptorImpl(classDescriptor, Annotations.EMPTY, isPrimary = false) val constructorDescriptor = JavaConstructorDescriptor(classDescriptor, Annotations.EMPTY, /* isPrimary = */ false)
val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.getValueParameters()) val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.getValueParameters())
val effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature( val effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature(
@@ -85,6 +86,7 @@ public class LazyJavaClassMemberScope(
constructor.getVisibility(), constructor.getVisibility(),
isStaticClass isStaticClass
) )
constructorDescriptor.setHasStableParameterNames(effectiveSignature.hasStableParameterNames())
constructorDescriptor.setReturnType(classDescriptor.getDefaultType()) constructorDescriptor.setReturnType(classDescriptor.getDefaultType())
@@ -104,12 +106,13 @@ public class LazyJavaClassMemberScope(
return null return null
val classDescriptor = getContainingDeclaration() val classDescriptor = getContainingDeclaration()
val constructorDescriptor = ConstructorDescriptorImpl(classDescriptor, Annotations.EMPTY, isPrimary = true) val constructorDescriptor = JavaConstructorDescriptor(classDescriptor, Annotations.EMPTY, /* isPrimary = */ true)
val typeParameters = classDescriptor.getTypeConstructor().getParameters() val typeParameters = classDescriptor.getTypeConstructor().getParameters()
val valueParameters = if (isAnnotation) createAnnotationConstructorParameters(constructorDescriptor) val valueParameters = if (isAnnotation) createAnnotationConstructorParameters(constructorDescriptor)
else Collections.emptyList<ValueParameterDescriptor>() else Collections.emptyList<ValueParameterDescriptor>()
constructorDescriptor.initialize(typeParameters, valueParameters, getConstructorVisibility(classDescriptor), jClass.isStatic()) constructorDescriptor.initialize(typeParameters, valueParameters, getConstructorVisibility(classDescriptor), jClass.isStatic())
constructorDescriptor.setHasStableParameterNames(true)
constructorDescriptor.setReturnType(classDescriptor.getDefaultType()) constructorDescriptor.setReturnType(classDescriptor.getDefaultType())
c.javaResolverCache.recordConstructor(jClass, constructorDescriptor); c.javaResolverCache.recordConstructor(jClass, constructorDescriptor);
return constructorDescriptor return constructorDescriptor
@@ -33,10 +33,10 @@ class LazyJavaTypeParameterDescriptor(
) : AbstractLazyTypeParameterDescriptor( ) : AbstractLazyTypeParameterDescriptor(
c.storageManager, c.storageManager,
containingDeclaration, containingDeclaration,
name = javaTypeParameter.getName(), javaTypeParameter.getName(),
variance = Variance.INVARIANT, Variance.INVARIANT,
isReified = false, /* isReified = */ false,
index = javaTypeParameter.getIndex() javaTypeParameter.getIndex()
) { ) {
override fun resolveUpperBounds(): Set<JetType> { override fun resolveUpperBounds(): Set<JetType> {
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.descriptors.impl;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -32,7 +31,7 @@ import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_
public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements ConstructorDescriptor { public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements ConstructorDescriptor {
private final boolean isPrimary; protected final boolean isPrimary;
private static final Name NAME = Name.special("<init>"); private static final Name NAME = Name.special("<init>");
@@ -75,7 +75,7 @@ public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase()
} }
override fun getProjectDescriptor(): LightProjectDescriptor { override fun getProjectDescriptor(): LightProjectDescriptor {
return JdkAndMockLibraryProjectDescriptor(TEST_DATA_PATH, withSources = false) return JdkAndMockLibraryProjectDescriptor(TEST_DATA_PATH, /* withSources = */ false)
} }
private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = { private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = {
@@ -154,12 +154,12 @@ enum class MoveAction {
val targetPackage = config.getString("targetPackage") val targetPackage = config.getString("targetPackage")
MoveClassesOrPackagesProcessor( MoveClassesOrPackagesProcessor(
project = mainFile.getProject(), mainFile.getProject(),
elements = array(classToMove), array(classToMove),
moveDestination = MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)), MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)),
searchInComments = false, /* searchInComments = */ false,
searchInNonJavaFiles = true, /* searchInNonJavaFiles = */ true,
moveCallback = null /* moveCallback = */ null
).run() ).run()
} }
} }
@@ -171,12 +171,12 @@ enum class MoveAction {
val targetPackage = config.getString("targetPackage") val targetPackage = config.getString("targetPackage")
MoveClassesOrPackagesProcessor( MoveClassesOrPackagesProcessor(
project = project, project,
elements = array(JavaPsiFacade.getInstance(project).findPackage(sourcePackage)!!), array(JavaPsiFacade.getInstance(project).findPackage(sourcePackage)!!),
moveDestination = MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)), MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)),
searchInComments = false, /* searchInComments = */ false,
searchInNonJavaFiles = true, /* searchInNonJavaFiles = */ true,
moveCallback = null /* moveCallback = */ null
).run() ).run()
} }
} }
@@ -189,12 +189,12 @@ enum class MoveAction {
val targetClass = config.getString("targetClass") val targetClass = config.getString("targetClass")
MoveClassToInnerProcessor( MoveClassToInnerProcessor(
project = project, project,
classesToMove = array(classToMove), array(classToMove),
targetClass = JavaPsiFacade.getInstance(project).findClass(targetClass, GlobalSearchScope.allScope(project))!!, JavaPsiFacade.getInstance(project).findClass(targetClass, GlobalSearchScope.allScope(project))!!,
searchInComments = false, /* searchInComments = */ false,
searchInNonJavaFiles = true, /* searchInNonJavaFiles = */ true,
moveCallback = null /* moveCallback = */ null
).run() ).run()
} }
} }
@@ -209,12 +209,12 @@ enum class MoveAction {
val targetPackage = config.getString("targetPackage") val targetPackage = config.getString("targetPackage")
MoveInnerProcessor( MoveInnerProcessor(
project = project, project,
innerClass = classToMove, classToMove,
name = newClassName, newClassName,
passOuterClass = outerInstanceParameterName != null, outerInstanceParameterName != null,
parameterName = outerInstanceParameterName, outerInstanceParameterName,
targetContainer = JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0] JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0]
).run() ).run()
} }
} }
@@ -226,13 +226,13 @@ enum class MoveAction {
val targetPackage = config.getNullableString("targetPackage") val targetPackage = config.getNullableString("targetPackage")
if (targetPackage != null) { if (targetPackage != null) {
MoveFilesOrDirectoriesProcessor( MoveFilesOrDirectoriesProcessor(
project = project, project,
elements = array(mainFile), array(mainFile),
newParent = JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0], JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0],
searchInComments = false, /* searchInComments = */ false,
searchInNonJavaFiles = true, /* searchInNonJavaFiles = */ true,
moveCallback = null, /* moveCallback = */ null,
prepareSuccessfulCallback = null /* prepareSuccessfulCallback = */ null
).run() ).run()
} }
else { else {