Add common JetElement for imports: JetImportList

This commit is contained in:
Natalia Ukhorskaya
2013-10-23 18:07:22 +04:00
parent 796dad5798
commit 3287744415
24 changed files with 550 additions and 343 deletions
@@ -51,6 +51,7 @@ public interface JetNodeTypes {
IElementType VALUE_PARAMETER = JetStubElementTypes.VALUE_PARAMETER;
JetNodeType CLASS_BODY = new JetNodeType("CLASS_BODY", JetClassBody.class);
JetNodeType IMPORT_LIST = new JetNodeType("IMPORT_LIST", JetImportList.class);
JetNodeType IMPORT_DIRECTIVE = new JetNodeType("IMPORT_DIRECTIVE", JetImportDirective.class);
JetNodeType MODIFIER_LIST = new JetNodeType("MODIFIER_LIST", JetModifierList.class);
JetNodeType PRIMARY_CONSTRUCTOR_MODIFIER_LIST = new JetNodeType("PRIMARY_CONSTRUCTOR_MODIFIER_LIST", JetModifierList.class);
@@ -86,7 +86,7 @@ public class JetParsing extends AbstractJetParsing {
/*
* [start] jetlFile
* : preamble toplevelObject[| import]* [eof]
* : preamble toplevelObject* [eof]
* ;
*/
void parseFile() {
@@ -94,7 +94,9 @@ public class JetParsing extends AbstractJetParsing {
parsePreamble(true);
parseToplevelDeclarations(false);
while (!eof()) {
parseTopLevelObject();
}
fileMarker.done(JET_FILE);
}
@@ -140,20 +142,6 @@ public class JetParsing extends AbstractJetParsing {
fileMarker.done(JET_FILE);
}
/*
* toplevelObject[| import]*
*/
private void parseToplevelDeclarations(boolean insideBlock) {
while (!eof() && (!insideBlock || !at(RBRACE))) {
if (at(IMPORT_KEYWORD)) {
parseImportDirective();
}
else {
parseTopLevelObject();
}
}
}
/*
*preamble
* : namespaceHeader? import*
@@ -230,6 +218,10 @@ public class JetParsing extends AbstractJetParsing {
PsiBuilder.Marker importDirective = mark();
advance(); // IMPORT_KEYWORD
if (closeImportWithErrorIfNewline(importDirective, "Expecting qualified name")) {
return;
}
PsiBuilder.Marker qualifiedName = mark();
PsiBuilder.Marker reference = mark();
@@ -239,6 +231,11 @@ public class JetParsing extends AbstractJetParsing {
while (at(DOT) && lookahead(1) != MUL) {
advance(); // DOT
if (closeImportWithErrorIfNewline(importDirective, "Import must be placed on a single line")) {
qualifiedName.drop();
return;
}
reference = mark();
if (expect(IDENTIFIER, "Qualified name must be a '.'-separated identifier list", IMPORT_RECOVERY_SET)) {
reference.done(REFERENCE_EXPRESSION);
@@ -257,29 +254,44 @@ public class JetParsing extends AbstractJetParsing {
advance(); // DOT
assert _at(MUL);
advance(); // MUL
handleUselessRename();
if (at(AS_KEYWORD)) {
PsiBuilder.Marker as = mark();
advance(); // AS_KEYWORD
if (closeImportWithErrorIfNewline(importDirective, "Expecting identifier")) {
as.drop();
return;
}
consumeIf(IDENTIFIER);
as.error("Cannot rename all imported items to one identifier");
}
}
if (at(AS_KEYWORD)) {
advance(); // AS_KEYWORD
if (closeImportWithErrorIfNewline(importDirective, "Expecting identifier")) {
return;
}
expect(IDENTIFIER, "Expecting identifier", TokenSet.create(SEMICOLON));
}
consumeIf(SEMICOLON);
importDirective.done(IMPORT_DIRECTIVE);
}
private void parseImportDirectives() {
// TODO: Duplicate with parsing imports in parseToplevelDeclarations
while (at(IMPORT_KEYWORD)) {
parseImportDirective();
private boolean closeImportWithErrorIfNewline(PsiBuilder.Marker importDirective, String errorMessage) {
if (myBuilder.newlineBeforeCurrentToken()) {
error(errorMessage);
importDirective.done(IMPORT_DIRECTIVE);
return true;
}
return false;
}
private void handleUselessRename() {
if (at(AS_KEYWORD)) {
PsiBuilder.Marker as = mark();
advance(); // AS_KEYWORD
consumeIf(IDENTIFIER);
as.error("Cannot rename a all imported items to one identifier");
private void parseImportDirectives() {
if (at(IMPORT_KEYWORD)) {
PsiBuilder.Marker importList = mark();
while (at(IMPORT_KEYWORD)) {
parseImportDirective();
}
importList.done(IMPORT_LIST);
}
}
@@ -19,21 +19,9 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.lang.ASTNode;
import com.intellij.lang.FileASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLock;
import com.intellij.psi.stubs.ObjectStubTree;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubTree;
import com.intellij.psi.stubs.StubTreeLoader;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,6 +30,7 @@ import org.jetbrains.jet.lang.psi.stubs.PsiJetFileStub;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.JetLanguage;
import java.util.Collections;
import java.util.List;
public class JetFile extends PsiFileBase implements JetDeclarationContainer, JetElement {
@@ -79,8 +68,15 @@ public class JetFile extends PsiFileBase implements JetDeclarationContainer, Jet
return PsiTreeUtil.getChildrenOfTypeAsList(this, JetDeclaration.class);
}
@Nullable
public JetImportList getImportList() {
return findChildByClass(JetImportList.class);
}
@NotNull
public List<JetImportDirective> getImportDirectives() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, JetImportDirective.class);
JetImportList importList = getImportList();
return importList != null ? importList.getImports() : Collections.<JetImportDirective>emptyList();
}
@Nullable
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class JetImportList extends JetElementImpl {
public JetImportList(@NotNull ASTNode node) {
super(node);
}
@Override
public void accept(@NotNull JetVisitorVoid visitor) {
visitor.visitImportList(this);
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitImportList(this, data);
}
@NotNull
public List<JetImportDirective> getImports() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, JetImportDirective.class);
}
}
@@ -305,6 +305,12 @@ public class JetPsiFactory {
return namespace.getImportDirectives().iterator().next();
}
@NotNull
public static JetImportList createImportDirectiveWithImportList(Project project, @NotNull ImportPath importPath) {
JetImportDirective importDirective = createImportDirective(project, importPath);
return (JetImportList) importDirective.getParent();
}
@NotNull
public static PsiElement createPrimaryConstructor(Project project) {
JetClass aClass = createClass(project, "class A()");
@@ -19,7 +19,9 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
public class JetScript extends JetDeclarationImpl {
@@ -33,9 +35,15 @@ public class JetScript extends JetDeclarationImpl {
return findNotNullChildByClass(JetBlockExpression.class);
}
@Nullable
public JetImportList getImportList() {
return findChildByClass(JetImportList.class);
}
@NotNull
public List<JetImportDirective> getImportDirectives() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, JetImportDirective.class);
JetImportList importList = getImportList();
return importList != null ? importList.getImports() : Collections.<JetImportDirective>emptyList();
}
@NotNull
@@ -70,6 +70,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
return visitJetElement(importDirective, data);
}
public R visitImportList(@NotNull JetImportList importList, D data) {
return visitJetElement(importList, data);
}
public R visitClassBody(@NotNull JetClassBody classBody, D data) {
return visitJetElement(classBody, data);
}
@@ -59,6 +59,10 @@ public class JetVisitorVoid extends PsiElementVisitor {
visitJetElement(importDirective);
}
public void visitImportList(JetImportList importList) {
visitJetElement(importList);
}
public void visitClassBody(JetClassBody classBody) {
visitJetElement(classBody);
}