Test literals
This commit is contained in:
Clément Fournier
committed by
Andreas Dangel
parent
56b2e6c420
commit
dc56dd0676
@ -65,7 +65,7 @@ by it was inconsistent, and ultimately that level of nesting was unnecessary.
|
||||
* As is usual, use the designer to explore the new AST structure
|
||||
|
||||
* {% jdoc_old jast::ASTPrimaryPrefix %} and {% jdoc_old jast::ASTPrimarySuffix %} are not nodes anymore.
|
||||
Subtrees for expressions appear to be left-recursive now. For example,
|
||||
Subtrees for primary expressions appear to be left-recursive now. For example,
|
||||
|
||||
```java
|
||||
new Foo().bar.foo(1)
|
||||
@ -120,6 +120,23 @@ give you the information you need quickly.
|
||||
TODO write a summary of changes in the javadoc of the package, will be more
|
||||
accessible.
|
||||
|
||||
Note: this doesn't affect binary expressions like {% jdoc jast::ASTAdditiveExpression %}.
|
||||
E.g. `a+b+c` is not parsed as
|
||||
```
|
||||
AdditiveExpression
|
||||
+ AdditiveExpression
|
||||
+ (a)
|
||||
+ (b)
|
||||
+ (c)
|
||||
```
|
||||
It's still
|
||||
```
|
||||
AdditiveExpression
|
||||
+ (a)
|
||||
+ (b)
|
||||
+ (c)
|
||||
```
|
||||
which is easier to navigate, especially from XPath.
|
||||
|
||||
## New API support guidelines
|
||||
|
||||
|
@ -5,19 +5,22 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public class ASTBooleanLiteral extends AbstractJavaTypeNode {
|
||||
public final class ASTBooleanLiteral extends AbstractJavaTypeNode implements ASTLiteral {
|
||||
|
||||
private boolean isTrue;
|
||||
|
||||
public ASTBooleanLiteral(int id) {
|
||||
|
||||
ASTBooleanLiteral(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public ASTBooleanLiteral(JavaParser p, int id) {
|
||||
|
||||
ASTBooleanLiteral(JavaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
public void setTrue() {
|
||||
|
||||
void setTrue() {
|
||||
isTrue = true;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,11 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a character literal. The image of this node can be the literal as it appeared
|
||||
* in the source, but JavaCC performs its own unescaping and some escapes may be lost. At the
|
||||
* very least it has delimiters. {@link #getUnescapedValue()} allows to recover the actual runtime value.
|
||||
*/
|
||||
public final class ASTCharLiteral extends AbstractJavaTypeNode implements ASTLiteral {
|
||||
|
||||
|
||||
@ -21,9 +26,7 @@ public final class ASTCharLiteral extends AbstractJavaTypeNode implements ASTLit
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accept the visitor. *
|
||||
*/
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
@ -39,9 +42,10 @@ public final class ASTCharLiteral extends AbstractJavaTypeNode implements ASTLit
|
||||
/**
|
||||
* Gets the char value of this literal.
|
||||
*/
|
||||
public char getEscapedValue() {
|
||||
// TODO
|
||||
return StringEscapeUtils.unescapeJava(getImage()).charAt(0);
|
||||
public char getUnescapedValue() {
|
||||
String image = getImage();
|
||||
String woDelims = image.substring(1, image.length() - 1);
|
||||
return StringEscapeUtils.unescapeJava(woDelims).charAt(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
* | {@link ASTCharLiteral CharLiteral}
|
||||
* | {@link ASTBooleanLiteral BooleanLiteral}
|
||||
* | {@link ASTNullLiteral NullLiteral}
|
||||
* | {@link ASTClassLiteral ClassLiteral}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@ -44,6 +45,21 @@ public interface ASTLiteral extends ASTPrimaryExpression {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this is a {@linkplain ASTNullLiteral class literal}.
|
||||
*/
|
||||
default boolean isClassLiteral() {
|
||||
return this instanceof ASTClassLiteral;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this is a {@linkplain ASTBooleanLiteral boolean literal}.
|
||||
*/
|
||||
default boolean isBooleanLiteral() {
|
||||
return this instanceof ASTBooleanLiteral;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a {@linkplain ASTNumericLiteral numeric literal}
|
||||
* of any kind.
|
||||
|
@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
@ -17,7 +16,7 @@ public class ASTNumericLiteral extends AbstractJavaTypeNode implements ASTLitera
|
||||
|
||||
|
||||
// by default is double
|
||||
// TODO this can be done in jjtCloseNodeScope
|
||||
// TODO all of this can be done in jjtCloseNodeScope
|
||||
private boolean isInt;
|
||||
private boolean isFloat;
|
||||
|
||||
@ -60,9 +59,7 @@ public class ASTNumericLiteral extends AbstractJavaTypeNode implements ASTLitera
|
||||
public boolean isIntLiteral() {
|
||||
String image = getImage();
|
||||
if (isInt && image != null && image.length() > 0) {
|
||||
if (!image.endsWith("l") && !image.endsWith("L")) {
|
||||
return true;
|
||||
}
|
||||
return !image.endsWith("l") && !image.endsWith("L");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -77,9 +74,7 @@ public class ASTNumericLiteral extends AbstractJavaTypeNode implements ASTLitera
|
||||
public boolean isLongLiteral() {
|
||||
String image = getImage();
|
||||
if (isInt && image != null && image.length() > 0) {
|
||||
if (image.endsWith("l") || image.endsWith("L")) {
|
||||
return true;
|
||||
}
|
||||
return image.endsWith("l") || image.endsWith("L");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -91,9 +86,7 @@ public class ASTNumericLiteral extends AbstractJavaTypeNode implements ASTLitera
|
||||
String image = getImage();
|
||||
if (isFloat && image != null && image.length() > 0) {
|
||||
char lastChar = image.charAt(image.length() - 1);
|
||||
if (lastChar == 'f' || lastChar == 'F') {
|
||||
return true;
|
||||
}
|
||||
return lastChar == 'f' || lastChar == 'F';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -109,9 +102,7 @@ public class ASTNumericLiteral extends AbstractJavaTypeNode implements ASTLitera
|
||||
String image = getImage();
|
||||
if (isFloat && image != null && image.length() > 0) {
|
||||
char lastChar = image.charAt(image.length() - 1);
|
||||
if (lastChar == 'd' || lastChar == 'D' || Character.isDigit(lastChar) || lastChar == '.') {
|
||||
return true;
|
||||
}
|
||||
return lastChar == 'd' || lastChar == 'D' || Character.isDigit(lastChar) || lastChar == '.';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -126,7 +117,8 @@ public class ASTNumericLiteral extends AbstractJavaTypeNode implements ASTLitera
|
||||
image = image.substring(1);
|
||||
}
|
||||
|
||||
if (image.endsWith("l")) {
|
||||
char last = image.charAt(image.length()-1);
|
||||
if (last == 'l' || last == 'd' || last == 'f') {
|
||||
image = image.substring(0, image.length() - 1);
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,10 @@ import org.apache.commons.lang3.StringEscapeUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a string literal. The image of this node is the literal as it appeared
|
||||
* in the source. {@link #getEscapedValue()} allows to recover the actual runtime value.
|
||||
* Represents a string literal. The image of this node can be the literal as it appeared
|
||||
* in the source, but JavaCC performs its own unescaping and some escapes may be lost.
|
||||
* At the very least it has delimiters. {@link #getUnescapedValue()} allows to recover
|
||||
* the actual runtime value.
|
||||
*/
|
||||
public final class ASTStringLiteral extends AbstractJavaTypeNode implements ASTLiteral {
|
||||
|
||||
@ -25,6 +27,42 @@ public final class ASTStringLiteral extends AbstractJavaTypeNode implements ASTL
|
||||
}
|
||||
|
||||
|
||||
private String reconstructedImage = null;
|
||||
|
||||
|
||||
@Override
|
||||
public String getImage() {
|
||||
if (reconstructedImage == null) {
|
||||
reconstructedImage = getEscapedStringLiteral(super.getImage());
|
||||
}
|
||||
return reconstructedImage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tries to reconstruct the original string literal. If the original length
|
||||
* is greater than the parsed String literal, then probably some unicode
|
||||
* escape sequences have been used.
|
||||
*/
|
||||
private String getEscapedStringLiteral(String javaccEscaped) {
|
||||
int fullLength = getEndColumn() - getBeginColumn();
|
||||
if (fullLength > javaccEscaped.length()) {
|
||||
StringBuilder result = new StringBuilder(fullLength);
|
||||
for (int i = 0; i < javaccEscaped.length(); i++) {
|
||||
char c = javaccEscaped.charAt(i);
|
||||
if (c < 0x20 || c > 0xff || javaccEscaped.length() == 1) {
|
||||
String hex = "0000" + Integer.toHexString(c);
|
||||
result.append("\\u").append(hex.substring(hex.length() - 4));
|
||||
} else {
|
||||
result.append(c);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
return javaccEscaped;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accept the visitor. *
|
||||
*/
|
||||
@ -43,8 +81,10 @@ public final class ASTStringLiteral extends AbstractJavaTypeNode implements ASTL
|
||||
/**
|
||||
* Returns the value without delimiters and unescaped.
|
||||
*/
|
||||
public String getEscapedValue() {
|
||||
return StringEscapeUtils.unescapeJava(getImage());
|
||||
public String getUnescapedValue() {
|
||||
String image = getImage();
|
||||
String woDelims = image.substring(1, image.length() - 1);
|
||||
return StringEscapeUtils.unescapeJava(woDelims);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ public class AvoidDuplicateLiteralsRule extends AbstractJavaRule {
|
||||
if (occurrences.size() >= threshold) {
|
||||
ASTLiteral first = occurrences.get(0);
|
||||
if (first instanceof ASTStringLiteral) {
|
||||
String rawImage = ((ASTStringLiteral) first).getEscapedValue();
|
||||
String rawImage = ((ASTStringLiteral) first).getUnescapedValue();
|
||||
Object[] args = {rawImage, occurrences.size(), first.getBeginLine(),};
|
||||
addViolation(data, first, args);
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.performance;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTBlockStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTStringLiteral;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
|
||||
@ -32,7 +31,7 @@ public class AppendCharacterWithCharRule extends AbstractJavaRule {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (((ASTStringLiteral) node).getEscapedValue().length() == 1) {
|
||||
if (((ASTStringLiteral) node).getUnescapedValue().length() == 1) {
|
||||
if (!InefficientStringBufferingRule.isInStringBufferOperation(node, 8, "append")) {
|
||||
return data;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
package net.sourceforge.pmd.lang.java.rule.performance;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTStringLiteral;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractPoorMethodCall;
|
||||
|
||||
@ -38,7 +37,7 @@ public class UseIndexOfCharRule extends AbstractPoorMethodCall {
|
||||
|
||||
@Override
|
||||
protected boolean isViolationArgument(Node arg) {
|
||||
return arg instanceof ASTStringLiteral && ((ASTStringLiteral) arg).getEscapedValue().length() == 1;
|
||||
return arg instanceof ASTStringLiteral && ((ASTStringLiteral) arg).getUnescapedValue().length() == 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,155 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.pmd.PMD;
|
||||
|
||||
public class ASTLiteralTest {
|
||||
|
||||
@Test
|
||||
public void testIsStringLiteral() {
|
||||
Set<ASTLiteral> literals = getNodes(ASTLiteral.class, TEST1);
|
||||
assertTrue((literals.iterator().next()).isStringLiteral());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNotStringLiteral() {
|
||||
Set<ASTLiteral> literals = getNodes(ASTLiteral.class, TEST2);
|
||||
assertFalse((literals.iterator().next()).isStringLiteral());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsIntIntLiteral() {
|
||||
Set<ASTLiteral> literals = getNodes(ASTLiteral.class, TEST3);
|
||||
assertTrue((literals.iterator().next()).isIntLiteral());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsIntLongLiteral() {
|
||||
Set<ASTLiteral> literals = getNodes(ASTLiteral.class, TEST4);
|
||||
assertTrue((literals.iterator().next()).isLongLiteral());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsFloatFloatLiteral() {
|
||||
Set<ASTLiteral> literals = getNodes(ASTLiteral.class, TEST5);
|
||||
assertTrue((literals.iterator().next()).isFloatLiteral());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsFloatDoubleLiteral() {
|
||||
Set<ASTLiteral> literals = getNodes(ASTLiteral.class, TEST6);
|
||||
assertTrue((literals.iterator().next()).isDoubleLiteral());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsCharLiteral() {
|
||||
Set<ASTLiteral> literals = getNodes(ASTLiteral.class, TEST7);
|
||||
assertTrue((literals.iterator().next()).isCharLiteral());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntValueParsing() {
|
||||
ASTNumericLiteral literal = new ASTNumericLiteral(1);
|
||||
literal.setIntLiteral();
|
||||
literal.setImage("1___234");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(7);
|
||||
assertEquals(1___234, literal.getValueAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntValueParsingBinary() {
|
||||
ASTNumericLiteral literal = new ASTNumericLiteral(1);
|
||||
literal.setIntLiteral();
|
||||
literal.setImage("0b0000_0010");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(7);
|
||||
assertEquals(0b0000_0010, literal.getValueAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntValueParsingNegativeHexa() {
|
||||
ASTNumericLiteral literal = new ASTNumericLiteral(1);
|
||||
literal.setIntLiteral();
|
||||
literal.setImage("-0X0000_000f");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(7);
|
||||
assertEquals(-0X0000_000f, literal.getValueAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatValueParsingNegative() {
|
||||
ASTNumericLiteral literal = new ASTNumericLiteral(1);
|
||||
literal.setFloatLiteral();
|
||||
literal.setImage("-3_456.123_456");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(7);
|
||||
assertEquals(-3_456.123_456f, literal.getValueAsFloat(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringUnicodeEscapesNotEscaped() {
|
||||
ASTStringLiteral literal = new ASTStringLiteral(1);
|
||||
literal.setImage("abcüabc");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(7);
|
||||
assertEquals("abcüabc", literal.getEscapedValue());
|
||||
assertEquals("abcüabc", literal.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringUnicodeEscapesInvalid() {
|
||||
ASTStringLiteral literal = new ASTStringLiteral(1);
|
||||
literal.setImage("abc\\uXYZAabc");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(12);
|
||||
assertEquals("abc\\uXYZAabc", literal.getEscapedValue());
|
||||
assertEquals("abc\\uXYZAabc", literal.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringUnicodeEscapesValid() {
|
||||
ASTStringLiteral literal = new ASTStringLiteral(1);
|
||||
literal.setImage("abc\u1234abc");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(12);
|
||||
assertEquals("abc\\u1234abc", literal.getEscapedValue());
|
||||
assertEquals("abcሴabc", literal.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterUnicodeEscapesValid() {
|
||||
ASTCharLiteral literal = new ASTCharLiteral(1);
|
||||
literal.setImage("\u0030");
|
||||
literal.testingOnlySetBeginColumn(1);
|
||||
literal.testingOnlySetEndColumn(6);
|
||||
assertEquals("\\u0030", literal.getEscapedValue());
|
||||
assertEquals("0", literal.getImage());
|
||||
}
|
||||
|
||||
private static final String TEST1 = "public class Foo {" + PMD.EOL + " String x = \"foo\";" + PMD.EOL + "}";
|
||||
|
||||
private static final String TEST2 = "public class Foo {" + PMD.EOL + " int x = 42;" + PMD.EOL + "}";
|
||||
|
||||
private static final String TEST3 = "public class Foo {" + PMD.EOL + " int x = 42;" + PMD.EOL + "}";
|
||||
|
||||
private static final String TEST4 = "public class Foo {" + PMD.EOL + " long x = 42L;" + PMD.EOL + "}";
|
||||
|
||||
private static final String TEST5 = "public class Foo {" + PMD.EOL + " float x = 3.14159f;" + PMD.EOL + "}";
|
||||
|
||||
private static final String TEST6 = "public class Foo {" + PMD.EOL + " double x = 3.14159;" + PMD.EOL + "}";
|
||||
|
||||
private static final String TEST7 = "public class Foo {" + PMD.EOL + " char x = 'x';" + PMD.EOL + "}";
|
||||
}
|
@ -0,0 +1,221 @@
|
||||
package net.sourceforge.pmd.lang.java.ast
|
||||
|
||||
import io.kotlintest.shouldBe
|
||||
import io.kotlintest.specs.FunSpec
|
||||
import net.sourceforge.pmd.lang.ast.test.shouldBe
|
||||
|
||||
/**
|
||||
* @author Clément Fournier
|
||||
* @since 7.0.0
|
||||
*/
|
||||
class ASTLiteralTest : FunSpec({
|
||||
|
||||
testGroup("String literal") {
|
||||
|
||||
"\"\"" should matchExpr<ASTStringLiteral> {
|
||||
it::isStringLiteral shouldBe true
|
||||
it::getUnescapedValue shouldBe ""
|
||||
it::getImage shouldBe "\"\""
|
||||
}
|
||||
|
||||
"\"foo\"" should matchExpr<ASTStringLiteral> {
|
||||
it::getUnescapedValue shouldBe "foo"
|
||||
it::getImage shouldBe "\"foo\""
|
||||
}
|
||||
|
||||
"\"foo\\t\"" should matchExpr<ASTStringLiteral> {
|
||||
it::getUnescapedValue shouldBe "foo\t"
|
||||
it::getImage shouldBe "\"foo\\t\""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
testGroup("String literal escapes") {
|
||||
"\"abc\u1234abc\"" should matchExpr<ASTStringLiteral> {
|
||||
it::getUnescapedValue shouldBe "abc\u1234abc"
|
||||
it::getImage shouldBe "\"abc\u1234abc\""
|
||||
}
|
||||
|
||||
"\"abc\\u1234abc\"" should matchExpr<ASTStringLiteral> {
|
||||
it::getUnescapedValue shouldBe "abc\u1234abc"
|
||||
it::getImage shouldBe "\"abc\\u1234abc\""
|
||||
}
|
||||
"\"abcüabc\"" should matchExpr<ASTStringLiteral> {
|
||||
it::getUnescapedValue shouldBe "abcüabc"
|
||||
it::getImage shouldBe "\"abcüabc\""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
testGroup("Char literal") {
|
||||
|
||||
"'c'" should matchExpr<ASTCharLiteral> {
|
||||
it::isCharLiteral shouldBe true
|
||||
it::getUnescapedValue shouldBe 'c'
|
||||
it::getImage shouldBe "'c'"
|
||||
}
|
||||
|
||||
"'\t'" should matchExpr<ASTCharLiteral> {
|
||||
it::getUnescapedValue shouldBe '\t'
|
||||
it::getImage shouldBe "'\t'"
|
||||
}
|
||||
|
||||
"'\\t'" should matchExpr<ASTCharLiteral> {
|
||||
it::getUnescapedValue shouldBe '\t'
|
||||
it::getImage shouldBe "'\\t'"
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("Class literals") {
|
||||
|
||||
"void.class" should matchExpr<ASTClassLiteral> {
|
||||
it::isClassLiteral shouldBe true
|
||||
it::isVoid shouldBe true
|
||||
it.typeNode.shouldBeEmpty()
|
||||
}
|
||||
|
||||
"Integer.class" should matchExpr<ASTClassLiteral> {
|
||||
it::isClassLiteral shouldBe true
|
||||
it::isVoid shouldBe false
|
||||
|
||||
it.typeNode shouldBePresent child<ASTClassOrInterfaceType> {}
|
||||
}
|
||||
|
||||
"int.class" should matchExpr<ASTClassLiteral> {
|
||||
it::isVoid shouldBe false
|
||||
|
||||
it.typeNode shouldBePresent child<ASTPrimitiveType> {}
|
||||
}
|
||||
|
||||
"int[].class" should matchExpr<ASTClassLiteral> {
|
||||
it::isVoid shouldBe false
|
||||
|
||||
it.typeNode shouldBePresent child<ASTArrayType> {
|
||||
it.elementType shouldBe child<ASTPrimitiveType> {}
|
||||
it.dimensions shouldBe child {
|
||||
it.size shouldBe 1
|
||||
|
||||
child<ASTArrayTypeDim> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
testGroup("Boolean literals") {
|
||||
|
||||
"true" should matchExpr<ASTBooleanLiteral> {
|
||||
it::isBooleanLiteral shouldBe true
|
||||
it::isTrue shouldBe true
|
||||
}
|
||||
|
||||
"false" should matchExpr<ASTBooleanLiteral> {
|
||||
it::isBooleanLiteral shouldBe true
|
||||
it::isTrue shouldBe false
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("Null literal") {
|
||||
|
||||
"null" should matchExpr<ASTNullLiteral> {
|
||||
it::isBooleanLiteral shouldBe false
|
||||
it::isStringLiteral shouldBe false
|
||||
it::isNullLiteral shouldBe true
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("Numeric literals") {
|
||||
|
||||
"12" should matchExpr<ASTNumericLiteral> {
|
||||
it::isStringLiteral shouldBe false
|
||||
it::isCharLiteral shouldBe false
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isIntLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe 12
|
||||
it::getValueAsLong shouldBe 12L
|
||||
it::getValueAsFloat shouldBe 12.0f
|
||||
it::getValueAsDouble shouldBe 12.0
|
||||
it::getImage shouldBe "12"
|
||||
}
|
||||
|
||||
"1___234" should matchExpr<ASTNumericLiteral> {
|
||||
it::isCharLiteral shouldBe false
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isIntLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe 1234
|
||||
it::getImage shouldBe "1___234"
|
||||
}
|
||||
|
||||
"0b0000_0010" should matchExpr<ASTNumericLiteral> {
|
||||
it::isCharLiteral shouldBe false
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isIntLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe 2
|
||||
it::getImage shouldBe "0b0000_0010"
|
||||
}
|
||||
|
||||
"-0X0000_000f" should matchExpr<ASTNumericLiteral> {
|
||||
it::isCharLiteral shouldBe false
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isIntLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe -15
|
||||
it::getImage shouldBe "-0X0000_000f"
|
||||
}
|
||||
|
||||
"12l" should matchExpr<ASTNumericLiteral> {
|
||||
it::isCharLiteral shouldBe false
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isIntLiteral shouldBe false
|
||||
it::isLongLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe 12
|
||||
it::getValueAsLong shouldBe 12L
|
||||
it::getValueAsFloat shouldBe 12.0f
|
||||
it::getValueAsDouble shouldBe 12.0
|
||||
it::getImage shouldBe "12l"
|
||||
}
|
||||
|
||||
"12L" should matchExpr<ASTNumericLiteral> {
|
||||
it::isLongLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe 12
|
||||
it::getValueAsLong shouldBe 12L
|
||||
it::getImage shouldBe "12L"
|
||||
}
|
||||
|
||||
"12d" should matchExpr<ASTNumericLiteral> {
|
||||
it::isIntLiteral shouldBe false
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isDoubleLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe 12
|
||||
it::getValueAsFloat shouldBe 12.0f
|
||||
it::getValueAsDouble shouldBe 12.0
|
||||
it::getImage shouldBe "12d"
|
||||
}
|
||||
|
||||
"12f" should matchExpr<ASTNumericLiteral> {
|
||||
it::isIntLiteral shouldBe false
|
||||
it::isDoubleLiteral shouldBe false
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isFloatLiteral shouldBe true
|
||||
it::getValueAsInt shouldBe 12
|
||||
it::getValueAsFloat shouldBe 12.0f
|
||||
it::getValueAsDouble shouldBe 12.0
|
||||
it::getImage shouldBe "12f"
|
||||
}
|
||||
|
||||
"-3_456.123_456" should matchExpr<ASTNumericLiteral> {
|
||||
it::isIntLiteral shouldBe false
|
||||
it::isDoubleLiteral shouldBe true
|
||||
it::isNumericLiteral shouldBe true
|
||||
it::isFloatLiteral shouldBe false
|
||||
it::getValueAsInt shouldBe -3456
|
||||
it::getValueAsFloat shouldBe -3456.123456f
|
||||
it::getValueAsDouble shouldBe -3456.123456
|
||||
it::getImage shouldBe "-3_456.123_456"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
Reference in New Issue
Block a user