From d2f6b55cb51d8f0d5b4564c831f9c1ba3330a360 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 28 Feb 2014 16:31:12 +0400 Subject: [PATCH] Box qualified names of package directives into dot-qualified expressions --- .../jet/lang/parsing/JetParsing.java | 10 +++++ .../jet/lang/psi/JetPackageDirective.java | 39 ++++++++++++++----- compiler/testData/psi/Attributes.txt | 18 +++++---- compiler/testData/psi/Attributes_ERR.txt | 18 +++++---- compiler/testData/psi/Imports.txt | 18 +++++---- compiler/testData/psi/Imports_ERR.txt | 18 +++++---- compiler/testData/psi/LongPackageName.kt | 1 + compiler/testData/psi/LongPackageName.txt | 18 +++++++++ compiler/testData/psi/RootPackage.txt | 11 +++--- compiler/testData/psi/SimpleModifiers.txt | 18 +++++---- compiler/testData/psi/SoftKeywords.txt | 18 +++++---- compiler/testData/psi/TypeDef.txt | 18 +++++---- .../psi/recovery/PackageNewLineRecovery.kt | 2 + .../psi/recovery/PackageNewLineRecovery.txt | 39 +++++++++++++++++++ .../jet/parsing/JetParsingTestGenerated.java | 10 +++++ 15 files changed, 185 insertions(+), 71 deletions(-) create mode 100644 compiler/testData/psi/LongPackageName.kt create mode 100644 compiler/testData/psi/LongPackageName.txt create mode 100644 compiler/testData/psi/recovery/PackageNewLineRecovery.kt create mode 100644 compiler/testData/psi/recovery/PackageNewLineRecovery.txt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java index ba1ddf3c73b..4fc2956c295 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -185,6 +185,8 @@ public class JetParsing extends AbstractJetParsing { /* SimpleName{"."} */ private void parsePackageName() { + PsiBuilder.Marker qualifiedExpression = mark(); + boolean simpleName = true; while (true) { if (myBuilder.newlineBeforeCurrentToken()) { errorWithRecovery("Package name must be a '.'-separated identifier list placed on a single line", PACKAGE_NAME_RECOVERY_SET); @@ -199,13 +201,21 @@ public class JetParsing extends AbstractJetParsing { nsName.drop(); } + if (!simpleName) { + PsiBuilder.Marker precedingMarker = qualifiedExpression.precede(); + qualifiedExpression.done(DOT_QUALIFIED_EXPRESSION); + qualifiedExpression = precedingMarker; + } + if (at(DOT)) { + simpleName = false; advance(); // DOT } else { break; } } + qualifiedExpression.drop(); } /* diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java index cf5b7fd5395..a932de43d7a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPackageDirective.java @@ -18,13 +18,15 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.SpecialNames; +import java.util.Collections; import java.util.List; public class JetPackageDirective extends JetReferenceExpression { @@ -34,17 +36,36 @@ public class JetPackageDirective extends JetReferenceExpression { super(node); } + // This should be either JetSimpleNameExpression, or JetDotQualifiedExpression + @Nullable + public JetExpression getPackageNameExpression() { + return findChildByClass(JetExpression.class); + } + @NotNull public List getPackageNames() { - return findChildrenByType(JetNodeTypes.REFERENCE_EXPRESSION); + JetExpression nameExpression = getPackageNameExpression(); + if (nameExpression == null) return Collections.emptyList(); + + List packageNames = ContainerUtil.newArrayList(); + while (nameExpression instanceof JetQualifiedExpression) { + JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) nameExpression; + packageNames.add((JetSimpleNameExpression) qualifiedExpression.getSelectorExpression()); + nameExpression = qualifiedExpression.getReceiverExpression(); + } + packageNames.add((JetSimpleNameExpression) nameExpression); + Collections.reverse(packageNames); + + return packageNames; } @Nullable public PsiElement getNameIdentifier() { - JetSimpleNameExpression lastPart = (JetSimpleNameExpression)findLastChildByType(JetNodeTypes.REFERENCE_EXPRESSION); - if (lastPart == null) { - return null; - } + JetExpression nameExpression = getPackageNameExpression(); + if (nameExpression == null) return null; + + JetSimpleNameExpression lastPart = (JetSimpleNameExpression)PsiUtilPackage.getQualifiedElementSelector(nameExpression); + if (lastPart == null) return null; return lastPart.getIdentifier(); } @@ -89,15 +110,13 @@ public class JetPackageDirective extends JetReferenceExpression { @NotNull private String getQualifiedNameOf(@Nullable JetSimpleNameExpression nameExpression) { StringBuilder builder = new StringBuilder(); - for (JetSimpleNameExpression e : findChildrenByClass(JetSimpleNameExpression.class)) { + for (JetSimpleNameExpression e : getPackageNames()) { if (builder.length() > 0) { builder.append("."); } builder.append(e.getReferencedName()); - if (e == nameExpression) { - break; - } + if (e == nameExpression) break; } return builder.toString(); } diff --git a/compiler/testData/psi/Attributes.txt b/compiler/testData/psi/Attributes.txt index a60e346bee2..1a1c0a00710 100644 --- a/compiler/testData/psi/Attributes.txt +++ b/compiler/testData/psi/Attributes.txt @@ -2,14 +2,16 @@ JetFile: Attributes.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('goo') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('goo') PsiWhiteSpace('\n\n') CLASS MODIFIER_LIST diff --git a/compiler/testData/psi/Attributes_ERR.txt b/compiler/testData/psi/Attributes_ERR.txt index 39f9f8ea88f..f6a359bf155 100644 --- a/compiler/testData/psi/Attributes_ERR.txt +++ b/compiler/testData/psi/Attributes_ERR.txt @@ -2,14 +2,16 @@ JetFile: Attributes_ERR.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('goo') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('goo') PsiWhiteSpace('\n\n') CLASS MODIFIER_LIST diff --git a/compiler/testData/psi/Imports.txt b/compiler/testData/psi/Imports.txt index c20892204a1..40513b30904 100644 --- a/compiler/testData/psi/Imports.txt +++ b/compiler/testData/psi/Imports.txt @@ -2,14 +2,16 @@ JetFile: Imports.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('goo') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('goo') PsiWhiteSpace('\n\n') IMPORT_LIST IMPORT_DIRECTIVE diff --git a/compiler/testData/psi/Imports_ERR.txt b/compiler/testData/psi/Imports_ERR.txt index 60ff6011022..1f769ea2551 100644 --- a/compiler/testData/psi/Imports_ERR.txt +++ b/compiler/testData/psi/Imports_ERR.txt @@ -2,14 +2,16 @@ JetFile: Imports_ERR.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('goo') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('goo') PsiWhiteSpace('\n\n') IMPORT_LIST IMPORT_DIRECTIVE diff --git a/compiler/testData/psi/LongPackageName.kt b/compiler/testData/psi/LongPackageName.kt new file mode 100644 index 00000000000..1df1922875e --- /dev/null +++ b/compiler/testData/psi/LongPackageName.kt @@ -0,0 +1 @@ +package foo.bar.baz.buzz \ No newline at end of file diff --git a/compiler/testData/psi/LongPackageName.txt b/compiler/testData/psi/LongPackageName.txt new file mode 100644 index 00000000000..da7a9e7ea5b --- /dev/null +++ b/compiler/testData/psi/LongPackageName.txt @@ -0,0 +1,18 @@ +JetFile: LongPackageName.kt + PACKAGE_DIRECTIVE + PsiElement(package)('package') + PsiWhiteSpace(' ') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('baz') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('buzz') \ No newline at end of file diff --git a/compiler/testData/psi/RootPackage.txt b/compiler/testData/psi/RootPackage.txt index 49e8322a696..11cb2e7075d 100644 --- a/compiler/testData/psi/RootPackage.txt +++ b/compiler/testData/psi/RootPackage.txt @@ -2,11 +2,12 @@ JetFile: RootPackage.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') PsiElement(SEMICOLON)(';') PsiWhiteSpace('\n\n') CLASS diff --git a/compiler/testData/psi/SimpleModifiers.txt b/compiler/testData/psi/SimpleModifiers.txt index 74e9e31cf09..6ff0a067aa1 100644 --- a/compiler/testData/psi/SimpleModifiers.txt +++ b/compiler/testData/psi/SimpleModifiers.txt @@ -2,14 +2,16 @@ JetFile: SimpleModifiers.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('goo') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('goo') PsiWhiteSpace('\n\n') CLASS MODIFIER_LIST diff --git a/compiler/testData/psi/SoftKeywords.txt b/compiler/testData/psi/SoftKeywords.txt index 16f0fa4b0ca..6c9fa68b99c 100644 --- a/compiler/testData/psi/SoftKeywords.txt +++ b/compiler/testData/psi/SoftKeywords.txt @@ -2,14 +2,16 @@ JetFile: SoftKeywords.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('goo') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('goo') PsiWhiteSpace('\n\n') IMPORT_LIST IMPORT_DIRECTIVE diff --git a/compiler/testData/psi/TypeDef.txt b/compiler/testData/psi/TypeDef.txt index 1ffa18263b5..eac894dc895 100644 --- a/compiler/testData/psi/TypeDef.txt +++ b/compiler/testData/psi/TypeDef.txt @@ -2,14 +2,16 @@ JetFile: TypeDef.kt PACKAGE_DIRECTIVE PsiElement(package)('package') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('bar') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('goo') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('goo') PsiWhiteSpace('\n\n') TYPEDEF PsiElement(type)('type') diff --git a/compiler/testData/psi/recovery/PackageNewLineRecovery.kt b/compiler/testData/psi/recovery/PackageNewLineRecovery.kt new file mode 100644 index 00000000000..d867219775f --- /dev/null +++ b/compiler/testData/psi/recovery/PackageNewLineRecovery.kt @@ -0,0 +1,2 @@ +package foo.bar.baz.buzz. +test val a = 12 \ No newline at end of file diff --git a/compiler/testData/psi/recovery/PackageNewLineRecovery.txt b/compiler/testData/psi/recovery/PackageNewLineRecovery.txt new file mode 100644 index 00000000000..92edbacb991 --- /dev/null +++ b/compiler/testData/psi/recovery/PackageNewLineRecovery.txt @@ -0,0 +1,39 @@ +JetFile: PackageNewLineRecovery.kt + PACKAGE_DIRECTIVE + PsiElement(package)('package') + PsiWhiteSpace(' ') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('baz') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('buzz') + PsiElement(DOT)('.') + PsiErrorElement:Package name must be a '.'-separated identifier list placed on a single line + + PsiWhiteSpace('\n') + PROPERTY + MODIFIER_LIST + ANNOTATION_ENTRY + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('test') + PsiWhiteSpace(' ') + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('a') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('12') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java b/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java index 764b9cf154d..6ced9b565e4 100644 --- a/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java @@ -257,6 +257,11 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { doParsingTest("compiler/testData/psi/LocalDeclarations.kt"); } + @TestMetadata("LongPackageName.kt") + public void testLongPackageName() throws Exception { + doParsingTest("compiler/testData/psi/LongPackageName.kt"); + } + @TestMetadata("ModifierAsSelector.kt") public void testModifierAsSelector() throws Exception { doParsingTest("compiler/testData/psi/ModifierAsSelector.kt"); @@ -898,6 +903,11 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { doParsingTest("compiler/testData/psi/recovery/MissingCommaInValueParameterList.kt"); } + @TestMetadata("PackageNewLineRecovery.kt") + public void testPackageNewLineRecovery() throws Exception { + doParsingTest("compiler/testData/psi/recovery/PackageNewLineRecovery.kt"); + } + @TestMetadata("PackageRecovery.kt") public void testPackageRecovery() throws Exception { doParsingTest("compiler/testData/psi/recovery/PackageRecovery.kt");