mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
[java-rd] IDEA-333104 fix cases when highlighting get null in parents
- added new test for consistency GitOrigin-RevId: d3aa13912b43b6717d675d5ea5a9abce7e38dad6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b851673c40
commit
8be2252d3f
@@ -10,6 +10,8 @@ import com.intellij.psi.tree.TokenSet;
|
||||
* The BasicElementTypes interface represents a collection of basic element types used in frontback java modules.
|
||||
* {@link TokenSet} is used for set, which contains `basic` types, which are not used in hierarchy.
|
||||
* for other sets {@link ParentAwareTokenSet} is used.
|
||||
* This set of sets must be consistent with {@link com.intellij.psi.impl.source.tree.ElementType}.
|
||||
* It checks with {@link com.intellij.java.parser.FrontBackElementTypeTest#testJavaTokenSet()}
|
||||
*
|
||||
* @see ParentAwareTokenSet
|
||||
*/
|
||||
|
||||
@@ -7,15 +7,17 @@ import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.util.text.Strings;
|
||||
import com.intellij.psi.impl.source.AbstractBasicJavaDocElementTypeFactory;
|
||||
import com.intellij.psi.impl.source.AbstractBasicJavaElementTypeFactory;
|
||||
import com.intellij.psi.impl.source.BasicJavaDocElementType;
|
||||
import com.intellij.psi.impl.source.BasicJavaElementType;
|
||||
import com.intellij.psi.impl.source.*;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaDocElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaDocElementTypeFactory;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementTypeFactory;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.ParentAwareTokenSet;
|
||||
import com.intellij.psi.tree.ParentProviderElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -23,13 +25,163 @@ import java.lang.reflect.Field;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FrontBackElementTypeTest extends AbstractBasicJavaParsingTestCase {
|
||||
|
||||
public static final String BASIC = "BASIC_";
|
||||
|
||||
public FrontBackElementTypeTest() {
|
||||
super("dummy", new JavaParsingTestConfigurator());
|
||||
}
|
||||
|
||||
public void testJavaTokenSet() throws IOException, IllegalAccessException {
|
||||
checkTokenSetContains(ElementType.class, BasicJavaElementType.class);
|
||||
checkTokenSet(ElementType.class, BasicElementTypes.class);
|
||||
}
|
||||
|
||||
public void testJavaDocTokenSet() throws IllegalAccessException {
|
||||
checkTokenSet(JavaDocElementType.class, BasicJavaDocElementType.class);
|
||||
}
|
||||
|
||||
private static void checkTokenSet(Class<?> mainTokenSetClass, Class<?> basicTokenSetClass)
|
||||
throws IllegalAccessException {
|
||||
Map<String, TokenSet> mainTokenSets = getFieldsByName(mainTokenSetClass, TokenSet.class);
|
||||
Map<String, ParentAwareTokenSet> mainParentTokenSets = getFieldsByName(mainTokenSetClass, ParentAwareTokenSet.class);
|
||||
|
||||
Assert.assertEquals("ParentAwareTokenSet should not be used in " + mainTokenSetClass.getName() + ", use TokenSet",
|
||||
mainParentTokenSets.size(), 0);
|
||||
|
||||
Map<String, TokenSet> basicTokenSets = getFieldsByName(basicTokenSetClass, TokenSet.class);
|
||||
Map<String, ParentAwareTokenSet> basicParentTokenSets = getFieldsByName(basicTokenSetClass, ParentAwareTokenSet.class);
|
||||
|
||||
IElementType[] allLoadedTypes = IElementType.enumerate(e -> true);
|
||||
for (Map.Entry<String, TokenSet> basicTokenSet : basicTokenSets.entrySet()) {
|
||||
ParentAwareTokenSet parentAwareTokenSet = ParentAwareTokenSet.create(basicTokenSet.getValue());
|
||||
Set<IElementType> parentContained = getContained(parentAwareTokenSet, allLoadedTypes);
|
||||
Set<IElementType> contained = getContained(basicTokenSet.getValue(), allLoadedTypes);
|
||||
Assertions.assertThat(parentContained)
|
||||
.withFailMessage("TokenSet " +
|
||||
basicTokenSet.getKey() +
|
||||
" probably contains ParentProviderElementType and should be converted to ParentAwareTokenSet")
|
||||
.containsExactlyInAnyOrderElementsOf(contained);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, TokenSet> basicTokenSetsEntry : basicTokenSets.entrySet()) {
|
||||
String basicTokenSetName = basicTokenSetsEntry.getKey();
|
||||
if (!basicTokenSetName.startsWith(BASIC)) {
|
||||
Assertions.fail("Name of TokenSet " + basicTokenSetName + " doesn't start with " + BASIC + " in " + basicTokenSetClass.getName());
|
||||
}
|
||||
String expectedBasicTokenSetName = basicTokenSetName.substring(BASIC.length());
|
||||
TokenSet tokenSet = mainTokenSets.get(expectedBasicTokenSetName);
|
||||
if (tokenSet == null) {
|
||||
Assertions.fail(mainTokenSetClass.getName() + " doesn't contain TokenSet with name " + expectedBasicTokenSetName + ". " +
|
||||
basicTokenSetClass.getName() + "contains " + basicTokenSetName);
|
||||
}
|
||||
|
||||
if (tokenSet != basicTokenSetsEntry.getValue()) {
|
||||
Assertions.fail("TokenSets with names :" + basicTokenSetName + " and " + expectedBasicTokenSetName + " from " +
|
||||
mainTokenSetClass.getName() + " and " + basicTokenSetClass.getName() + " are different");
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, ParentAwareTokenSet> basicTokenSetsEntry : basicParentTokenSets.entrySet()) {
|
||||
String basicTokenSetName = basicTokenSetsEntry.getKey();
|
||||
if (!basicTokenSetName.startsWith(BASIC)) {
|
||||
Assertions.fail(
|
||||
"Name of ParentAwareTokenSet " + basicTokenSetName + " doesn't start with " + BASIC + " in " + basicTokenSetClass.getName());
|
||||
}
|
||||
String expectedBasicTokenSetName = basicTokenSetName.substring(BASIC.length());
|
||||
TokenSet tokenSet = mainTokenSets.get(expectedBasicTokenSetName);
|
||||
if (tokenSet == null) {
|
||||
Assertions.fail(mainTokenSetClass.getName() + " doesn't contain TokenSet with name " + expectedBasicTokenSetName + ". " +
|
||||
basicTokenSetClass.getName() + "contains " + basicTokenSetName);
|
||||
}
|
||||
|
||||
Set<IElementType> parentContained = getContained(basicTokenSetsEntry.getValue(), allLoadedTypes);
|
||||
Set<IElementType> contained = getContained(tokenSet, allLoadedTypes);
|
||||
if (!parentContained.containsAll(contained)) {
|
||||
contained.removeAll(parentContained);
|
||||
Assertions.fail("ParentAwareTokenSet " +
|
||||
basicTokenSetName +
|
||||
" doesn't contains all IElementType, which TokenSet " +
|
||||
expectedBasicTokenSetName +
|
||||
" contains. " +
|
||||
"see " +
|
||||
basicTokenSetClass.getName() +
|
||||
" and " +
|
||||
mainTokenSetClass.getName() +
|
||||
". Difference: " +
|
||||
contained.stream().map(t -> t.getDebugName()).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
Set<IElementType> additionalSet = new HashSet<>();
|
||||
for (IElementType elementType : contained) {
|
||||
if (elementType instanceof ParentProviderElementType parentProviderElementType) {
|
||||
additionalSet.addAll(parentProviderElementType.getParents());
|
||||
}
|
||||
}
|
||||
contained.addAll(additionalSet);
|
||||
if (!contained.containsAll(parentContained)) {
|
||||
parentContained.removeAll(contained);
|
||||
Assertions.fail("TokenSet " +
|
||||
expectedBasicTokenSetName +
|
||||
" doesn't contains all IElementType, which ParentAwareTokenSet " +
|
||||
basicTokenSetName +
|
||||
" contains. " +
|
||||
"see " +
|
||||
basicTokenSetClass.getName() +
|
||||
" and " +
|
||||
mainTokenSetClass.getName() +
|
||||
". Difference: " +
|
||||
parentContained.stream().map(t -> t.getDebugName()).collect(Collectors.joining(", ")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<IElementType> getContained(ParentAwareTokenSet set, IElementType[] types) {
|
||||
Set<IElementType> result = new HashSet<>();
|
||||
for (IElementType type : types) {
|
||||
if (set.contains(type)) {
|
||||
result.add(type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Set<IElementType> getContained(TokenSet set, IElementType[] types) {
|
||||
Set<IElementType> result = new HashSet<>();
|
||||
for (IElementType type : types) {
|
||||
if (set.contains(type)) {
|
||||
result.add(type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <T> Map<String, T> getFieldsByName(Class<?> aClass, Class<T> targetType) throws IllegalAccessException {
|
||||
Field[] fields = aClass.getDeclaredFields();
|
||||
HashMap<String, T> result = new HashMap<>();
|
||||
for (Field field : fields) {
|
||||
field.setAccessible(true);
|
||||
Class<?> fieldType = field.getType();
|
||||
if (fieldType == targetType) {
|
||||
String name = field.getName();
|
||||
Object object = field.get(null);
|
||||
result.put(name, (T)object);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void checkTokenSetContains(Class<?> mainTokenSet, Class<?> elements) throws IOException {
|
||||
String pathToModule = FileUtil.toSystemDependentName("/../../java-psi-impl/src/");
|
||||
String fullPath = PathManagerEx.getTestDataPath() + pathToModule;
|
||||
String pathToClass = mainTokenSet.getName();
|
||||
checkContains(fullPath + FileUtil.toSystemDependentName(pathToClass.replace(".", "/") + ".java"), elements.getSimpleName());
|
||||
}
|
||||
|
||||
public void testJavaElementType() {
|
||||
AbstractBasicJavaElementTypeFactory.JavaElementTypeContainer javaElementTypeContainer = JavaElementTypeFactory.INSTANCE.getContainer();
|
||||
check(javaElementTypeContainer);
|
||||
@@ -60,7 +212,6 @@ public class FrontBackElementTypeTest extends AbstractBasicJavaParsingTestCase {
|
||||
Assert.assertNotEquals(parserPath, backJavaElementTypePath, "Lexer and element types must be placed in different folders");
|
||||
|
||||
//not used in parser and lexer
|
||||
System.out.println();
|
||||
String pathToModule = FileUtil.toSystemDependentName("/../../java-frontback-psi-impl/src/");
|
||||
String fullPath = PathManagerEx.getTestDataPath() + pathToModule;
|
||||
checkContains(fullPath + FileUtil.toSystemDependentName(lexerPath.replace(".", "/")), BasicJavaElementType.class.getSimpleName());
|
||||
|
||||
Reference in New Issue
Block a user