LHS of qualified expressions are determined manually
ExpressionPosition is useless now and will be dropped #KT-3866 Fixed
This commit is contained in:
@@ -431,6 +431,13 @@ public class JetPsiUtil {
|
||||
return selectorParent instanceof JetQualifiedExpression && (((JetQualifiedExpression) selectorParent).getSelectorExpression() == selector);
|
||||
}
|
||||
|
||||
public static boolean isLHSOfDot(@NotNull JetExpression expression) {
|
||||
PsiElement parent = expression.getParent();
|
||||
if (!(parent instanceof JetQualifiedExpression)) return false;
|
||||
JetQualifiedExpression qualifiedParent = (JetQualifiedExpression) parent;
|
||||
return qualifiedParent.getReceiverExpression() == expression || isLHSOfDot(qualifiedParent);
|
||||
}
|
||||
|
||||
public static boolean isVoidType(@Nullable JetTypeReference typeReference) {
|
||||
if (typeReference == null) {
|
||||
return false;
|
||||
|
||||
+12
-10
@@ -53,6 +53,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getStaticNestedClassesScope;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
import static org.jetbrains.jet.lang.psi.JetPsiUtil.isLHSOfDot;
|
||||
|
||||
public class CallExpressionResolver {
|
||||
@NotNull
|
||||
@@ -71,7 +72,7 @@ public class CallExpressionResolver {
|
||||
JetType classObjectType = classifier.getClassObjectType();
|
||||
if (classObjectType != null) {
|
||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||
JetType result = getExtendedClassObjectType(classObjectType, referencedName, classifier, context);
|
||||
JetType result = getExtendedClassObjectType(expression, classObjectType, classifier, context);
|
||||
checkClassObjectVisibility(classifier, expression, context);
|
||||
return DataFlowUtils.checkType(result, expression, context);
|
||||
}
|
||||
@@ -86,14 +87,14 @@ public class CallExpressionResolver {
|
||||
// To report NO_CLASS_OBJECT when no namespace found
|
||||
if (classifier != null) {
|
||||
if (classifier instanceof TypeParameterDescriptor) {
|
||||
if (context.expressionPosition == ExpressionPosition.FREE) {
|
||||
context.trace.report(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(expression, (TypeParameterDescriptor) classifier));
|
||||
}
|
||||
else {
|
||||
if (isLHSOfDot(expression)) {
|
||||
context.trace.report(TYPE_PARAMETER_ON_LHS_OF_DOT.on(expression, (TypeParameterDescriptor) classifier));
|
||||
}
|
||||
else {
|
||||
context.trace.report(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(expression, (TypeParameterDescriptor) classifier));
|
||||
}
|
||||
}
|
||||
else if (context.expressionPosition == ExpressionPosition.FREE) {
|
||||
else if (!isLHSOfDot(expression)) {
|
||||
context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
|
||||
}
|
||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||
@@ -134,17 +135,18 @@ public class CallExpressionResolver {
|
||||
|
||||
@NotNull
|
||||
private static JetType getExtendedClassObjectType(
|
||||
@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull JetType classObjectType,
|
||||
@NotNull Name referencedName,
|
||||
@NotNull ClassifierDescriptor classifier,
|
||||
@NotNull ResolutionContext context
|
||||
) {
|
||||
if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT && classifier instanceof ClassDescriptor) {
|
||||
if (isLHSOfDot(expression) && classifier instanceof ClassDescriptor) {
|
||||
List<JetScope> scopes = new ArrayList<JetScope>(3);
|
||||
|
||||
scopes.add(classObjectType.getMemberScope());
|
||||
scopes.add(getStaticNestedClassesScope((ClassDescriptor) classifier));
|
||||
|
||||
Name referencedName = expression.getReferencedNameAsName();
|
||||
NamespaceDescriptor namespace = context.scope.getNamespace(referencedName);
|
||||
if (namespace != null) {
|
||||
//for enums loaded from java binaries
|
||||
@@ -166,7 +168,7 @@ public class CallExpressionResolver {
|
||||
if (namespaceType == null) {
|
||||
return false;
|
||||
}
|
||||
if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT) {
|
||||
if (isLHSOfDot(expression)) {
|
||||
result[0] = namespaceType;
|
||||
return true;
|
||||
}
|
||||
@@ -266,7 +268,7 @@ public class CallExpressionResolver {
|
||||
JetType type = getVariableType(nameExpression, receiver, callOperationNode, context.replaceTraceAndCache(temporaryForVariable), result);
|
||||
if (result[0]) {
|
||||
temporaryForVariable.commit();
|
||||
if (type instanceof NamespaceType && context.expressionPosition == ExpressionPosition.FREE) {
|
||||
if (type instanceof NamespaceType && !isLHSOfDot(nameExpression)) {
|
||||
type = null;
|
||||
}
|
||||
return JetTypeInfo.create(type, context.dataFlowInfo);
|
||||
|
||||
+3
-3
@@ -36,7 +36,6 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.TemporaryTraceAndCache;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||
@@ -281,10 +280,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
public JetTypeInfo visitSuperExpression(@NotNull JetSuperExpression expression, ExpressionTypingContext context) {
|
||||
LabelResolver.LabeledReceiverResolutionResult resolutionResult = resolveToReceiver(expression, context, true);
|
||||
|
||||
if (context.expressionPosition == ExpressionPosition.FREE) {
|
||||
if (!JetPsiUtil.isLHSOfDot(expression)) {
|
||||
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(expression, expression.getText()));
|
||||
return errorInSuper(expression, context);
|
||||
}
|
||||
|
||||
switch (resolutionResult.getCode()) {
|
||||
case LABEL_RESOLUTION_ERROR:
|
||||
// The error is already reported
|
||||
@@ -1124,7 +1124,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public JetTypeInfo visitRootNamespaceExpression(@NotNull JetRootNamespaceExpression expression, ExpressionTypingContext context) {
|
||||
if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT) {
|
||||
if (JetPsiUtil.isLHSOfDot(expression)) {
|
||||
return DataFlowUtils.checkType(JetModuleUtil.getRootNamespaceType(expression), expression, context, context.dataFlowInfo);
|
||||
}
|
||||
context.trace.report(NAMESPACE_IS_NOT_AN_EXPRESSION.on(expression));
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
open class C {
|
||||
}
|
||||
|
||||
fun C.foo() {}
|
||||
|
||||
open class X {
|
||||
class object : C() {}
|
||||
}
|
||||
|
||||
open class Y {
|
||||
class object : C() {}
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
val x = X
|
||||
x.foo()
|
||||
X.foo()
|
||||
(X : C).foo()
|
||||
(X <!USELESS_CAST_STATIC_ASSERT_IS_FINE!>as<!> C).foo()
|
||||
((if (1<2) X else Y) : C).foo()
|
||||
}
|
||||
@@ -1374,6 +1374,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/classObjects/invisibleClassObjects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt3866.kt")
|
||||
public void testKt3866() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/classObjects/kt3866.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClassInPrivateClassObject.kt")
|
||||
public void testNestedClassInPrivateClassObject() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.kt");
|
||||
|
||||
Reference in New Issue
Block a user