Create special type for missing dependencies when resolving annotations
#KT-10748 Fixed
This commit is contained in:
+12
@@ -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
|
||||||
|
}
|
||||||
+11
@@ -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 }
|
||||||
|
}
|
||||||
+22
@@ -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?>!
|
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 getFocusTraversalPolicy(): [ERROR : Unresolved java classifier: FocusTraversalPolicy]!
|
||||||
public open override /*1*/ /*fake_override*/ fun getFocusableWindowState(): kotlin.Boolean
|
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]!
|
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]!
|
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 getGlassPane(): java.awt.Component!
|
||||||
public open override /*1*/ /*fake_override*/ fun getGraphics(): [ERROR : Unresolved java classifier: Graphics]!
|
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]!
|
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 isUndecorated(): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun isValid(): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun isValid(): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun isValidateRoot(): 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
|
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 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
|
@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);
|
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")
|
@TestMetadata("arrayOfStarParametrized.kt")
|
||||||
public void testArrayOfStarParametrized() throws Exception {
|
public void testArrayOfStarParametrized() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/arrayOfStarParametrized.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/arrayOfStarParametrized.kt");
|
||||||
@@ -11937,6 +11943,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("nullableTypeArgument.kt")
|
||||||
public void testNullableTypeArgument() throws Exception {
|
public void testNullableTypeArgument() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt");
|
||||||
|
|||||||
+1
-1
@@ -93,7 +93,7 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
|
|||||||
/* checkPropertyAccessors = */ true,
|
/* checkPropertyAccessors = */ true,
|
||||||
/* includeMethodsOfKotlinAny = */ false,
|
/* includeMethodsOfKotlinAny = */ false,
|
||||||
// Skip Java annotation constructors because order of their parameters is not retained at runtime
|
// Skip Java annotation constructors because order of their parameters is not retained at runtime
|
||||||
{ descriptor -> !descriptor.isJavaAnnotationConstructor() },
|
{ descriptor -> !descriptor!!.isJavaAnnotationConstructor() },
|
||||||
errorTypesForbidden(), renderer
|
errorTypesForbidden(), renderer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+18
-3
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.lazy.descriptors
|
package org.jetbrains.kotlin.load.java.lazy.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
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.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.isSpecialAnnotation
|
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.ConstantValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
|
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||||
|
|
||||||
@@ -56,7 +59,7 @@ class LazyJavaAnnotationDescriptor(
|
|||||||
val fqName = fqName() ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
|
val fqName = fqName() ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
|
||||||
val annotationClass = JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(fqName)
|
val annotationClass = JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(fqName)
|
||||||
?: javaAnnotation.resolve()?.let { javaClass -> c.components.moduleClassResolver.resolveClass(javaClass) }
|
?: 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)
|
private val source = c.components.sourceElementFactory.source(javaAnnotation)
|
||||||
@@ -156,4 +159,16 @@ class LazyJavaAnnotationDescriptor(
|
|||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderAnnotation(this)
|
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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-2
@@ -50,13 +50,25 @@ public class ClassDescriptorImpl extends ClassDescriptorBase {
|
|||||||
@NotNull ClassKind kind,
|
@NotNull ClassKind kind,
|
||||||
@NotNull Collection<KotlinType> supertypes,
|
@NotNull Collection<KotlinType> supertypes,
|
||||||
@NotNull SourceElement source
|
@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);
|
super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, name, source);
|
||||||
this.modality = modality;
|
this.modality = modality;
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
|
|
||||||
this.typeConstructor = TypeConstructorImpl.createForClass(this, Annotations.Companion.getEMPTY(), false, getName().asString(),
|
this.typeConstructor = TypeConstructorImpl.createForClass(this, Annotations.Companion.getEMPTY(), false, debugName,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(), supertypes);
|
Collections.<TypeParameterDescriptor>emptyList(), supertypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void initialize(
|
public final void initialize(
|
||||||
|
|||||||
+25
@@ -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
|
// 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)
|
.filter(descriptorFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user