Skip to content

Commit 9853faa

Browse files
andre15silvawoutersmeenk
authored andcommitted
fix: Fix compliance level support for old code (INRIA#4068)
1 parent 2245454 commit 9853faa

File tree

3 files changed

+59
-15
lines changed

3 files changed

+59
-15
lines changed

src/main/java/spoon/support/reflect/reference/CtReferenceImpl.java

+32-9
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@
3131
public abstract class CtReferenceImpl extends CtElementImpl implements CtReference, Serializable {
3232

3333
private static final long serialVersionUID = 1L;
34-
private static Collection<String> keywords = fillWithKeywords();
34+
35+
// See isKeyword for more information on keywords
36+
private static final Collection<String> baseKeywords = fillWithBaseKeywords();
37+
private static final Collection<String> java2Keywords = Stream.of("strictfp").collect(Collectors.toCollection(HashSet::new));
38+
private static final Collection<String> java4Keywords = Stream.of("assert").collect(Collectors.toCollection(HashSet::new));
39+
private static final Collection<String> java5Keywords = Stream.of("enum").collect(Collectors.toCollection(HashSet::new));
40+
private static final Collection<String> java9Keywords = Stream.of("_").collect(Collectors.toCollection(HashSet::new));
3541

3642
@MetamodelPropertyField(role = NAME)
3743
protected String simplename = "";
@@ -109,9 +115,25 @@ private void checkIdentiferForJLSCorrectness(String simplename) {
109115
}
110116
}
111117
}
118+
119+
/**
120+
* Keywords list and history selected according to:
121+
* https://docs.oracle.com/en/java/javase/15/docs/specs/sealed-classes-jls.html#jls-3.9
122+
* https://en.wikipedia.org/wiki/List_of_Java_keywords (contains history of revisions)
123+
* and https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html (history up to java 8)
124+
*
125+
* @param simplename
126+
* @return true if simplename is a keyword in the current setting (compliance level), false if not
127+
*/
112128
private boolean isKeyword(String simplename) {
113-
return keywords.contains(simplename);
129+
int complianceLevel = getFactory().getEnvironment().getComplianceLevel();
130+
return (baseKeywords.contains(simplename)
131+
|| (complianceLevel >= 2 && java2Keywords.contains(simplename))
132+
|| (complianceLevel >= 4 && java4Keywords.contains(simplename))
133+
|| (complianceLevel >= 5 && java5Keywords.contains(simplename))
134+
|| (complianceLevel >= 9 && java9Keywords.contains(simplename)));
114135
}
136+
115137
private boolean checkAllParts(String[] simplenameParts) {
116138
for (String simpleName:simplenameParts) {
117139
//because arrays use e.g. int[] and @Number is used for instances of an object e.g. foo@1
@@ -135,13 +157,14 @@ private boolean checkIdentifierChars(String simplename) {
135157
);
136158
}
137159

138-
private static Collection<String> fillWithKeywords() {
139-
//removed types because needed as ref: "int","short", "char", "void", "byte","float", "true","false","boolean","double","long","class", "null"
140-
return Stream.of("abstract", "continue", "for", "new", "switch", "assert", "default", "if", "package", "synchronized", "do", "goto", "private",
141-
"this", "break", "implements", "protected", "throw", "else", "import", "public", "throws", "case", "enum", "instanceof", "return",
142-
"transient", "catch", "extends", "try", "final", "interface", "static", "finally", "strictfp", "volatile",
143-
"const", "native", "super", "while", "_")
144-
.collect(Collectors.toCollection(HashSet::new));
160+
private static Collection<String> fillWithBaseKeywords() {
161+
// removed types because needed as ref: "int","short", "char", "void", "byte","float", "true","false","boolean","double","long","class", "null"
162+
// in the method isKeyword, more keywords are added to the checks based on the compliance level
163+
return Stream.of("abstract", "continue", "for", "new", "switch", "default", "if", "package", "synchronized", "do", "goto", "private",
164+
"this", "break", "implements", "protected", "throw", "else", "import", "public", "throws", "case", "instanceof", "return",
165+
"transient", "catch", "extends", "try", "final", "interface", "static", "finally", "volatile",
166+
"const", "native", "super", "while")
167+
.collect(Collectors.toCollection(HashSet::new));
145168
}
146169

147170
/**

src/test/java/spoon/test/ctType/CtTypeTest.java

+19-6
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,12 @@
3737
import spoon.reflect.visitor.filter.TypeFilter;
3838
import spoon.test.ctType.testclasses.X;
3939

40-
import java.util.Arrays;
41-
import java.util.HashMap;
42-
import java.util.List;
43-
import java.util.Map;
40+
import java.util.*;
4441
import java.util.regex.Matcher;
4542
import java.util.regex.Pattern;
4643
import java.util.stream.Collectors;
4744

48-
import static org.hamcrest.CoreMatchers.anyOf;
49-
import static org.hamcrest.CoreMatchers.equalTo;
45+
import static org.hamcrest.CoreMatchers.*;
5046
import static org.hamcrest.MatcherAssert.assertThat;
5147
import static org.junit.jupiter.api.Assertions.assertEquals;
5248
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -296,4 +292,21 @@ public void testGetAllExecutablesOnTypeImplementingNestedInterface() {
296292
equalTo(expectedNumExecutablesPostJDK8))
297293
);
298294
}
295+
296+
/**
297+
* This test captures keyword constraint in CtReferenceImpl based on the compliance level, since the keyword
298+
* "enum" was only introduced in Java 5
299+
*/
300+
@Test
301+
public void testEnumPackage() {
302+
final Launcher launcher = new Launcher();
303+
launcher.addInputResource("./src/test/resources/keywordCompliance/enum/Foo.java");
304+
launcher.getEnvironment().setComplianceLevel(4);
305+
launcher.run();
306+
307+
Collection<CtType<?>> types = launcher.getModel().getAllTypes();
308+
assertThat(types.size(), is(1));
309+
assertThat(types.stream().findFirst().get(), notNullValue());
310+
assertThat(types.stream().findFirst().get().getQualifiedName(), is("keywordCompliance.enum.Foo"));
311+
}
299312
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package keywordCompliance.enum;
2+
3+
public class Foo {
4+
5+
public Foo() {
6+
7+
}
8+
}

0 commit comments

Comments
 (0)