From 921d74d821c2411a954901a7adb4bbfb0cdf9314 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Dec 2010 17:09:30 +0300 Subject: [PATCH] Namespace blocks --- grammar/src/expressions.grm | 2 +- idea/src/org/jetbrains/jet/JetNodeTypes.java | 2 + .../jet/lang/parsing/JetParsing.java | 201 ++++++++----- .../org/jetbrains/jet/lexer/JetTokens.java | 2 + idea/testData/psi/NamespaceBlock.jet | 29 ++ idea/testData/psi/NamespaceBlock.txt | 138 +++++++++ idea/testData/psi/NamespaceBlock_ERR.jet | 44 +++ idea/testData/psi/NamespaceBlock_ERR.txt | 271 ++++++++++++++++++ .../jetbrains/jet/parsing/JetParsingTest.java | 2 + 9 files changed, 612 insertions(+), 79 deletions(-) create mode 100644 idea/testData/psi/NamespaceBlock.jet create mode 100644 idea/testData/psi/NamespaceBlock.txt create mode 100644 idea/testData/psi/NamespaceBlock_ERR.jet create mode 100644 idea/testData/psi/NamespaceBlock_ERR.txt diff --git a/grammar/src/expressions.grm b/grammar/src/expressions.grm index e34c2bc04c1..ae5acebf2a6 100644 --- a/grammar/src/expressions.grm +++ b/grammar/src/expressions.grm @@ -125,7 +125,7 @@ typeArguments ; valueArguments - : "(" (SimpleName "=")? expression{","} ")" + : "(" (SimpleName "=")? ("out" | "ref")? expression{","} ")" ; infixFunctionCall diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 3bc2a83bca6..dc80fcd99e4 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -30,6 +30,8 @@ public interface JetNodeTypes { JetNodeType CLASS_BODY = new JetNodeType("CLASS_BODY"); JetNodeType IMPORT_DIRECTIVE = new JetNodeType("IMPORT_DIRECTIVE"); JetNodeType IMPORTED = new JetNodeType("IMPORTED"); + JetNodeType NAMESPACE_BODY = new JetNodeType("NAMESPACE_BODY"); + IElementType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME"); } diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 823ad21baae..4163893ae21 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -3,7 +3,6 @@ */ package org.jetbrains.jet.lang.parsing; -import com.intellij.lang.ITokenTypeRemapper; import com.intellij.lang.PsiBuilder; import com.intellij.lang.WhitespaceSkippedCallback; import com.intellij.psi.tree.IElementType; @@ -52,7 +51,17 @@ public class JetParsing { parsePreamble(); - while (!eof()) { + parseToplevelDeclarations(false); + + namespaceMarker.done(NAMESPACE); + fileMarker.done(JET_FILE); + } + + /* + * toplevelObject[| import]* + */ + private void parseToplevelDeclarations(boolean insideBlock) { + while (!eof() && (!insideBlock || !at(RBRACE))) { if (at(IMPORT_KEYWORD)) { parseImportDirective(); } @@ -60,9 +69,6 @@ public class JetParsing { parseTopLevelObject(); } } - - namespaceMarker.done(NAMESPACE); - fileMarker.done(JET_FILE); } /* @@ -77,7 +83,7 @@ public class JetParsing { * ; */ if (at(NAMESPACE_KEYWORD)) { - advance(); + advance(); // NAMESPACE_KEYWORD parseNamespaceName(); } @@ -92,7 +98,7 @@ public class JetParsing { PsiBuilder.Marker nsName = mark(); expect(IDENTIFIER, "Expecting qualified name", NAMESPACE_NAME_RECOVERY_SET); while (at(DOT)) { - advance(); + advance(); // DOT expect(IDENTIFIER, "Namespace name must be a '.'-separated identifier list", NAMESPACE_NAME_RECOVERY_SET); if (at(EOL_OR_SEMICOLON)) break; } @@ -107,16 +113,16 @@ public class JetParsing { private void parseImportDirective() { assert at(IMPORT_KEYWORD); PsiBuilder.Marker importDirective = mark(); - advance(); + advance(); // IMPORT_KEYWORD expect(IDENTIFIER, "Expecting qualified name", TokenSet.create(DOT, MAP)); while (at(DOT)) { - advance(); + advance(); // DOT if (at(IDENTIFIER)) { - advance(); + advance(); // IDENTIFIER } else if (at(MUL)) { - advance(); + advance(); // MUL handleUselessRename(); break; } @@ -125,41 +131,50 @@ public class JetParsing { } } if (at(MAP)) { - advance(); + advance(); // MAP handleUselessRename(); } else if (at(AS_KEYWORD)) { - advance(); + advance(); // AS_KEYWORD expect(IDENTIFIER, "Expecting identifier", TokenSet.create(SEMICOLON)); } cosumeIf(SEMICOLON); importDirective.done(IMPORT_DIRECTIVE); } - private void cosumeIf(JetToken token) { - if (at(token)) advance(); - } - private void handleUselessRename() { if (at(AS_KEYWORD)) { PsiBuilder.Marker as = mark(); - advance(); + advance(); // AS_KEYWORD cosumeIf(IDENTIFIER); as.error("Cannot rename a all imported items to one identifier"); } } + /* + * toplevelObject + * : namespace + * : class + * : extension + * : function + * : property + * : typedef + * ; + */ private void parseTopLevelObject() { PsiBuilder.Marker decl = mark(); if (!parseModifierList()) { decl.drop(); - advance(); + advance(); // TODO return; } JetToken keywordToken = tt(); JetNodeType declType = null; - if (keywordToken == CLASS_KEYWORD) { + if (keywordToken == NAMESPACE_KEYWORD) { + declType = parseNamespaceBlock(); + } + else if (keywordToken == CLASS_KEYWORD) { declType = parseClass(); } else if (keywordToken == EXTENSION_KEYWORD) { @@ -171,9 +186,6 @@ public class JetParsing { else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) { declType = parseProperty(); } - else if (keywordToken == NAMESPACE_KEYWORD) { - declType = parseBlockNamespace(); - } else if (keywordToken == TYPE_KEYWORD) { declType = parseTypedef(); } @@ -187,16 +199,75 @@ public class JetParsing { } } + private boolean parseModifierList() { + // TODO + return true; + } + + /* + * namespace + * : "namespace" SimpleName{"."} "{" + * import* + * toplevelObject[| import]* + * "}" + * ; + */ + private JetNodeType parseNamespaceBlock() { + assert at(NAMESPACE); + advance(); // NAMESPACE + + if (at(LBRACE)) { + error("Expecting namespace name"); + } + else { + parseNamespaceName(); + } + + if (!at(LBRACE)) { + error("A namespace block in '{...}' expected"); + return NAMESPACE; + } + + advance(); // LBRACE + PsiBuilder.Marker namespaceBody = mark(); + + parseToplevelDeclarations(true); + + namespaceBody.done(NAMESPACE_BODY); + expect(RBRACE, "Expecting '}'"); + + return NAMESPACE; + } + + private JetNodeType parseClass() { + assert at(CLASS_KEYWORD); + advance(); // CLASS_KEYWORD + + expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET); + parseTypeParameterList(); + + cosumeIf(WRAPS_KEYWORD); + if (at(LPAR)) { + parsePrimaryConstructorParameterList(); + } + + if (at(COLON)) { + advance(); // COLON + parseDelegationSpecifierList(); + } + + if (at(LBRACE)) { + parseClassBody(); + } + + return CLASS; + } + private JetNodeType parseTypedef() { advance(); // TODO return TYPEDEF; } - private JetNodeType parseBlockNamespace() { - advance(); // TODO - return NAMESPACE; - } - private JetNodeType parseProperty() { advance(); // TODO return PROPERTY; @@ -212,40 +283,16 @@ public class JetParsing { return EXTENSION; } - private JetNodeType parseClass() { - assert at(CLASS_KEYWORD); - advance(); - - expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET); - parseTypeParameterList(); - - cosumeIf(WRAPS_KEYWORD); - if (at(LPAR)) { - parsePrimaryConstructorParameterList(); - } - - if (at(COLON)) { - advance(); - parseDelegationSpecifierList(); - } - - if (at(LBRACE)) { - parseClassBody(); - } - - return CLASS; - } - private void parseClassBody() { assert at(LBRACE); PsiBuilder.Marker body = mark(); - advance(); + advance(); // LBRACE while (!eof()) { if (at(RBRACE)) { break; } - advance(); + advance(); // TODO } expect(RBRACE, "Missing '}"); body.done(CLASS_BODY); @@ -256,7 +303,7 @@ public class JetParsing { while (true) { parseDelegationSpecifier(); if (!at(COMMA)) break; - advance(); + advance(); // COMMA } list.done(DELEGATION_SPECIFIER_LIST); @@ -269,7 +316,7 @@ public class JetParsing { PsiBuilder.Marker delegator = mark(); parseTypeRef(); // TODO: Error recovery!!! if (at(BY_KEYWORD)) { - advance(); + advance(); // BY_KEYWORD parseExpression(); delegator.done(DELEGATOR_BY); } @@ -287,12 +334,12 @@ public class JetParsing { private void parseValueParameterList() { assert at(LPAR); PsiBuilder.Marker list = mark(); - advance(); + advance(); // LPAR while (true) { if (at(IDENTIFIER) && lookahead(1) == EQ) { PsiBuilder.Marker named = mark(); - advance(); - advance(); + advance(); // IDENTIFIER + advance(); // EQ parseExpression(); named.done(NAMED_ARGUMENT); } @@ -318,12 +365,12 @@ public class JetParsing { private void parsePrimaryConstructorParameterList() { assert at(LPAR); PsiBuilder.Marker cons = mark(); - advance(); + advance(); // LPAR while (true) { parsePrimaryConstructorParameter(); if (!at(COMMA)) break; - advance(); + advance(); // COMMA } expect(RPAR, "')' expected"); @@ -336,7 +383,7 @@ public class JetParsing { parseModifierList(); if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) { - advance(); + advance(); // VAR_KEYWORD | VAL_KEYWORD } parseFunctionParameterRest(); @@ -348,7 +395,7 @@ public class JetParsing { expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET); if (at(COLON)) { - advance(); + advance(); // COLON parseTypeRef(); } else { @@ -356,26 +403,25 @@ public class JetParsing { } if (at(EQ)) { - advance(); + advance(); // EQ parseExpression(); } } private void parseExpression() { - advance(); - // TODO + advance(); // TODO } private void parseTypeParameterList() { PsiBuilder.Marker list = mark(); if (tt() == LT) { - advance(); + advance(); // LT while (true) { parseTypeParameter(); if (!at(COMMA)) break; - advance(); + advance(); // COMMA } expect(GT, "Missing '>'", TYPE_PARAMETER_GT_RECOVERY_SET); @@ -394,7 +440,7 @@ public class JetParsing { expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY); if (at(COLON)) { - advance(); + advance(); // COLON parseTypeRef(); } @@ -403,13 +449,7 @@ public class JetParsing { } private void parseTypeRef() { - advance(); - // tODO: - } - - private boolean parseModifierList() { - // TODO - return true; + advance(); // tODO: } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -431,7 +471,7 @@ public class JetParsing { private boolean expect(JetToken expectation, String message, TokenSet recoverySet) { if (at(expectation)) { - advance(); + advance(); // expectation return true; } @@ -454,7 +494,7 @@ public class JetParsing { private void errorAndAdvance(String message) { PsiBuilder.Marker err = mark(); - advance(); + advance(); // erroneous token err.error(message); } @@ -503,4 +543,9 @@ public class JetParsing { tmp.rollbackTo(); return tt; } + + private void cosumeIf(JetToken token) { + if (at(token)) advance(); // token + } + } diff --git a/idea/src/org/jetbrains/jet/lexer/JetTokens.java b/idea/src/org/jetbrains/jet/lexer/JetTokens.java index 0c357b56e77..b296b2c030c 100644 --- a/idea/src/org/jetbrains/jet/lexer/JetTokens.java +++ b/idea/src/org/jetbrains/jet/lexer/JetTokens.java @@ -12,6 +12,8 @@ import java.util.Arrays; import java.util.Set; public interface JetTokens { + JetToken EOF = new JetToken("EOF"); + JetToken BLOCK_COMMENT = new JetToken("BLOCK_COMMENT"); JetToken DOC_COMMENT = new JetToken("DOC_COMMENT"); JetToken EOL_COMMENT = new JetToken("EOL_COMMENT"); diff --git a/idea/testData/psi/NamespaceBlock.jet b/idea/testData/psi/NamespaceBlock.jet new file mode 100644 index 00000000000..10b13428cd4 --- /dev/null +++ b/idea/testData/psi/NamespaceBlock.jet @@ -0,0 +1,29 @@ +namespace foo.bar.goo + +import foo as bar + +namespace foof { + import foo.bar.*; + + class Foo {} + + namespace bar { + class Bar {} + + namespace ns { + class X + + class Y + } + } +} + + +class Bar {} + +namespace foo {} + +namespace bar { + import sdf + +} \ No newline at end of file diff --git a/idea/testData/psi/NamespaceBlock.txt b/idea/testData/psi/NamespaceBlock.txt new file mode 100644 index 00000000000..c9271bfa9fd --- /dev/null +++ b/idea/testData/psi/NamespaceBlock.txt @@ -0,0 +1,138 @@ +JetFile: NamespaceBlock.jet + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('goo') + PsiWhiteSpace('\n\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace('\n\n') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('foof') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(MAP)('.*') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n ') + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Foo') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Bar') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('ns') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('X') + PsiWhiteSpace('\n\n ') + TYPE_PARAMETER_LIST + + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Y') + PsiWhiteSpace('\n ') + TYPE_PARAMETER_LIST + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n\n') + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Bar') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + NAMESPACE_BODY + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('sdf') + PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/idea/testData/psi/NamespaceBlock_ERR.jet b/idea/testData/psi/NamespaceBlock_ERR.jet new file mode 100644 index 00000000000..fa0133ce0b4 --- /dev/null +++ b/idea/testData/psi/NamespaceBlock_ERR.jet @@ -0,0 +1,44 @@ +namespace foo.bar.goo + +import foo as +import foo. +import foo.bar. +import foo. as bar + +namespace foof { + import foo.bar.* as bar + import foo.bar.* as + + import foo as ; + import foo. ; + import foo.bar. ; + import foo. as bar ; + import foo.bar.* as bar ; + import foo.bar.* as ; + + namespace foo + + class Foo {} + namespace { + class Bar {} + + namespace ns { + class X + + class Y + } + } +} + +dsfgd + +class Bar {} + +namespace foo + +namespace {} + +namespace bar { + import sdf + +} \ No newline at end of file diff --git a/idea/testData/psi/NamespaceBlock_ERR.txt b/idea/testData/psi/NamespaceBlock_ERR.txt new file mode 100644 index 00000000000..21e92f342ca --- /dev/null +++ b/idea/testData/psi/NamespaceBlock_ERR.txt @@ -0,0 +1,271 @@ +JetFile: NamespaceBlock_ERR.jet + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('goo') + PsiWhiteSpace('\n\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace('\n') + PsiElement(IDENTIFIER)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(IDENTIFIER)('foo') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(DOT)('.') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + PsiWhiteSpace('\n') + PsiElement(IDENTIFIER)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(IDENTIFIER)('foo') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(DOT)('.') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace('\n\n') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('foof') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(MAP)('.*') + PsiWhiteSpace(' ') + PsiErrorElement:Cannot rename a all imported items to one identifier + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace('\n ') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(MAP)('.*') + PsiWhiteSpace(' ') + PsiErrorElement:Cannot rename a all imported items to one identifier + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace('\n\n ') + PsiElement(IDENTIFIER)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiErrorElement:Qualified name must be a '.'-separated identifier list + + PsiWhiteSpace(' ') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(DOT)('.') + PsiErrorElement:Qualified name must be a '.'-separated identifier list + + PsiWhiteSpace(' ') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiErrorElement:Qualified name must be a '.'-separated identifier list + + PsiWhiteSpace(' ') + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace(' ') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(MAP)('.*') + PsiWhiteSpace(' ') + PsiErrorElement:Cannot rename a all imported items to one identifier + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace(' ') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiElement(MAP)('.*') + PsiWhiteSpace(' ') + PsiErrorElement:Cannot rename a all imported items to one identifier + PsiElement(AS_KEYWORD)('as') + PsiWhiteSpace(' ') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n ') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('foo') + PsiErrorElement:A namespace block in '{...}' expected + + PsiWhiteSpace('\n\n ') + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Foo') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiErrorElement:Expecting namespace name + + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Bar') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('ns') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('X') + PsiWhiteSpace('\n\n ') + TYPE_PARAMETER_LIST + + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Y') + PsiWhiteSpace('\n ') + TYPE_PARAMETER_LIST + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + PsiErrorElement:Expecting namespace or top level declaration + PsiElement(IDENTIFIER)('dsfgd') + PsiWhiteSpace('\n\n') + CLASS + PsiElement(CLASS_KEYWORD)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Bar') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('foo') + PsiErrorElement:A namespace block in '{...}' expected + + PsiWhiteSpace('\n\n') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiErrorElement:Expecting namespace name + + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + NAMESPACE_BODY + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + NAMESPACE + PsiElement(NAMESPACE_KEYWORD)('namespace') + PsiWhiteSpace(' ') + NAMESPACE_NAME + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + NAMESPACE_BODY + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('sdf') + PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java b/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java index 9be65f01fd5..afe7c3fd8b3 100644 --- a/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java +++ b/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java @@ -32,4 +32,6 @@ public class JetParsingTest extends ParsingTestCase { public void testImports() throws Exception {doTest(true);} public void testImports_ERR() throws Exception {doTest(true);} public void testImportSoftKW() throws Exception {doTest(true);} + public void testNamespaceBlock_ERR() throws Exception {doTest(true);} + public void testNamespaceBlock() throws Exception {doTest(true);} }