Create class descriptors for local classes in illegal positions
Typecheck code in illegal selector position Fixes exceptions on "val p = A.class" erroneous code
This commit is contained in:
@@ -81,7 +81,7 @@ public class OverloadResolver {
|
||||
else if (containingDeclaration instanceof ScriptDescriptor) {
|
||||
// TODO: check overload conflicts of functions with constructors in scripts
|
||||
}
|
||||
else if (!(containingDeclaration instanceof FunctionDescriptor)) {
|
||||
else if (!(containingDeclaration instanceof FunctionDescriptor || containingDeclaration instanceof PropertyDescriptor)) {
|
||||
throw new IllegalStateException("Illegal class container: " + containingDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,6 +321,7 @@ public class CallExpressionResolver {
|
||||
return getSimpleNameExpressionTypeInfo((KtSimpleNameExpression) selectorExpression, receiver, callOperationNode, context);
|
||||
}
|
||||
else if (selectorExpression != null) {
|
||||
expressionTypingServices.getTypeInfo(selectorExpression, context);
|
||||
context.trace.report(ILLEGAL_SELECTOR.on(selectorExpression, selectorExpression.getText()));
|
||||
}
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
|
||||
+21
-2
@@ -1448,6 +1448,26 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return components.dataFlowAnalyzer.checkType(resolveArrayAccessGetMethod(expression, context), expression, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitClass(@NotNull KtClass klass, ExpressionTypingContext context) {
|
||||
// analyze class in illegal position and write descriptor to trace but do not write to any scope
|
||||
components.localClassifierAnalyzer.processClassOrObject(
|
||||
null, context.replaceContextDependency(INDEPENDENT),
|
||||
context.scope.getOwnerDescriptor(),
|
||||
klass
|
||||
);
|
||||
return declarationInIllegalContext(klass, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static KotlinTypeInfo declarationInIllegalContext(
|
||||
@NotNull KtDeclaration declaration,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(declaration));
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KotlinTypeInfo getTypeInfoForBinaryCall(
|
||||
@NotNull Name name,
|
||||
@@ -1486,8 +1506,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitDeclaration(@NotNull KtDeclaration dcl, ExpressionTypingContext context) {
|
||||
context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(dcl));
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
return declarationInIllegalContext(dcl, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
@@ -384,6 +384,11 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
|
||||
return basic.visitDeclaration(dcl, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitClass(@NotNull KtClass klass, ExpressionTypingContext data) {
|
||||
return basic.visitClass(klass, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitStringTemplateExpression(@NotNull KtStringTemplateExpression expression, ExpressionTypingContext data) {
|
||||
return basic.visitStringTemplateExpression(expression, data);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
val receiver = { Int.(<!SYNTAX!><!>) <!SYNTAX!>-><!> }
|
||||
val receiverWithParameter = { Int.<!ILLEGAL_SELECTOR!>(<!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>)<!> <!SYNTAX!>-><!> }
|
||||
val receiverWithParameter = { Int.<!ILLEGAL_SELECTOR!>(<!UNRESOLVED_REFERENCE!>a<!>)<!> <!SYNTAX!>-><!> }
|
||||
|
||||
val receiverAndReturnType = { Int.(<!SYNTAX!><!>)<!SYNTAX!>: Int -> 5<!> }
|
||||
val receiverAndReturnTypeWithParameter = { Int.(<!DEBUG_INFO_MISSING_UNRESOLVED!>a<!><!SYNTAX!><!SYNTAX!><!>: Int): Int -> 5<!> }
|
||||
val receiverAndReturnTypeWithParameter = { Int.(<!UNRESOLVED_REFERENCE!>a<!><!SYNTAX!><!SYNTAX!><!>: Int): Int -> 5<!> }
|
||||
|
||||
val returnType = { (<!SYNTAX!><!>)<!SYNTAX!>: Int -> 5<!> }
|
||||
val returnTypeWithParameter = { (<!UNRESOLVED_REFERENCE!>b<!><!SYNTAX!><!SYNTAX!><!>: Int): Int -> 5<!> }
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
fun foo(s: String) {
|
||||
s.
|
||||
<!ILLEGAL_SELECTOR!>val b = 42<!>
|
||||
<!DECLARATION_IN_ILLEGAL_CONTEXT, ILLEGAL_SELECTOR!>val b = 42<!>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class A
|
||||
|
||||
fun f() {
|
||||
A.class<EOLError descr="Name expected"></EOLError>
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun f() {
|
||||
A.<error>class B {
|
||||
fun f() {
|
||||
f()
|
||||
}
|
||||
}</error>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
val p = 1 < <error>class A {
|
||||
fun f() {
|
||||
f()
|
||||
}
|
||||
}</error>
|
||||
@@ -0,0 +1 @@
|
||||
fun g() = 1 < <error>class A</error>
|
||||
@@ -0,0 +1,7 @@
|
||||
fun f(<warning>i</warning>: Int = 3 < <error>class A {
|
||||
fun f() {
|
||||
f()
|
||||
}
|
||||
}</error>) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class A
|
||||
|
||||
fun f() {
|
||||
A.<error>fun <error>g</error>() {
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: g">g</error>()
|
||||
}</error>
|
||||
}
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
interface Hi {
|
||||
fun foo(): Int
|
||||
interface <lineMarker></lineMarker>Hi {
|
||||
fun <lineMarker></lineMarker>foo(): Int
|
||||
}
|
||||
|
||||
// Closing brace is intentionally missed
|
||||
val id = array("kotlin.FlexibleType"
|
||||
|
||||
private class Some(): Hi {
|
||||
override fun foo() = 1
|
||||
override fun <lineMarker></lineMarker>foo() = 1
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="no_name_in_PSI_3d19d79d_1ba9_4cd0_b7f5_b46aa3cd5d40 in f() in main.kt ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A
|
||||
|
||||
fun f() {
|
||||
A.class<caret>
|
||||
}
|
||||
|
||||
@@ -55,4 +55,12 @@
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused Symbol</problem_class>
|
||||
<description>Property 'id' is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>BadCodeNoExceptions.kt</file>
|
||||
<line>4</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/BadCodeNoExceptions.kt" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused symbol</problem_class>
|
||||
<description>Class 'Some' is never used</description>
|
||||
</problem>
|
||||
</problems>
|
||||
|
||||
@@ -394,6 +394,36 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassDeclarationAfterDot.kt")
|
||||
public void testClassDeclarationAfterDot() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ClassDeclarationAfterDot.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassDeclarationAfterDot2.kt")
|
||||
public void testClassDeclarationAfterDot2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ClassDeclarationAfterDot2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassDeclarationAsExpression.kt")
|
||||
public void testClassDeclarationAsExpression() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ClassDeclarationAsExpression.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassDeclarationAsExpression2.kt")
|
||||
public void testClassDeclarationAsExpression2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ClassDeclarationAsExpression2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassDeclarationAsExpression3.kt")
|
||||
public void testClassDeclarationAsExpression3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ClassDeclarationAsExpression3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CoercionToUnit.kt")
|
||||
public void testCoercionToUnit() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/CoercionToUnit.kt");
|
||||
@@ -418,6 +448,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FunDeclarationAfterDot.kt")
|
||||
public void testFunDeclarationAfterDot() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/FunDeclarationAfterDot.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("javaStyleClassLiteralInAnnotationArguments.kt")
|
||||
public void testJavaStyleClassLiteralInAnnotationArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/javaStyleClassLiteralInAnnotationArguments.kt");
|
||||
|
||||
@@ -157,6 +157,12 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
|
||||
doTypeClassHierarchyTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("JavaStyleClassLiteralInvalidCode")
|
||||
public void testJavaStyleClassLiteralInvalidCode() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/type/JavaStyleClassLiteralInvalidCode/");
|
||||
doTypeClassHierarchyTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("JetInt")
|
||||
public void testJetInt() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/type/JetInt/");
|
||||
|
||||
Reference in New Issue
Block a user