Create special type for missing dependencies when resolving annotations

#KT-10748 Fixed
This commit is contained in:
Denis Zharkov
2016-01-22 14:25:14 +03:00
parent 76f60294a8
commit d87b13931d
11 changed files with 136 additions and 10 deletions
@@ -0,0 +1,12 @@
// FILE: A.java
@missing.Ann(x = "")
public class A {
@missing.Ann(1)
public String foo() {}
}
// FILE: main.kt
fun main() {
A().foo().length
}
@@ -0,0 +1,11 @@
package
public fun main(): kotlin.Unit
@[Missing annotation class: missing.Ann]() public open class A {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@[Missing annotation class: missing.Ann]() public open fun foo(): kotlin.String!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,17 @@
// FILE: A.java
// It's supposed that there is no JSR-305 annotation in classpath
public interface A<T> {
public boolean foo(@javax.annotation.Nullable T y) {}
}
// FILE: B.java
public class B {
public static void bar(A<String> y) {}
}
// FILE: main.kt
fun test() {
B.bar() { it<!UNSAFE_CALL!>.<!>hashCode() > 0 }
}
@@ -0,0 +1,22 @@
package
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (T!) -> kotlin.Boolean): A<T>
public fun test(): kotlin.Unit
public interface A</*0*/ T : kotlin.Any!> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(/*0*/ @[Missing annotation class: javax.annotation.Nullable]() y: T?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class B {
public constructor B()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun bar(/*0*/ y: ((kotlin.String?) -> kotlin.Boolean)!): kotlin.Unit
public open fun bar(/*0*/ y: A<kotlin.String!>!): kotlin.Unit
}
@@ -293,10 +293,10 @@ package test {
invisible_fake final override /*1*/ /*fake_override*/ fun getFocusTraversalKeys_NoIDCheck(/*0*/ p0: kotlin.Int): kotlin.collections.(Mutable)Set<(raw) kotlin.Any?>!
public open override /*1*/ /*fake_override*/ fun getFocusTraversalPolicy(): [ERROR : Unresolved java classifier: FocusTraversalPolicy]!
public open override /*1*/ /*fake_override*/ fun getFocusableWindowState(): kotlin.Boolean
@[ERROR : java.beans.Transient]() public open override /*1*/ /*fake_override*/ fun getFont(): [ERROR : Unresolved java classifier: Font]!
@[Missing annotation class: java.beans.Transient]() public open override /*1*/ /*fake_override*/ fun getFont(): [ERROR : Unresolved java classifier: Font]!
public open override /*1*/ /*fake_override*/ fun getFontMetrics(/*0*/ p0: [ERROR : Unresolved java classifier: Font]!): [ERROR : Unresolved java classifier: FontMetrics]!
invisible_fake final override /*1*/ /*fake_override*/ fun getFont_NoClientCode(): [ERROR : Unresolved java classifier: Font]!
@[ERROR : java.beans.Transient]() public open override /*1*/ /*fake_override*/ fun getForeground(): [ERROR : Unresolved java classifier: Color]!
@[Missing annotation class: java.beans.Transient]() public open override /*1*/ /*fake_override*/ fun getForeground(): [ERROR : Unresolved java classifier: Color]!
public open override /*1*/ /*fake_override*/ fun getGlassPane(): java.awt.Component!
public open override /*1*/ /*fake_override*/ fun getGraphics(): [ERROR : Unresolved java classifier: Graphics]!
public open override /*1*/ /*fake_override*/ fun getGraphicsConfiguration(): [ERROR : Unresolved java classifier: GraphicsConfiguration]!
@@ -450,7 +450,7 @@ package test {
public open override /*1*/ /*fake_override*/ fun isUndecorated(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun isValid(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun isValidateRoot(): kotlin.Boolean
@[ERROR : java.beans.Transient]() public open override /*1*/ /*fake_override*/ fun isVisible(): kotlin.Boolean
@[Missing annotation class: java.beans.Transient]() public open override /*1*/ /*fake_override*/ fun isVisible(): kotlin.Boolean
invisible_fake final override /*1*/ /*fake_override*/ fun isVisible_NoClientCode(): kotlin.Boolean
@kotlin.Deprecated(message = "Deprecated in Java") public open override /*1*/ /*fake_override*/ fun keyDown(/*0*/ p0: [ERROR : Unresolved java classifier: Event]!, /*1*/ p1: kotlin.Int): kotlin.Boolean
@kotlin.Deprecated(message = "Deprecated in Java") public open override /*1*/ /*fake_override*/ fun keyUp(/*0*/ p0: [ERROR : Unresolved java classifier: Event]!, /*1*/ p1: kotlin.Int): kotlin.Boolean
@@ -9684,6 +9684,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("annotationWithArgumentsMissingDependencies.kt")
public void testAnnotationWithArgumentsMissingDependencies() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/annotationWithArgumentsMissingDependencies.kt");
doTest(fileName);
}
@TestMetadata("arrayOfStarParametrized.kt")
public void testArrayOfStarParametrized() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/arrayOfStarParametrized.kt");
@@ -11937,6 +11943,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("noAnnotationInClassPath.kt")
public void testNoAnnotationInClassPath() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/noAnnotationInClassPath.kt");
doTest(fileName);
}
@TestMetadata("nullableTypeArgument.kt")
public void testNullableTypeArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt");
@@ -93,7 +93,7 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
/* checkPropertyAccessors = */ true,
/* includeMethodsOfKotlinAny = */ false,
// Skip Java annotation constructors because order of their parameters is not retained at runtime
{ descriptor -> !descriptor.isJavaAnnotationConstructor() },
{ descriptor -> !descriptor!!.isJavaAnnotationConstructor() },
errorTypesForbidden(), renderer
)
@@ -16,9 +16,11 @@
package org.jetbrains.kotlin.load.java.lazy.descriptors
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.isSpecialAnnotation
@@ -34,6 +36,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
@@ -56,7 +59,7 @@ class LazyJavaAnnotationDescriptor(
val fqName = fqName() ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
val annotationClass = JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(fqName)
?: javaAnnotation.resolve()?.let { javaClass -> c.components.moduleClassResolver.resolveClass(javaClass) }
annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString())
annotationClass?.defaultType ?: createTypeForMissingDependencies(fqName)
}
private val source = c.components.sourceElementFactory.source(javaAnnotation)
@@ -156,4 +159,16 @@ class LazyJavaAnnotationDescriptor(
override fun toString(): String {
return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderAnnotation(this)
}
private fun createTypeForMissingDependencies(fqName: FqName) =
ErrorUtils.createErrorTypeWithCustomConstructor(
"[Missing annotation class: $fqName]",
ClassDescriptorImpl(
EmptyPackageFragmentDescriptor(c.module, fqName.parent()), fqName.shortName(), Modality.FINAL,
ClassKind.ANNOTATION_CLASS, listOf(c.module.builtIns.anyType), SourceElement.NO_SOURCE,
"[Missing annotation class: $fqName]"
).apply {
initialize(MemberScope.Empty, emptySet(), null)
}.typeConstructor
)
}
@@ -50,13 +50,25 @@ public class ClassDescriptorImpl extends ClassDescriptorBase {
@NotNull ClassKind kind,
@NotNull Collection<KotlinType> supertypes,
@NotNull SourceElement source
) {
this(containingDeclaration, name, modality, kind, supertypes, source, name.asString());
}
public ClassDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull Modality modality,
@NotNull ClassKind kind,
@NotNull Collection<KotlinType> supertypes,
@NotNull SourceElement source,
@NotNull String debugName
) {
super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, name, source);
this.modality = modality;
this.kind = kind;
this.typeConstructor = TypeConstructorImpl.createForClass(this, Annotations.Companion.getEMPTY(), false, getName().asString(),
Collections.<TypeParameterDescriptor>emptyList(), supertypes);
this.typeConstructor = TypeConstructorImpl.createForClass(this, Annotations.Companion.getEMPTY(), false, debugName,
Collections.<TypeParameterDescriptor>emptyList(), supertypes);
}
public final void initialize(
@@ -0,0 +1,25 @@
/*
* Copyright 2010-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.
* 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.kotlin.descriptors.impl
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.scopes.MemberScope
class EmptyPackageFragmentDescriptor(module: ModuleDescriptor, fqName: FqName) : PackageFragmentDescriptorImpl(module, fqName) {
override fun getMemberScope() = MemberScope.Empty
}
@@ -215,7 +215,7 @@ class KotlinIndicesHelper(
}
// Note: Can't search with psi element as analyzer could be built over temp files
return ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(moduleDescriptor, classFQName) { kindFilter(it.kind) }
return ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(moduleDescriptor, classFQName) { kindFilter(it!!.kind) }
.filter(descriptorFilter)
}