Parser: Do not produce qualified expressions without receiver in package directives. Add assertion on JetQualifiedExpression
#KT-6907 Fixed
This commit is contained in:
@@ -228,8 +228,16 @@ public class JetParsing extends AbstractJetParsing {
|
||||
break;
|
||||
}
|
||||
|
||||
if (at(DOT)) {
|
||||
advance(); // DOT
|
||||
qualifiedExpression.error("Package name must be a '.'-separated identifier list");
|
||||
qualifiedExpression = mark();
|
||||
continue;
|
||||
}
|
||||
|
||||
PsiBuilder.Marker nsName = mark();
|
||||
if (expect(IDENTIFIER, "Package name must be a '.'-separated identifier list", PACKAGE_NAME_RECOVERY_SET)) {
|
||||
boolean simpleNameFound = expect(IDENTIFIER, "Package name must be a '.'-separated identifier list", PACKAGE_NAME_RECOVERY_SET);
|
||||
if (simpleNameFound) {
|
||||
nsName.done(REFERENCE_EXPRESSION);
|
||||
}
|
||||
else {
|
||||
@@ -243,8 +251,15 @@ public class JetParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
if (at(DOT)) {
|
||||
simpleName = false;
|
||||
advance(); // DOT
|
||||
|
||||
if (simpleName && !simpleNameFound) {
|
||||
qualifiedExpression.drop();
|
||||
qualifiedExpression = mark();
|
||||
}
|
||||
else {
|
||||
simpleName = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode
|
||||
import org.jetbrains.kotlin.lexer.JetToken
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
|
||||
object JetQualifiedExpressionImpl {
|
||||
public fun JetQualifiedExpression.getOperationTokenNode(): ASTNode {
|
||||
@@ -31,20 +32,15 @@ object JetQualifiedExpressionImpl {
|
||||
return this.getOperationTokenNode().getElementType() as JetToken
|
||||
}
|
||||
|
||||
private fun JetQualifiedExpression.getExpression(afterOperation: Boolean): JetExpression? {
|
||||
return getOperationTokenNode()?.getPsi()?.siblings(afterOperation, false)?.firstOrNull { it is JetExpression } as? JetExpression
|
||||
}
|
||||
|
||||
public fun JetQualifiedExpression.getReceiverExpression(): JetExpression {
|
||||
val left = PsiTreeUtil.findChildOfType(this, javaClass<JetExpression>())
|
||||
return left!!
|
||||
return getExpression(false) ?: throw AssertionError("No receiver found: ${JetPsiUtil.getElementTextWithContext(this)}")
|
||||
}
|
||||
|
||||
public fun JetQualifiedExpression.getSelectorExpression(): JetExpression? {
|
||||
var node: ASTNode? = getOperationTokenNode()
|
||||
while (node != null) {
|
||||
val psi = node!!.getPsi()
|
||||
if (psi is JetExpression) {
|
||||
return (psi as JetExpression)
|
||||
}
|
||||
node = node!!.getTreeNext()
|
||||
}
|
||||
return null
|
||||
return getExpression(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
package .a b
|
||||
@@ -0,0 +1,18 @@
|
||||
JetFile: PackageLeadingDotDoubleID.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiErrorElement:Expecting a top level declaration
|
||||
<empty list>
|
||||
@@ -0,0 +1 @@
|
||||
package .a.b.c.
|
||||
@@ -0,0 +1,19 @@
|
||||
JetFile: PackageLongNameBetweenDots.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('c')
|
||||
PsiElement(DOT)('.')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list placed on a single line
|
||||
<empty list>
|
||||
@@ -0,0 +1 @@
|
||||
package a b
|
||||
@@ -0,0 +1,16 @@
|
||||
JetFile: PackageLongNameDoubleID.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiErrorElement:Expecting a top level declaration
|
||||
<empty list>
|
||||
@@ -0,0 +1 @@
|
||||
package .a.b.c
|
||||
@@ -0,0 +1,16 @@
|
||||
JetFile: PackageLongNameLeadingDot.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('c')
|
||||
@@ -0,0 +1 @@
|
||||
package . .a.b.c
|
||||
@@ -0,0 +1,19 @@
|
||||
JetFile: PackageLongNameLeadingDoubleDot.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('c')
|
||||
@@ -0,0 +1 @@
|
||||
package . .
|
||||
@@ -0,0 +1,11 @@
|
||||
JetFile: PackageNameDoubleDot.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list placed on a single line
|
||||
<empty list>
|
||||
@@ -0,0 +1 @@
|
||||
package .
|
||||
@@ -0,0 +1,8 @@
|
||||
JetFile: PackageNameJustDot.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list placed on a single line
|
||||
<empty list>
|
||||
@@ -0,0 +1 @@
|
||||
package .a
|
||||
@@ -0,0 +1,8 @@
|
||||
JetFile: PackageSimpleNameLeadingDot.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
@@ -0,0 +1 @@
|
||||
package . .a
|
||||
@@ -0,0 +1,11 @@
|
||||
JetFile: PackageSimpleNameLeadingDoubleDot.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Package name must be a '.'-separated identifier list
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
@@ -43,6 +43,7 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
|
||||
Psi.FunctionReceivers.class,
|
||||
Psi.GreatSyntacticShift.class,
|
||||
Psi.Kdoc.class,
|
||||
Psi.Packages.class,
|
||||
Psi.PlatformTypesRecovery.class,
|
||||
Psi.PropertyDelegate.class,
|
||||
Psi.Recovery.class,
|
||||
@@ -433,18 +434,6 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageBlockFirst.kt")
|
||||
public void testPackageBlockFirst() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/PackageBlockFirst.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageModifiers.kt")
|
||||
public void testPackageModifiers() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/PackageModifiers.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ParameterNameMising.kt")
|
||||
public void testParameterNameMising() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/ParameterNameMising.kt");
|
||||
@@ -1200,6 +1189,81 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/packages")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Packages extends AbstractJetParsingTest {
|
||||
public void testAllFilesPresentInPackages() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/packages"), Pattern.compile("^(.*)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageBlockFirst.kt")
|
||||
public void testPackageBlockFirst() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageBlockFirst.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageLeadingDotDoubleID.kt")
|
||||
public void testPackageLeadingDotDoubleID() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageLeadingDotDoubleID.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageLongNameBetweenDots.kt")
|
||||
public void testPackageLongNameBetweenDots() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageLongNameBetweenDots.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageLongNameDoubleID.kt")
|
||||
public void testPackageLongNameDoubleID() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageLongNameDoubleID.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageLongNameLeadingDot.kt")
|
||||
public void testPackageLongNameLeadingDot() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageLongNameLeadingDot.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageLongNameLeadingDoubleDot.kt")
|
||||
public void testPackageLongNameLeadingDoubleDot() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageLongNameLeadingDoubleDot.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageModifiers.kt")
|
||||
public void testPackageModifiers() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageModifiers.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageNameDoubleDot.kt")
|
||||
public void testPackageNameDoubleDot() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageNameDoubleDot.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageNameJustDot.kt")
|
||||
public void testPackageNameJustDot() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageNameJustDot.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageSimpleNameLeadingDot.kt")
|
||||
public void testPackageSimpleNameLeadingDot() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageSimpleNameLeadingDot.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageSimpleNameLeadingDoubleDot.kt")
|
||||
public void testPackageSimpleNameLeadingDoubleDot() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/packages/PackageSimpleNameLeadingDoubleDot.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/platformTypesRecovery")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user