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,
|
||||
|
||||
Reference in New Issue
Block a user