mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java] fixes parsing of imports in module-info.java files (IDEA-169208)
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -27,6 +28,8 @@ import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.*;
|
||||
|
||||
@@ -42,16 +45,16 @@ public class FileParser {
|
||||
}
|
||||
|
||||
public void parse(@NotNull PsiBuilder builder) {
|
||||
parseFile(builder, IMPORT_LIST_STOPPER_SET, JavaErrorMessages.INSTANCE, "expected.class.or.interface");
|
||||
parseFile(builder, FileParser::stopImportListParsing, JavaErrorMessages.INSTANCE, "expected.class.or.interface");
|
||||
}
|
||||
|
||||
public void parseFile(@NotNull PsiBuilder builder,
|
||||
@NotNull TokenSet importListStoppers,
|
||||
@NotNull Predicate<PsiBuilder> importListStopper,
|
||||
@NotNull AbstractBundle bundle,
|
||||
@NotNull String errorMessageKey) {
|
||||
parsePackageStatement(builder);
|
||||
|
||||
Pair<PsiBuilder.Marker, Boolean> impListInfo = parseImportList(builder, importListStoppers); // (importList, isEmpty)
|
||||
Pair<PsiBuilder.Marker, Boolean> impListInfo = parseImportList(builder, importListStopper); // (importList, isEmpty)
|
||||
Boolean firstDeclarationOk = null;
|
||||
PsiBuilder.Marker firstDeclaration = null;
|
||||
|
||||
@@ -101,6 +104,14 @@ public class FileParser {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean stopImportListParsing(PsiBuilder b) {
|
||||
IElementType type = b.getTokenType();
|
||||
String text = b.getTokenText();
|
||||
if (IMPORT_LIST_STOPPER_SET.contains(type)) return true;
|
||||
if (type == JavaTokenType.IDENTIFIER && (PsiKeyword.OPEN.equals(text) || PsiKeyword.MODULE.equals(text))) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected PsiBuilder.Marker parseInitial(PsiBuilder builder) {
|
||||
return myParser.getDeclarationParser().parse(builder, DeclarationParser.Context.FILE);
|
||||
@@ -131,7 +142,7 @@ public class FileParser {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Pair<PsiBuilder.Marker, Boolean> parseImportList(PsiBuilder builder, TokenSet stoppers) {
|
||||
private Pair<PsiBuilder.Marker, Boolean> parseImportList(PsiBuilder builder, Predicate<PsiBuilder> stopper) {
|
||||
PsiBuilder.Marker list = builder.mark();
|
||||
|
||||
IElementType tokenType = builder.getTokenType();
|
||||
@@ -139,11 +150,10 @@ public class FileParser {
|
||||
if (!isEmpty) {
|
||||
PsiBuilder.Marker invalidElements = null;
|
||||
while (!builder.eof()) {
|
||||
tokenType = builder.getTokenType();
|
||||
if (stoppers.contains(tokenType)) {
|
||||
if (stopper.test(builder)) {
|
||||
break;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.SEMICOLON) {
|
||||
else if (builder.getTokenType() == JavaTokenType.SEMICOLON) {
|
||||
builder.advanceLexer();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
PsiJavaFile:Imports.java
|
||||
PsiImportList
|
||||
PsiImportStatement
|
||||
PsiKeyword:import('import')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaCodeReferenceElement:java.lang.Deprecated
|
||||
PsiJavaCodeReferenceElement:java.lang
|
||||
PsiJavaCodeReferenceElement:java
|
||||
PsiIdentifier:java('java')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiIdentifier:lang('lang')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiIdentifier:Deprecated('Deprecated')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiJavaModule:M
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiKeyword:module('module')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaModuleReference
|
||||
PsiIdentifier:M('M')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -28,6 +28,7 @@ public class ModuleParserTest extends JavaParsingTestCase {
|
||||
public void testSimple2() { doParserTest("/* comment */\nmodule X { }"); }
|
||||
|
||||
public void testPackaged() { doParserTest("package pkg;\nmodule M { }"); }
|
||||
public void testImports() { doParserTest("import java.lang.Deprecated;\nmodule M { }"); }
|
||||
|
||||
public void testModifierList0() { doParserTest("open module M { }"); }
|
||||
public void testModifierList1() { doParserTest("@Deprecated module M { }"); }
|
||||
|
||||
Reference in New Issue
Block a user