diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 6b455107e11..27a1ea6e9f6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -3393,7 +3393,7 @@ public class ExpressionCodegen extends KtVisitor impleme @Override public Unit invoke(InstructionAdapter v) { KotlinType type = lhs.getType(); - if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObject()) { + if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObjectQualifier()) { JavaClassProperty.INSTANCE.generateImpl(v, gen(receiverExpression)); } else { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index 110336754f3..4534f320f20 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -140,7 +140,7 @@ class ConstantExpressionEvaluator( val lhsExpression = argumentExpression.receiverExpression if (lhsExpression != null) { val doubleColonLhs = trace.bindingContext.get(BindingContext.DOUBLE_COLON_LHS, lhsExpression) - if (doubleColonLhs is DoubleColonLHS.Expression && !doubleColonLhs.isObject) { + if (doubleColonLhs is DoubleColonLHS.Expression && !doubleColonLhs.isObjectQualifier) { trace.report(Errors.ANNOTATION_PARAMETER_MUST_BE_KCLASS_LITERAL.on(argumentExpression)) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt index 4241579e418..9eef019cbba 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt @@ -60,7 +60,18 @@ import java.util.* import javax.inject.Inject sealed class DoubleColonLHS(val type: KotlinType) { - class Expression(typeInfo: KotlinTypeInfo, val isObject: Boolean) : DoubleColonLHS(typeInfo.type!!) { + /** + * [isObjectQualifier] is true iff the LHS of a callable reference is a qualified expression which references a named object. + * Note that such LHS can be treated both as a type and as an expression, so special handling may be required. + * + * For example, if `Obj` is an object: + * + * Obj::class // object qualifier + * test.Obj::class // object qualifier + * (Obj)::class // not an object qualifier (can only be treated as an expression, not as a type) + * { Obj }()::class // not an object qualifier + */ + class Expression(typeInfo: KotlinTypeInfo, val isObjectQualifier: Boolean) : DoubleColonLHS(typeInfo.type!!) { val dataFlowInfo: DataFlowInfo = typeInfo.dataFlowInfo } @@ -98,7 +109,8 @@ class DoubleColonExpressionResolver( val type = result?.type if (type != null && !type.isError) { checkClassLiteral(c, expression, result) - val variance = if (result is DoubleColonLHS.Expression && !result.isObject) Variance.OUT_VARIANCE else Variance.INVARIANT + val variance = + if (result is DoubleColonLHS.Expression && !result.isObjectQualifier) Variance.OUT_VARIANCE else Variance.INVARIANT val kClassType = reflectionTypes.getKClassType(Annotations.EMPTY, type, variance) if (kClassType.isError) { c.trace.report(MISSING_DEPENDENCY_CLASS.on(expression.receiverExpression!!, KotlinBuiltIns.FQ_NAMES.kClass.toSafe())) @@ -115,7 +127,7 @@ class DoubleColonExpressionResolver( val type = result.type if (result is DoubleColonLHS.Expression) { - if (!result.isObject) { + if (!result.isObjectQualifier) { if (!type.isSubtypeOf(type.builtIns.anyType)) { c.trace.report(EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS.on(expression.receiverExpression!!, type)) } @@ -316,7 +328,7 @@ class DoubleColonExpressionResolver( val lhs = resultForExpr.lhs // If expression result is an object, we remember this and skip it here, because there are valid situations where // another type (representing another classifier) should win - if (lhs != null && !lhs.isObject) { + if (lhs != null && !lhs.isObjectQualifier) { return resultForExpr.commit() } } @@ -404,7 +416,7 @@ class DoubleColonExpressionResolver( if (classDescriptor.companionObjectDescriptor != null) return null if (DescriptorUtils.isObject(classDescriptor)) { - return DoubleColonLHS.Expression(typeInfo, isObject = true) + return DoubleColonLHS.Expression(typeInfo, isObjectQualifier = true) } } @@ -412,7 +424,7 @@ class DoubleColonExpressionResolver( if (expression.canBeConsideredProperType() && resultingDescriptor !is VariableDescriptor) return null } - return DoubleColonLHS.Expression(typeInfo, isObject = false) + return DoubleColonLHS.Expression(typeInfo, isObjectQualifier = false) } private fun resolveTypeOnLHS( @@ -684,7 +696,7 @@ class DoubleColonExpressionResolver( ) if (result != null) return result - if (lhs.isObject) { + if (lhs.isObjectQualifier) { val classifier = lhsType.constructor.declarationDescriptor val calleeExpression = expression.receiverExpression?.getCalleeExpressionIfAny() if (calleeExpression is KtSimpleNameExpression && classifier is ClassDescriptor) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 4dd5972fac0..8b68ff019f2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -839,7 +839,7 @@ class ExpressionCodegen( wrapIntoKClass: Boolean, data: BlockInfo ) { - if (receiverExpression !is IrClassReference /* && DescriptorUtils.isObject(receiverExpression.descriptor)*/) { + if (receiverExpression !is IrClassReference /* && DescriptorUtils.isObjectQualifier(receiverExpression.descriptor)*/) { JavaClassProperty.generateImpl(mv, gen(receiverExpression, data)) } else { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt index 7569b4afea0..06002461c17 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt @@ -35,9 +35,9 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument) val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral) - return if (lhs is DoubleColonLHS.Expression && !lhs.isObject) { + return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) { IrGetClassImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType, - statementGenerator.generateExpression(ktArgument)) + statementGenerator.generateExpression(ktArgument)) } else { val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java index 9d77c8c68bf..f2736bf4043 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java @@ -236,7 +236,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { DoubleColonLHS lhs = context.bindingContext().get(DOUBLE_COLON_LHS, receiverExpression); assert lhs != null : "Class literal expression should have LHS resolved"; - if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObject()) { + if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObjectQualifier()) { JsExpression receiver = translateAsExpression(receiverExpression, context); return new JsInvocation(context.namer().kotlin(GET_KCLASS_FROM_EXPRESSION), receiver); }