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 05e1fd9ab0d..82b634ee7cf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -54,6 +54,7 @@ public class JetParsing extends AbstractJetParsing { private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, LPAR, COLON, LBRACE, GT); private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR); private static final TokenSet NAMESPACE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON); + private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON); /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, FUN_KEYWORD, LPAR, CAPITALIZED_THIS_KEYWORD, HASH); private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS); @@ -220,11 +221,12 @@ public class JetParsing extends AbstractJetParsing { PsiBuilder.Marker reference = mark(); expect(IDENTIFIER, "Expecting qualified name"); reference.done(REFERENCE_EXPRESSION); + while (at(DOT) && lookahead(1) != MUL) { advance(); // DOT reference = mark(); - if (expect(IDENTIFIER, "Qualified name must be a '.'-separated identifier list", TokenSet.create(AS_KEYWORD, DOT, SEMICOLON))) { + if (expect(IDENTIFIER, "Qualified name must be a '.'-separated identifier list", IMPORT_RECOVERY_SET)) { reference.done(REFERENCE_EXPRESSION); } else { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 2c1303c0586..59cb8fca887 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -174,6 +174,10 @@ public class JetPsiUtil { return null; } + if (PsiTreeUtil.hasErrorElements(importedReference)) { + return null; + } + final String text = importedReference.getText(); return new ImportPath(text.replaceAll(" ", "") + (importDirective.isAllUnder() ? ".*" : "")); } diff --git a/compiler/testData/psi/recovery/ImportRecovery.jet b/compiler/testData/psi/recovery/ImportRecovery.jet new file mode 100644 index 00000000000..46ff52a1d56 --- /dev/null +++ b/compiler/testData/psi/recovery/ImportRecovery.jet @@ -0,0 +1,6 @@ +import some.test. + +// Some +// SomeOther + +object StyleSheetOrigin {} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/ImportRecovery.txt b/compiler/testData/psi/recovery/ImportRecovery.txt new file mode 100644 index 00000000000..6e66dd7f049 --- /dev/null +++ b/compiler/testData/psi/recovery/ImportRecovery.txt @@ -0,0 +1,30 @@ +JetFile: ImportRecovery.jet + NAMESPACE_HEADER + + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + DOT_QUALIFIED_EXPRESSION + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('some') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('test') + PsiElement(DOT)('.') + PsiErrorElement:Qualified name must be a '.'-separated identifier list + + PsiWhiteSpace('\n\n') + PsiComment(EOL_COMMENT)('// Some') + PsiWhiteSpace('\n') + PsiComment(EOL_COMMENT)('// SomeOther') + PsiWhiteSpace('\n\n') + OBJECT_DECLARATION + PsiElement(object)('object') + PsiWhiteSpace(' ') + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('StyleSheetOrigin') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/PackageRecovery.jet b/compiler/testData/psi/recovery/PackageRecovery.jet new file mode 100644 index 00000000000..79b7e4410c9 --- /dev/null +++ b/compiler/testData/psi/recovery/PackageRecovery.jet @@ -0,0 +1,3 @@ +package some. // Hello + +val a = 12 \ No newline at end of file diff --git a/compiler/testData/psi/recovery/PackageRecovery.txt b/compiler/testData/psi/recovery/PackageRecovery.txt new file mode 100644 index 00000000000..501092ae6bc --- /dev/null +++ b/compiler/testData/psi/recovery/PackageRecovery.txt @@ -0,0 +1,21 @@ +JetFile: PackageRecovery.jet + NAMESPACE_HEADER + PsiElement(package)('package') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('some') + PsiElement(DOT)('.') + PsiErrorElement:Package name must be a '.'-separated identifier list placed on a single line + + PsiWhiteSpace(' ') + PsiComment(EOL_COMMENT)('// Hello') + PsiWhiteSpace('\n\n') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('a') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('12') \ No newline at end of file