diff --git a/src/main/java/spoon/support/reflect/reference/CtReferenceImpl.java b/src/main/java/spoon/support/reflect/reference/CtReferenceImpl.java index 5145019af40..058fbffadf4 100644 --- a/src/main/java/spoon/support/reflect/reference/CtReferenceImpl.java +++ b/src/main/java/spoon/support/reflect/reference/CtReferenceImpl.java @@ -17,14 +17,18 @@ import java.io.Serializable; import java.lang.reflect.AnnotatedElement; +import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Objects; - +import java.util.stream.Collectors; +import java.util.stream.Stream; import static spoon.reflect.path.CtRole.NAME; public abstract class CtReferenceImpl extends CtElementImpl implements CtReference, Serializable { private static final long serialVersionUID = 1L; + private static Collection keywords = fillWithKeywords(); @MetamodelPropertyField(role = NAME) protected String simplename = ""; @@ -42,6 +46,12 @@ public String getSimpleName() { @Override public T setSimpleName(String simplename) { Factory factory = getFactory(); + if (simplename.length() == 0) { + throw new IllegalArgumentException("empty identifier found. See JLS for correct identifier"); + } + if (checkIdentifierChars(simplename) || isKeyword(simplename)) { + throw new IllegalArgumentException("Not allowed javaletter or keyword in identifier found. See JLS for correct identifier"); + } if (factory == null) { this.simplename = simplename; return (T) this; @@ -54,6 +64,7 @@ public T setSimpleName(String simplename) { return (T) this; } + @UnsettableProperty @Override public E setComments(List comments) { @@ -81,4 +92,18 @@ public boolean equals(Object o) { } return false; } + private boolean isKeyword(String simplename) { + return keywords.contains(simplename); + } + + private boolean checkIdentifierChars(String simplename) { + return (!Character.isJavaIdentifierStart(simplename.charAt(0))) || simplename.chars().anyMatch(letter -> !Character.isJavaIdentifierPart(letter)); + } + private static Collection fillWithKeywords() { + return Stream.of("abstract", "continue", "for", "new", "switch", "assert", "default", "if", "package", "synchronized", "boolean", "do", "goto", "private", + "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", + "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", + "const", "float", "native", "super", "while", "_", "true", "false", "null") + .collect(Collectors.toCollection(HashSet::new)); + } } diff --git a/src/test/java/spoon/generating/CorrectIdentifierTest.java b/src/test/java/spoon/generating/CorrectIdentifierTest.java new file mode 100644 index 00000000000..6eab24cca24 --- /dev/null +++ b/src/test/java/spoon/generating/CorrectIdentifierTest.java @@ -0,0 +1,49 @@ +package spoon.generating; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.Test; +import spoon.Launcher; +import spoon.reflect.reference.CtLocalVariableReference; +/** + * for correct identifier see JLS chapter 3.8 and for keywords 3.9 + */ +public class CorrectIdentifierTest { + + @Test + public void wrongIdentifer() { + CtLocalVariableReference localVariableRef = new Launcher().getFactory().createLocalVariableReference(); + assertThrows(IllegalArgumentException.class, () -> localVariableRef.setSimpleName("tacos.EatIt()")); + } + @Test + public void wrongIdentifer2() { + CtLocalVariableReference localVariableRef = new Launcher().getFactory().createLocalVariableReference(); + assertThrows(IllegalArgumentException.class, () -> localVariableRef.setSimpleName("1tacos")); + } + @Test + public void keyWord() { + CtLocalVariableReference localVariableRef = new Launcher().getFactory().createLocalVariableReference(); + assertThrows(IllegalArgumentException.class, () -> localVariableRef.setSimpleName("class")); + } + @Test + public void keyWord2() { + CtLocalVariableReference localVariableRef = new Launcher().getFactory().createLocalVariableReference(); + assertThrows(IllegalArgumentException.class, () -> localVariableRef.setSimpleName("null")); + } + @Test + public void keyWord3() { + CtLocalVariableReference localVariableRef = new Launcher().getFactory().createLocalVariableReference(); + assertThrows(IllegalArgumentException.class, () -> localVariableRef.setSimpleName("true")); + } + @Test + public void correctIdentifer() { + CtLocalVariableReference localVariableRef = new Launcher().getFactory().createLocalVariableReference(); + assertDoesNotThrow(() -> localVariableRef.setSimpleName("EatIt")); + + } + @Test + public void correctIdentifer2() { + CtLocalVariableReference localVariableRef = new Launcher().getFactory().createLocalVariableReference(); + assertDoesNotThrow(() -> localVariableRef.setSimpleName("ClassFoo")); + } +}