Box qualified names of package directives into dot-qualified expressions

This commit is contained in:
Alexey Sedunov
2014-02-28 16:31:12 +04:00
parent 5e87fc35e0
commit d2f6b55cb5
15 changed files with 185 additions and 71 deletions
@@ -185,6 +185,8 @@ public class JetParsing extends AbstractJetParsing {
/* SimpleName{"."} */ /* SimpleName{"."} */
private void parsePackageName() { private void parsePackageName() {
PsiBuilder.Marker qualifiedExpression = mark();
boolean simpleName = true;
while (true) { while (true) {
if (myBuilder.newlineBeforeCurrentToken()) { if (myBuilder.newlineBeforeCurrentToken()) {
errorWithRecovery("Package name must be a '.'-separated identifier list placed on a single line", PACKAGE_NAME_RECOVERY_SET); 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(); nsName.drop();
} }
if (!simpleName) {
PsiBuilder.Marker precedingMarker = qualifiedExpression.precede();
qualifiedExpression.done(DOT_QUALIFIED_EXPRESSION);
qualifiedExpression = precedingMarker;
}
if (at(DOT)) { if (at(DOT)) {
simpleName = false;
advance(); // DOT advance(); // DOT
} }
else { else {
break; break;
} }
} }
qualifiedExpression.drop();
} }
/* /*
@@ -18,13 +18,15 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.name.SpecialNames; import org.jetbrains.jet.lang.resolve.name.SpecialNames;
import java.util.Collections;
import java.util.List; import java.util.List;
public class JetPackageDirective extends JetReferenceExpression { public class JetPackageDirective extends JetReferenceExpression {
@@ -34,17 +36,36 @@ public class JetPackageDirective extends JetReferenceExpression {
super(node); super(node);
} }
// This should be either JetSimpleNameExpression, or JetDotQualifiedExpression
@Nullable
public JetExpression getPackageNameExpression() {
return findChildByClass(JetExpression.class);
}
@NotNull @NotNull
public List<JetSimpleNameExpression> getPackageNames() { public List<JetSimpleNameExpression> getPackageNames() {
return findChildrenByType(JetNodeTypes.REFERENCE_EXPRESSION); JetExpression nameExpression = getPackageNameExpression();
if (nameExpression == null) return Collections.emptyList();
List<JetSimpleNameExpression> 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 @Nullable
public PsiElement getNameIdentifier() { public PsiElement getNameIdentifier() {
JetSimpleNameExpression lastPart = (JetSimpleNameExpression)findLastChildByType(JetNodeTypes.REFERENCE_EXPRESSION); JetExpression nameExpression = getPackageNameExpression();
if (lastPart == null) { if (nameExpression == null) return null;
return null;
} JetSimpleNameExpression lastPart = (JetSimpleNameExpression)PsiUtilPackage.getQualifiedElementSelector(nameExpression);
if (lastPart == null) return null;
return lastPart.getIdentifier(); return lastPart.getIdentifier();
} }
@@ -89,15 +110,13 @@ public class JetPackageDirective extends JetReferenceExpression {
@NotNull @NotNull
private String getQualifiedNameOf(@Nullable JetSimpleNameExpression nameExpression) { private String getQualifiedNameOf(@Nullable JetSimpleNameExpression nameExpression) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (JetSimpleNameExpression e : findChildrenByClass(JetSimpleNameExpression.class)) { for (JetSimpleNameExpression e : getPackageNames()) {
if (builder.length() > 0) { if (builder.length() > 0) {
builder.append("."); builder.append(".");
} }
builder.append(e.getReferencedName()); builder.append(e.getReferencedName());
if (e == nameExpression) { if (e == nameExpression) break;
break;
}
} }
return builder.toString(); return builder.toString();
} }
+2
View File
@@ -2,6 +2,8 @@ JetFile: Attributes.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
+2
View File
@@ -2,6 +2,8 @@ JetFile: Attributes_ERR.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
+2
View File
@@ -2,6 +2,8 @@ JetFile: Imports.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
+2
View File
@@ -2,6 +2,8 @@ JetFile: Imports_ERR.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
+1
View File
@@ -0,0 +1 @@
package foo.bar.baz.buzz
+18
View File
@@ -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')
+1
View File
@@ -2,6 +2,7 @@ JetFile: RootPackage.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
@@ -2,6 +2,8 @@ JetFile: SimpleModifiers.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
+2
View File
@@ -2,6 +2,8 @@ JetFile: SoftKeywords.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
+2
View File
@@ -2,6 +2,8 @@ JetFile: TypeDef.kt
PACKAGE_DIRECTIVE PACKAGE_DIRECTIVE
PsiElement(package)('package') PsiElement(package)('package')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo') PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.') PsiElement(DOT)('.')
@@ -0,0 +1,2 @@
package foo.bar.baz.buzz.
test val a = 12
@@ -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
<empty list>
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')
@@ -257,6 +257,11 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
doParsingTest("compiler/testData/psi/LocalDeclarations.kt"); doParsingTest("compiler/testData/psi/LocalDeclarations.kt");
} }
@TestMetadata("LongPackageName.kt")
public void testLongPackageName() throws Exception {
doParsingTest("compiler/testData/psi/LongPackageName.kt");
}
@TestMetadata("ModifierAsSelector.kt") @TestMetadata("ModifierAsSelector.kt")
public void testModifierAsSelector() throws Exception { public void testModifierAsSelector() throws Exception {
doParsingTest("compiler/testData/psi/ModifierAsSelector.kt"); doParsingTest("compiler/testData/psi/ModifierAsSelector.kt");
@@ -898,6 +903,11 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
doParsingTest("compiler/testData/psi/recovery/MissingCommaInValueParameterList.kt"); 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") @TestMetadata("PackageRecovery.kt")
public void testPackageRecovery() throws Exception { public void testPackageRecovery() throws Exception {
doParsingTest("compiler/testData/psi/recovery/PackageRecovery.kt"); doParsingTest("compiler/testData/psi/recovery/PackageRecovery.kt");