Create error type if reflection class isn't found
Introduce a new diagnostic fired when reflection types aren't found in the classpath
This commit is contained in:
@@ -367,7 +367,9 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_UPPER_BOUND_VIOLATED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory2<JetExpression, JetType, JetType> TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
// Callable references
|
||||
// Reflection
|
||||
|
||||
DiagnosticFactory0<PsiElement> REFLECTION_TYPES_NOT_LOADED = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<JetExpression, CallableMemberDescriptor> EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<JetExpression> CALLABLE_REFERENCE_LHS_NOT_A_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
+2
@@ -471,6 +471,8 @@ public class DefaultErrorMessages {
|
||||
|
||||
MAP.put(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED, "Right-hand side has anonymous type. Please specify type explicitly", TO_STRING);
|
||||
|
||||
MAP.put(REFLECTION_TYPES_NOT_LOADED, "Reflection types can't be loaded. Please ensure that you have Kotlin Runtime in your classpath");
|
||||
|
||||
MAP.put(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED,
|
||||
"''{0}'' is a member and an extension at the same time. References to such elements are not allowed", NAME);
|
||||
MAP.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Callable reference left-hand side cannot be a type parameter");
|
||||
|
||||
+9
-4
@@ -33,15 +33,20 @@ public class JetCallableReferenceExpression extends JetExpressionImpl {
|
||||
return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement getDoubleColonTokenReference() {
|
||||
//noinspection ConstantConditions
|
||||
return findChildByType(JetTokens.COLONCOLON);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetSimpleNameExpression getCallableReference() {
|
||||
ASTNode node = getNode().findChildByType(JetTokens.COLONCOLON);
|
||||
while (node != null) {
|
||||
PsiElement psi = node.getPsi();
|
||||
PsiElement psi = getDoubleColonTokenReference();
|
||||
while (psi != null) {
|
||||
if (psi instanceof JetSimpleNameExpression) {
|
||||
return (JetSimpleNameExpression) psi;
|
||||
}
|
||||
node = node.getTreeNext();
|
||||
psi = psi.getNextSibling();
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Callable reference simple name shouldn't be parsed to null");
|
||||
|
||||
@@ -25,18 +25,19 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl
|
||||
import org.jetbrains.jet.lang.types.error.ErrorClassDescriptor
|
||||
|
||||
private val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
|
||||
|
||||
public class ReflectionTypes(private val module: ModuleDescriptor) {
|
||||
private val kotlinReflect: JetScope by Delegates.lazy {
|
||||
// TODO: handle errors gracefully (error types)
|
||||
val kotlin = module.getPackage(FqName("kotlin")) ?: error("Package kotlin not found in $module")
|
||||
val reflect = kotlin.getMemberScope().getPackage(Name.identifier("reflect")) ?: error("Package reflect not found in $kotlin")
|
||||
reflect.getMemberScope()
|
||||
private val kotlinReflectScope: JetScope? by Delegates.lazy {
|
||||
module.getPackage(KOTLIN_REFLECT_FQ_NAME)?.getMemberScope()
|
||||
}
|
||||
|
||||
fun find(className: String): ClassDescriptor {
|
||||
val name = Name.identifier(className)
|
||||
return kotlinReflect.getClassifier(name) as? ClassDescriptor ?: error("Reflection class not found: $name")
|
||||
return kotlinReflectScope?.getClassifier(name) as? ClassDescriptor
|
||||
?: ErrorClassDescriptor(KOTLIN_REFLECT_FQ_NAME.child(name).asString())
|
||||
}
|
||||
|
||||
public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n")
|
||||
@@ -53,7 +54,10 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
|
||||
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
|
||||
val classDescriptor = correspondingKFunctionClass(receiverType, extensionFunction, parameterTypes.size)
|
||||
|
||||
return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
|
||||
return if (classDescriptor is ErrorClassDescriptor)
|
||||
classDescriptor.getDefaultType()
|
||||
else
|
||||
JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
|
||||
}
|
||||
|
||||
private fun correspondingKFunctionClass(
|
||||
|
||||
+5
@@ -503,6 +503,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
receiverParameter != null
|
||||
);
|
||||
|
||||
if (type.isError()) {
|
||||
context.trace.report(REFLECTION_TYPES_NOT_LOADED.on(expression.getDoubleColonTokenReference()));
|
||||
return null;
|
||||
}
|
||||
|
||||
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
|
||||
context.scope.getContainingDeclaration(),
|
||||
Annotations.EMPTY,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo() {}
|
||||
|
||||
class A {
|
||||
fun baz() {}
|
||||
}
|
||||
|
||||
val bar = <!REFLECTION_TYPES_NOT_LOADED!>::<!>foo
|
||||
val quux = A<!REFLECTION_TYPES_NOT_LOADED!>::<!>baz
|
||||
@@ -374,6 +374,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest("compiler/testData/diagnostics/tests/RecursiveTypeInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ReflectionTypesNotLoaded.kt")
|
||||
public void testReflectionTypesNotLoaded() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/ReflectionTypesNotLoaded.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolveOfJavaGenerics.kt")
|
||||
public void testResolveOfJavaGenerics() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/ResolveOfJavaGenerics.kt");
|
||||
|
||||
@@ -227,7 +227,7 @@ public class ErrorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor("");
|
||||
private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor(null);
|
||||
|
||||
@NotNull
|
||||
public static JetScope createErrorScope(@NotNull String debugMessage) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.types.error;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
|
||||
@@ -32,13 +33,12 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.types.ErrorUtils.*;
|
||||
|
||||
public final class ErrorClassDescriptor extends ClassDescriptorImpl {
|
||||
public ErrorClassDescriptor(@NotNull String debugMessage) {
|
||||
super(getErrorModule(), Name.special("<ERROR CLASS: " + debugMessage + ">"), Modality.OPEN, Collections.<JetType>emptyList());
|
||||
|
||||
ConstructorDescriptorImpl errorConstructor =
|
||||
ConstructorDescriptorImpl.create(this, Annotations.EMPTY, true);
|
||||
public class ErrorClassDescriptor extends ClassDescriptorImpl {
|
||||
public ErrorClassDescriptor(@Nullable String name) {
|
||||
super(getErrorModule(), Name.special(name == null ? "<ERROR CLASS>" : "<ERROR CLASS: " + name + ">"),
|
||||
Modality.OPEN, Collections.<JetType>emptyList());
|
||||
|
||||
ConstructorDescriptorImpl errorConstructor = ConstructorDescriptorImpl.create(this, Annotations.EMPTY, true);
|
||||
errorConstructor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
|
||||
Visibilities.INTERNAL, false);
|
||||
errorConstructor.setReturnType(createErrorType("<ERROR RETURN TYPE>"));
|
||||
|
||||
Reference in New Issue
Block a user