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);
}
@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")
public void testDisallowForJavaMethods() throws Exception {
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);
}
@TestMetadata("constructorNamedArguments.kt")
public void testConstructorNamedArguments() throws Exception {
doTest("compiler/testData/diagnostics/testsWithStdLib/kotlinSignature/constructorNamedArguments.kt");
}
@TestMetadata("parameterNames.kt")
public void testParameterNames() throws Exception {
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 */
@SuppressWarnings("all")
@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 void testAllFilesPresentInBoxWithJava() throws Exception {
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")
public static class Enum extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInEnum() throws Exception {
@@ -552,6 +565,7 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
suite.addTestSuite(BlackBoxWithJavaCodegenTestGenerated.class);
suite.addTestSuite(Annotations.class);
suite.addTestSuite(CallableReference.class);
suite.addTestSuite(Constructor.class);
suite.addTestSuite(Enum.class);
suite.addTestSuite(Functions.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.resolve.java.sam.SingleAbstractMethodUtils
import org.jetbrains.jet.lang.resolve.java.JavaVisibilities
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaConstructorDescriptor
public class LazyJavaClassMemberScope(
c: LazyJavaResolverContextWithTypes,
@@ -73,7 +74,7 @@ public class LazyJavaClassMemberScope(
}
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 effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature(
@@ -85,6 +86,7 @@ public class LazyJavaClassMemberScope(
constructor.getVisibility(),
isStaticClass
)
constructorDescriptor.setHasStableParameterNames(effectiveSignature.hasStableParameterNames())
constructorDescriptor.setReturnType(classDescriptor.getDefaultType())
@@ -104,12 +106,13 @@ public class LazyJavaClassMemberScope(
return null
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 valueParameters = if (isAnnotation) createAnnotationConstructorParameters(constructorDescriptor)
else Collections.emptyList<ValueParameterDescriptor>()
constructorDescriptor.initialize(typeParameters, valueParameters, getConstructorVisibility(classDescriptor), jClass.isStatic())
constructorDescriptor.setHasStableParameterNames(true)
constructorDescriptor.setReturnType(classDescriptor.getDefaultType())
c.javaResolverCache.recordConstructor(jClass, constructorDescriptor);
return constructorDescriptor
@@ -207,4 +210,4 @@ public class LazyJavaClassMemberScope(
override fun getPackage(name: Name) = null
override fun toString() = "Lazy java member scope for " + jClass.getFqName()
}
}
@@ -33,10 +33,10 @@ class LazyJavaTypeParameterDescriptor(
) : AbstractLazyTypeParameterDescriptor(
c.storageManager,
containingDeclaration,
name = javaTypeParameter.getName(),
variance = Variance.INVARIANT,
isReified = false,
index = javaTypeParameter.getIndex()
javaTypeParameter.getName(),
Variance.INVARIANT,
/* isReified = */ false,
javaTypeParameter.getIndex()
) {
override fun resolveUpperBounds(): Set<JetType> {
@@ -51,4 +51,4 @@ class LazyJavaTypeParameterDescriptor(
}
}
}
}
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.descriptors.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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.resolve.DescriptorUtils;
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 {
private final boolean isPrimary;
protected final boolean isPrimary;
private static final Name NAME = Name.special("<init>");
@@ -75,7 +75,7 @@ public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase()
}
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 = {
@@ -154,12 +154,12 @@ enum class MoveAction {
val targetPackage = config.getString("targetPackage")
MoveClassesOrPackagesProcessor(
project = mainFile.getProject(),
elements = array(classToMove),
moveDestination = MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)),
searchInComments = false,
searchInNonJavaFiles = true,
moveCallback = null
mainFile.getProject(),
array(classToMove),
MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)),
/* searchInComments = */ false,
/* searchInNonJavaFiles = */ true,
/* moveCallback = */ null
).run()
}
}
@@ -171,12 +171,12 @@ enum class MoveAction {
val targetPackage = config.getString("targetPackage")
MoveClassesOrPackagesProcessor(
project = project,
elements = array(JavaPsiFacade.getInstance(project).findPackage(sourcePackage)!!),
moveDestination = MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)),
searchInComments = false,
searchInNonJavaFiles = true,
moveCallback = null
project,
array(JavaPsiFacade.getInstance(project).findPackage(sourcePackage)!!),
MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), targetPackage)),
/* searchInComments = */ false,
/* searchInNonJavaFiles = */ true,
/* moveCallback = */ null
).run()
}
}
@@ -189,12 +189,12 @@ enum class MoveAction {
val targetClass = config.getString("targetClass")
MoveClassToInnerProcessor(
project = project,
classesToMove = array(classToMove),
targetClass = JavaPsiFacade.getInstance(project).findClass(targetClass, GlobalSearchScope.allScope(project))!!,
searchInComments = false,
searchInNonJavaFiles = true,
moveCallback = null
project,
array(classToMove),
JavaPsiFacade.getInstance(project).findClass(targetClass, GlobalSearchScope.allScope(project))!!,
/* searchInComments = */ false,
/* searchInNonJavaFiles = */ true,
/* moveCallback = */ null
).run()
}
}
@@ -209,12 +209,12 @@ enum class MoveAction {
val targetPackage = config.getString("targetPackage")
MoveInnerProcessor(
project = project,
innerClass = classToMove,
name = newClassName,
passOuterClass = outerInstanceParameterName != null,
parameterName = outerInstanceParameterName,
targetContainer = JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0]
project,
classToMove,
newClassName,
outerInstanceParameterName != null,
outerInstanceParameterName,
JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0]
).run()
}
}
@@ -226,13 +226,13 @@ enum class MoveAction {
val targetPackage = config.getNullableString("targetPackage")
if (targetPackage != null) {
MoveFilesOrDirectoriesProcessor(
project = project,
elements = array(mainFile),
newParent = JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0],
searchInComments = false,
searchInNonJavaFiles = true,
moveCallback = null,
prepareSuccessfulCallback = null
project,
array(mainFile),
JavaPsiFacade.getInstance(project).findPackage(targetPackage)!!.getDirectories()[0],
/* searchInComments = */ false,
/* searchInNonJavaFiles = */ true,
/* moveCallback = */ null,
/* prepareSuccessfulCallback = */ null
).run()
}
else {