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);
|
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) {
|
public static boolean isVoidType(@Nullable JetTypeReference typeReference) {
|
||||||
if (typeReference == null) {
|
if (typeReference == null) {
|
||||||
return false;
|
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.BindingContext.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getStaticNestedClassesScope;
|
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.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
import static org.jetbrains.jet.lang.psi.JetPsiUtil.isLHSOfDot;
|
||||||
|
|
||||||
public class CallExpressionResolver {
|
public class CallExpressionResolver {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -71,7 +72,7 @@ public class CallExpressionResolver {
|
|||||||
JetType classObjectType = classifier.getClassObjectType();
|
JetType classObjectType = classifier.getClassObjectType();
|
||||||
if (classObjectType != null) {
|
if (classObjectType != null) {
|
||||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
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);
|
checkClassObjectVisibility(classifier, expression, context);
|
||||||
return DataFlowUtils.checkType(result, expression, context);
|
return DataFlowUtils.checkType(result, expression, context);
|
||||||
}
|
}
|
||||||
@@ -86,14 +87,14 @@ public class CallExpressionResolver {
|
|||||||
// To report NO_CLASS_OBJECT when no namespace found
|
// To report NO_CLASS_OBJECT when no namespace found
|
||||||
if (classifier != null) {
|
if (classifier != null) {
|
||||||
if (classifier instanceof TypeParameterDescriptor) {
|
if (classifier instanceof TypeParameterDescriptor) {
|
||||||
if (context.expressionPosition == ExpressionPosition.FREE) {
|
if (isLHSOfDot(expression)) {
|
||||||
context.trace.report(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(expression, (TypeParameterDescriptor) classifier));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.trace.report(TYPE_PARAMETER_ON_LHS_OF_DOT.on(expression, (TypeParameterDescriptor) classifier));
|
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.report(NO_CLASS_OBJECT.on(expression, classifier));
|
||||||
}
|
}
|
||||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||||
@@ -134,17 +135,18 @@ public class CallExpressionResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static JetType getExtendedClassObjectType(
|
private static JetType getExtendedClassObjectType(
|
||||||
|
@NotNull JetSimpleNameExpression expression,
|
||||||
@NotNull JetType classObjectType,
|
@NotNull JetType classObjectType,
|
||||||
@NotNull Name referencedName,
|
|
||||||
@NotNull ClassifierDescriptor classifier,
|
@NotNull ClassifierDescriptor classifier,
|
||||||
@NotNull ResolutionContext context
|
@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);
|
List<JetScope> scopes = new ArrayList<JetScope>(3);
|
||||||
|
|
||||||
scopes.add(classObjectType.getMemberScope());
|
scopes.add(classObjectType.getMemberScope());
|
||||||
scopes.add(getStaticNestedClassesScope((ClassDescriptor) classifier));
|
scopes.add(getStaticNestedClassesScope((ClassDescriptor) classifier));
|
||||||
|
|
||||||
|
Name referencedName = expression.getReferencedNameAsName();
|
||||||
NamespaceDescriptor namespace = context.scope.getNamespace(referencedName);
|
NamespaceDescriptor namespace = context.scope.getNamespace(referencedName);
|
||||||
if (namespace != null) {
|
if (namespace != null) {
|
||||||
//for enums loaded from java binaries
|
//for enums loaded from java binaries
|
||||||
@@ -166,7 +168,7 @@ public class CallExpressionResolver {
|
|||||||
if (namespaceType == null) {
|
if (namespaceType == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT) {
|
if (isLHSOfDot(expression)) {
|
||||||
result[0] = namespaceType;
|
result[0] = namespaceType;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -266,7 +268,7 @@ public class CallExpressionResolver {
|
|||||||
JetType type = getVariableType(nameExpression, receiver, callOperationNode, context.replaceTraceAndCache(temporaryForVariable), result);
|
JetType type = getVariableType(nameExpression, receiver, callOperationNode, context.replaceTraceAndCache(temporaryForVariable), result);
|
||||||
if (result[0]) {
|
if (result[0]) {
|
||||||
temporaryForVariable.commit();
|
temporaryForVariable.commit();
|
||||||
if (type instanceof NamespaceType && context.expressionPosition == ExpressionPosition.FREE) {
|
if (type instanceof NamespaceType && !isLHSOfDot(nameExpression)) {
|
||||||
type = null;
|
type = null;
|
||||||
}
|
}
|
||||||
return JetTypeInfo.create(type, context.dataFlowInfo);
|
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.DataFlowValueFactory;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability;
|
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.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.context.TemporaryTraceAndCache;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
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) {
|
public JetTypeInfo visitSuperExpression(@NotNull JetSuperExpression expression, ExpressionTypingContext context) {
|
||||||
LabelResolver.LabeledReceiverResolutionResult resolutionResult = resolveToReceiver(expression, context, true);
|
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()));
|
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(expression, expression.getText()));
|
||||||
return errorInSuper(expression, context);
|
return errorInSuper(expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (resolutionResult.getCode()) {
|
switch (resolutionResult.getCode()) {
|
||||||
case LABEL_RESOLUTION_ERROR:
|
case LABEL_RESOLUTION_ERROR:
|
||||||
// The error is already reported
|
// The error is already reported
|
||||||
@@ -1124,7 +1124,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetTypeInfo visitRootNamespaceExpression(@NotNull JetRootNamespaceExpression expression, ExpressionTypingContext context) {
|
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);
|
return DataFlowUtils.checkType(JetModuleUtil.getRootNamespaceType(expression), expression, context, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
context.trace.report(NAMESPACE_IS_NOT_AN_EXPRESSION.on(expression));
|
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");
|
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")
|
@TestMetadata("nestedClassInPrivateClassObject.kt")
|
||||||
public void testNestedClassInPrivateClassObject() throws Exception {
|
public void testNestedClassInPrivateClassObject() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.kt");
|
doTest("compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user