diff --git a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java index 17e41d2ea35..3cac49927bc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java @@ -286,10 +286,18 @@ public class JetParsing extends AbstractJetParsing { return; } - PsiBuilder.Marker qualifiedName = mark(); + if (!at(IDENTIFIER)) { + PsiBuilder.Marker error = mark(); + skipUntil(TokenSet.create(EOL_OR_SEMICOLON)); + error.error("Expecting qualified name"); + importDirective.done(IMPORT_DIRECTIVE); + consumeIf(SEMICOLON); + return; + } + PsiBuilder.Marker qualifiedName = mark(); PsiBuilder.Marker reference = mark(); - expect(IDENTIFIER, "Expecting qualified name"); + advance(); // IDENTIFIER reference.done(REFERENCE_EXPRESSION); while (at(DOT) && lookahead(1) != MUL) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetImportDirective.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetImportDirective.java index a32c6073ee1..5340cb52c05 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetImportDirective.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetImportDirective.java @@ -100,8 +100,6 @@ public class JetImportDirective extends JetElementImplStub { - public static final int STUB_VERSION = 47; + public static final int STUB_VERSION = 48; private static final String NAME = "kotlin.FILE"; diff --git a/compiler/testData/diagnostics/tests/imports/MalformedImports.kt b/compiler/testData/diagnostics/tests/imports/MalformedImports.kt new file mode 100644 index 00000000000..b03653e717d --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/MalformedImports.kt @@ -0,0 +1,9 @@ +package test + +import some. +import .some +import .kotlin +import kotlin. +import +import . +import * \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/MalformedImports.txt b/compiler/testData/diagnostics/tests/imports/MalformedImports.txt new file mode 100644 index 00000000000..da8f5c10690 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/MalformedImports.txt @@ -0,0 +1,4 @@ +package + +package test { +} diff --git a/compiler/testData/psi/Imports_ERR.kt b/compiler/testData/psi/Imports_ERR.kt index 91ddaef2bed..a4d6fe37a97 100644 --- a/compiler/testData/psi/Imports_ERR.kt +++ b/compiler/testData/psi/Imports_ERR.kt @@ -28,6 +28,14 @@ import foo.bar.* as import foo.bar. ; import foo.bar.* as bar ; import foo.bar.* as ; +import * +import - +import ^_^ +import . +import ---; import +++ +import ..{... +import ..}... +import foo fun foo() { diff --git a/compiler/testData/psi/Imports_ERR.txt b/compiler/testData/psi/Imports_ERR.txt index 1f769ea2551..79c90aa1274 100644 --- a/compiler/testData/psi/Imports_ERR.txt +++ b/compiler/testData/psi/Imports_ERR.txt @@ -317,6 +317,71 @@ JetFile: Imports_ERR.kt PsiElement(as)('as') PsiWhiteSpace(' ') PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(MUL)('*') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(MINUS)('-') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(BAD_CHARACTER)('^') + PsiElement(IDENTIFIER)('_') + PsiElement(BAD_CHARACTER)('^') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(DOT)('.') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(MINUSMINUS)('--') + PsiElement(MINUS)('-') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace(' ') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(PLUSPLUS)('++') + PsiElement(PLUS)('+') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(RANGE)('..') + PsiElement(LBRACE)('{') + PsiElement(RANGE)('..') + PsiElement(DOT)('.') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + PsiErrorElement:Expecting qualified name + PsiElement(RANGE)('..') + PsiElement(RBRACE)('}') + PsiElement(RANGE)('..') + PsiElement(DOT)('.') + PsiWhiteSpace('\n') + IMPORT_DIRECTIVE + PsiElement(import)('import') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') PsiWhiteSpace('\n\n') FUN PsiElement(fun)('fun') diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index a66527e6173..74f76731250 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -6132,6 +6132,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("MalformedImports.kt") + public void testMalformedImports() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/MalformedImports.kt"); + doTest(fileName); + } + @TestMetadata("PackageLocalClassNotImported.kt") public void testPackageLocalClassNotImported() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/PackageLocalClassNotImported.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/psi/JetPsiUtilTest.java b/compiler/tests/org/jetbrains/kotlin/psi/JetPsiUtilTest.java index bd0024a71ed..499700a721a 100644 --- a/compiler/tests/org/jetbrains/kotlin/psi/JetPsiUtilTest.java +++ b/compiler/tests/org/jetbrains/kotlin/psi/JetPsiUtilTest.java @@ -54,9 +54,9 @@ public class JetPsiUtilTest extends JetLiteFixture { public void testConvertToImportPath() { Assert.assertEquals(null, getImportPathFromParsed("import ")); - Assert.assertEquals(null, getImportPathFromParsed("import some.")); + Assert.assertEquals(new ImportPath(new FqName("some"), false), getImportPathFromParsed("import some.")); Assert.assertEquals(null, getImportPathFromParsed("import *")); - Assert.assertEquals(null, getImportPathFromParsed("import some.test.* as SomeTest")); + Assert.assertEquals(new ImportPath(new FqName("some.test"), true), getImportPathFromParsed("import some.test.* as SomeTest")); Assert.assertEquals(new ImportPath(new FqName("some"), false), getImportPathFromParsed("import some?.Test")); Assert.assertEquals(new ImportPath(new FqName("some"), false), getImportPathFromParsed("import some"));