Fix import resolution for some cases of malformed imports ("import some.")

Fix parsing import directives in case of non-identifier after "import"
Add diagnostics test for malformed imports
This commit is contained in:
Pavel V. Talanov
2015-06-16 20:46:25 +03:00
parent 37bcd455b5
commit 997a6f1381
9 changed files with 112 additions and 9 deletions
@@ -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) {
@@ -100,8 +100,6 @@ public class JetImportDirective extends JetElementImplStub<KotlinImportDirective
@Nullable
@IfNotParsed
public ImportPath getImportPath() {
if (!isValidImport()) return null;
FqName importFqn = fqNameFromExpression(getImportedReference());
if (importFqn == null) {
return null;
@@ -134,8 +132,13 @@ public class JetImportDirective extends JetElementImplStub<KotlinImportDirective
JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression) expression;
FqName parentFqn = fqNameFromExpression(dotQualifiedExpression.getReceiverExpression());
Name child = nameFromExpression(dotQualifiedExpression.getSelectorExpression());
return parentFqn != null && child != null ? parentFqn.child(child) : null;
if (child == null) {
return parentFqn;
}
if (parentFqn != null) {
return parentFqn.child(child);
}
return null;
}
else if (expression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinFileStubImpl;
import java.io.IOException;
public class JetFileElementType extends IStubFileElementType<KotlinFileStub> {
public static final int STUB_VERSION = 47;
public static final int STUB_VERSION = 48;
private static final String NAME = "kotlin.FILE";
@@ -0,0 +1,9 @@
package test
import <!UNRESOLVED_REFERENCE!>some<!>.<!SYNTAX!><!>
import <!SYNTAX!>.some<!>
import <!SYNTAX!>.kotlin<!>
import kotlin.<!SYNTAX!><!>
import<!SYNTAX!><!>
import <!SYNTAX!>.<!>
import <!SYNTAX!>*<!>
@@ -0,0 +1,4 @@
package
package test {
}
+8
View File
@@ -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() {
+65
View File
@@ -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')
@@ -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");
@@ -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"));