package org.jmlspecs.openjmltest.testcases;
import static com.sun.tools.javac.parser.Tokens.*;
import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
import static org.jmlspecs.openjml.JmlTokenKind.*;
import org.jmlspecs.openjml.JmlTokenKind;
import org.jmlspecs.openjmltest.JmlTestCase;
import org.jmlspecs.openjmltest.TestJavaFileObject;
import org.junit.Ignore;
import org.junit.Test;
import com.sun.tools.javac.parser.JmlScanner;
import com.sun.tools.javac.parser.JmlToken;
import com.sun.tools.javac.parser.Scanner;
import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.parser.Tokens;
import com.sun.tools.javac.util.Log;
import static org.junit.Assert.*;
// TODO - should test unicode, especially with multiple backslashes
// TODO - should test errPos for error tokens (is endPos set?)
public class scanner extends JmlTestCase {
final static JmlTokenKind EJML = ENDJMLCOMMENT;
ScannerFactory fac;
String[] keys;
// TODO - do we need to collect and compare System.out,err
/** Initializes a fresh scanner factory for each test */
@Override
public void setUp() throws Exception {
super.setUp(); // Sets up a main program, diagnostic collector
fac = ScannerFactory.instance(context);
keys = null;
}
/** This is a helper routine to check tests that are supposed to issue
* JUnit test failures.
*
* @param failureMessage The expected JUnit failure message
* @param s The string to parse
* @param list The tokens expected
* @param positions The expected start and end positions for each token
* @param numErrors The expected number of scanning errors
*/
//@ requires positions != null && list != null ==> positions.length == list.length*2;
public void helpFailure(String failureMessage, String s, ITokenKind[] list, /*@nullable*/ int[] positions, int numErrors) {
boolean failed = false;
try {
helpScanner(s,list,positions,numErrors);
} catch (AssertionError a) {
failed = true;
assertEquals("Failure report wrong",failureMessage,a.getMessage());
}
if (!failed) fail("Test harness failed to report an error");
}
/** This scans the input string and checks whether the tokens obtained
* match those in the list array and whether the positions found
* match those in the positions array and whether the number of
* errors found is 0. The positions array contains a start and end position
* for each token.
*/
public void helpScanner(String s, ITokenKind[] list, int[] positions) {
helpScanner(s,list,positions,0);
}
/** This scans the input string and checks whether the tokens obtained
* match those in the list array and whether the positions found
* match those in the positions array and whether the number of
* errors found is the last argument. The positions array contains a start and end position
* for each token.
*/
public void helpScanner(String s, ITokenKind[] list, int[] positions, int numErrors) {
try {
Log.instance(context).useSource(new TestJavaFileObject(s) );
JmlScanner sc = (JmlScanner)fac.newScanner(s, true);
if (keys != null) {
for (String k: keys) { ((JmlScanner)sc).keys().add(k); }
}
int i = 0;
while (i<list.length) {
sc.nextToken();
if (print) System.out.println(sc.token() + " " + ((JmlScanner)sc).jmlToken());
Token e = sc.token();
if (e.ikind != list[i]) {
fail("Unexpected token at position " + i + " expected: " + list[i] + " actual: " + e.kind );
}
if (positions != null && 2*i+1 < positions.length) {
assertEquals("pos for token " + i, positions[2*i], e.pos);
assertEquals("endpos for token " + i, positions[2*i+1], e.endPos);
}
i++;
}
sc.nextToken();
if (sc.token().kind != TokenKind.EOF) {
fail("Scanner not at EOF: " + sc.token().kind);
}
if (collector.getDiagnostics().size() != numErrors) {
if (!noExtraPrinting) printDiagnostics();
fail("Saw wrong number of errors: expected " + numErrors
+ " actual " + collector.getDiagnostics().size());
}
if (positions != null && 2*i != positions.length) fail("Number of start/end locations (" + (positions.length) + ") should be double the number of tokens (" + i + ")");
} catch (Exception e) {
e.printStackTrace(System.out);
fail("Exception thrown while processing test: " + e);
}
}
////////////////////////////////////////////////////////////////////////
/** Test scanning something very simple */
@Test public void testSomeJava() {
helpScanner("",new TokenKind[]{},null);
helpScanner("A",new TokenKind[]{IDENTIFIER},new int[]{0,1});
}
/** Test some unicode */
@Test public void testSomeUnicode() {
helpScanner("\\u0041\\u0020\\u0041",
new TokenKind[]{IDENTIFIER,IDENTIFIER},
new int[]{5,11,17,18}); // Current behavior but wrong - BUG - FIXME
//new int[]{0,6,12,18}); // This is what it should be
}
/** Test some unicode - multiple u*/
@Test public void testSomeUnicode2() {
helpScanner("\\uuuu0041 A",
new TokenKind[]{IDENTIFIER,IDENTIFIER},
null);
}
/** Test some unicode - multiple backslash*/
@Ignore // FIXME - understand correct unicode behavior here
@Test public void testSomeUnicode3() {
helpScanner("\\\\u0041 A",new ITokenKind[]{ERROR,IDENTIFIER,IDENTIFIER},
new int[]{0,1,2,7,8,9});
}
/** This tests that the test harness records if not enough tokens are listed */
@Test public void testHarness1() {
helpFailure("Scanner not at EOF: token.identifier",
"A A",new ITokenKind[]{IDENTIFIER},null,0);
}
/** This tests that the test harness records if too many tokens are listed */
@Test public void testHarness2() {
helpFailure("Unexpected token at position 1 expected: token.identifier actual: token.end-of-input",
"A",new ITokenKind[]{IDENTIFIER,IDENTIFIER},null,0);
}
/** This tests that the test harness records if a wrong token is listed */
@Test public void testHarness3() {
helpFailure("Unexpected token at position 0 expected: public actual: token.identifier",
"A",new ITokenKind[]{PUBLIC},null,0);
}
/** This tests that the test harness records if too many tokens are listed */
@Test public void testHarness4() {
helpFailure("Unexpected token at position 2 expected: token.identifier actual: token.end-of-input",
"A",new ITokenKind[]{IDENTIFIER,EOF,IDENTIFIER},null,0);
}
/** This tests that the test harness records if wrong start position is given */
@Test public void testHarness5() {
helpFailure("pos for token 0 expected:<1> but was:<0>",
"A",new ITokenKind[]{IDENTIFIER,EOF},new int[]{1,2,3,4},0);
}
/** This tests that the test harness fails if wrong end position is given */
@Test public void testHarness6() {
helpFailure("endpos for token 0 expected:<2> but was:<1>",
"A",new ITokenKind[]{IDENTIFIER,EOF},new int[]{0,2,3,4},0);
}
/** This tests that the test harness fails if wrong number of errors is given */
@Test public void testHarness7() {
noExtraPrinting = true;
helpFailure("Saw wrong number of errors: expected 1 actual 0",
"A",new ITokenKind[]{IDENTIFIER,EOF},new int[]{0,1,1,1},1);
}
/** This tests that the test harness fails if too few positions are given */
@Test public void testHarness8() {
helpFailure("Number of start/end locations (1) should be double the number of tokens (2)",
"A",new ITokenKind[]{IDENTIFIER,EOF},new int[]{0},0);
}
/** This tests that the test harness fails if too few positions are given */
@Test public void testHarness9() {
helpFailure("Number of start/end locations (2) should be double the number of tokens (2)",
"A",new ITokenKind[]{IDENTIFIER,EOF},new int[]{0,1},0);
}
/** This tests that the test harness fails if too few positions are given */
@Test public void testHarness10() {
helpFailure("Number of start/end locations (0) should be double the number of tokens (2)",
"A",new ITokenKind[]{IDENTIFIER,EOF},new int[]{},0);
}
/** This tests that the test harness fails if too many positions are given */
@Test public void testHarness11() {
helpFailure("Number of start/end locations (7) should be double the number of tokens (2)",
"A",new ITokenKind[]{IDENTIFIER,EOF},new int[]{0,1,1,1,4,5,6},0);
}
/** Tests that JML keywords are not found in Java */
@Test public void testJmlKeywordsNotInJml() {
helpScanner("requires ensures pure",
new ITokenKind[]{IDENTIFIER,IDENTIFIER,IDENTIFIER,},
new int[]{0,8,9,16,17,21});
}
/** Tests that JML keywords are found in a JML comment */
@Test public void testJmlKeywordsInJml() {
helpScanner("/*@requires ensures pure */",
new ITokenKind[]{REQUIRES,ENSURES,PURE,EJML,},
new int[]{3,11,12,19,20,24,25,27});
}
/** Tests that JML keywords are found in a JML comment */
@Test public void testJmlKeywordsInJmlA() {
helpScanner("//@requires ensures pure \n ",
new ITokenKind[]{REQUIRES,ENSURES,PURE,EJML,EOF},
new int[]{3,11,12,19,20,24,25,26,26,26}); // FIXME - review postion of EOF
}
/** Tests that JML keywords are found in a JML comment with nowarn */
@Test public void testJmlKeywordsInJmlWithNoWarn() {
helpScanner("/*@nowarn A; nowarn B,requires,C; requires ensures pure */",
new ITokenKind[]{REQUIRES,ENSURES,PURE,EJML,},
new int[]{34,42,43,50,51,55,56,58});
}
/** Tests that JML keywords are not found in a Java comment */
@Test public void testJmlKeywordsNotInJavaComment() {
helpScanner("/* requires */ /*@requires */",
new ITokenKind[]{REQUIRES,EJML,},
new int[]{18,26,27,29});
}
/** Tests that JML keywords are not found after a JML comment ends */
@Test public void testJmlKeywordsAfterJml() {
helpScanner("/*@requires */requires ensures pure",
new ITokenKind[]{REQUIRES,EJML,IDENTIFIER,IDENTIFIER,IDENTIFIER,},
new int[]{3,11,12,14,14,22,23,30,31,35});
}
/** Tests JML operators */
@Test public void testOperators() {
helpScanner("/*@ ==> <== <: <==> <=!=> -> <- */",
new ITokenKind[]{IMPLIES,REVERSE_IMPLIES,SUBTYPE_OF,EQUIVALENCE,INEQUIVALENCE,RIGHT_ARROW,LEFT_ARROW,EJML},
new int[]{4,7, 8,11, 12,14, 15,19, 20,25, 26,28, 29,31, 32,34});
}
/** Tests the Java operators related to JML operators */
@Test public void testOperators1() {
helpScanner("/*@ == <= < */",
new ITokenKind[]{EQEQ,LTEQ,LT,EJML},
new int[]{4,6,8,10,12,13,15,17});
}
/** Tests JML operators when in Java land */
@Test public void testOperators2() {
helpScanner(" ==> <== <: <==> <=!=> ",
new ITokenKind[]{EQEQ,GT, LTEQ,EQ, LT,COLON, LTEQ,EQ,GT, LTEQ,BANGEQ,GT},
new int[]{4,6,6,7, 8,10,10,11, 12,13,13,14, 15,17,17,18,18,19, 20,22,22,24,24,25});
}
@Test public void testBadOperator() {
helpScanner("/*@ <=! + */",
new ITokenKind[]{LTEQ,BANG,PLUS,EJML},
new int[]{4,6,6,7,8,9,10,12});
}
@Test public void testBadOperator2() {
helpScanner("/*@ <=!= + */",
new ITokenKind[]{LTEQ,BANGEQ,PLUS,EJML},
new int[]{4,6,6,8,9,10,11,13});
}
// NOTE: In the test strings, backslash characters must be escaped. So
// within the string you write \\result, not \result, to get the effect of
// \result in a test program.
/** Test that a backslash token is found */
@Test public void testBackslash() {
helpScanner("/*@ \\result */",
new ITokenKind[]{BSRESULT,EJML},
null);
}
/** Test that two immediately consecutive backslash tokens are found */
@Test public void testBackslash1() {
helpScanner("/*@ \\result\\result */",
new ITokenKind[]{BSRESULT,BSRESULT,EJML},
null);
}
/** Test that backslash tokens are found immediately after a line termination */
@Test public void testBackslash2() {
helpScanner("/*@ \\result \n\\result*/",
new ITokenKind[]{BSRESULT,BSRESULT,EJML},
null);
}
/** Test that a backslash token without the backslash is a regular identifier */
@Test public void testBackslash3() {
helpScanner("/*@ \\result result*/",
new ITokenKind[]{BSRESULT,IDENTIFIER,EJML},
null);
}
/** Test for an invalid backslash identifier */
@Test public void testBackslash5() {
helpScanner("/*@ \\xyz result*/",
new ITokenKind[]{ERROR,IDENTIFIER,EJML},
null,
1);
checkMessages(new String[]{"/TEST.java:1: This backslash token is unknown: \\xyz"},
new int[]{5});
}
/** Test for a JML backslash with no identifier */
@Test public void testBackslash6() {
helpScanner("/*@ \\ \\result*/",
new ITokenKind[]{ERROR,BSRESULT,EJML},
null,
1);
checkMessages("/TEST.java:1: A backslash in a JML comment expects to be followed by a valid identifier",5);
}
/** Test an empty Java line comment */
@Test public void testEmptyJavaComment() {
helpScanner("//",
new ITokenKind[]{},
new int[]{});
}
/** Test a mismatched comment ending */
@Test public void testMisMatchedJMLComment() {
helpScanner("//@*/ requires",
new ITokenKind[]{STAR,SLASH,REQUIRES,EOF},
null);
}
/** Test an empty JML line comment */
@Test public void testEmptyJMLComment() {
helpScanner("//\n//@requires",
new ITokenKind[]{REQUIRES,EOF},
null);
}
/** Test an embedded JML comment */
@Test public void testEmbeddedJMLComment() {
helpScanner("//@requires //@ requires",
new ITokenKind[]{REQUIRES,REQUIRES,EOF},
null);
}
/** Test an embedded JML comment */
@Test public void testEmbeddedJMLComment3() {
helpScanner("/*@requires /*@ requires */ requires */ public",
new ITokenKind[]{REQUIRES,REQUIRES,EJML,IDENTIFIER,STAR,SLASH,PUBLIC,EOF},
null);
}
/** Test an embedded JML comment */
@Test public void testEmbeddedJMLComment4() {
helpScanner("/*@requires //@ requires \n requires */ public",
new ITokenKind[]{REQUIRES,REQUIRES,REQUIRES,EJML,PUBLIC,EOF},
null);
}
/** Test an embedded JML comment */
@Test public void testEmbeddedJMLComment2() {
helpScanner("/*@requires //@ requires */ public",
new ITokenKind[]{REQUIRES,REQUIRES,EJML,PUBLIC,EOF},
null);
}
/** Test an embedded JML comment */
@Test public void testEmbeddedJMLComment5() {
helpScanner("//@requires /*@ requires\n requires */ requires",
new ITokenKind[]{REQUIRES,REQUIRES,EJML,IDENTIFIER,STAR, SLASH,IDENTIFIER,EOF},
null);
}
/** Test an embedded Java comment */
@Test public void testEmbeddedJavaComment() {
helpScanner("//@requires // requires",
new ITokenKind[]{REQUIRES,EOF},
null);
}
/** Test an embedded JML comment */
@Test public void testEmbeddedJavaComment2() {
helpScanner("//@requires /* requires */ ensures ",
new ITokenKind[]{REQUIRES,ENSURES,EOF},
null);
}
/** Test an embedded JML comment */
@Ignore // TODO: DO we really want this style of embedded comment to work?
@Test public void testEmbeddedJavaComment3() {
helpScanner("//@requires /* requires ensures \n signals */ modifies ",
new ITokenKind[]{REQUIRES,ASSIGNABLE,EOF},
new int[]{3,11,45,53,54,54});
}
/** Test an embedded Java comment */
@Test public void testEmbeddedJavaComment4() {
helpScanner("/*@requires // modifies \n ensures */ signals ",
new ITokenKind[]{REQUIRES,ENSURES,EJML,IDENTIFIER,EOF},
new int[]{3,11,26,33,34,36,37,44,44,44}); // FIXME - check position of EOF
}
/** Test an embedded Java comment */
@Ignore // TODO: DO we really want this style of embedded comment to work?
@Test public void testEmbeddedJavaComment6() {
helpScanner("/*@requires /* modifies \n ensures */ requires */ signals ",
new ITokenKind[]{REQUIRES,IDENTIFIER,STAR,SLASH,IDENTIFIER,EOF},
null);
}
@Test public void testLineComment1() {
helpScanner("//@ requires",new ITokenKind[]{REQUIRES,EOF},null);
}
// NOTE: The scanner absorbs ending whitespace into the EOF.
@Test public void testLineComment2() {
helpScanner("//@ requires\n",new ITokenKind[]{REQUIRES,EOF},null);
}
/** Test that a line comment ends with a NL character */
@Test public void testLineComment3() {
helpScanner("//@ requires\n ",
new ITokenKind[]{REQUIRES,EJML},
new int[]{4,12,12,13});
}
/** Test that a line comment ends with a CR character */
@Test public void testLineComment4() {
helpScanner("//@ requires\r ",
new ITokenKind[]{REQUIRES,EJML},
null);
}
/** Test that a line comment ends with a CR NL combination */
@Test public void testLineComment5() {
helpScanner("//@ requires\r\n",
new ITokenKind[]{REQUIRES,EJML},
null);
}
/** Test that JML identifiers are not found after a JML line comment ends*/
@Test public void testLineComment6() {
helpScanner("//@ requires\nrequires",
new ITokenKind[]{REQUIRES,EJML,IDENTIFIER},
null);
}
/** Test that an @ at the end of a line comment is found */
@Test public void testLineComment7() {
helpScanner("//@ requires @\n ",
new ITokenKind[]{REQUIRES,MONKEYS_AT,EJML},
null);
}
/** Test an empty line comment */
@Test public void testLineComment8() {
helpScanner("//\nrequires ",
new ITokenKind[]{IDENTIFIER},
null);
}
/** Test an empty JML line comment */
@Test public void testLineComment9() {
helpScanner("//@\nrequires ",
new ITokenKind[]{IDENTIFIER},
null);
}
/** Test an empty JML line comment */
@Test public void testLineComment10() {
helpScanner("//@@@@@\nrequires ",
new ITokenKind[]{IDENTIFIER},
null);
}
/** Test a bad backslash */
@Test public void testLineComment11() {
helpScanner("//@@x\\@@@\nrequires ",
new ITokenKind[]{IDENTIFIER,ERROR,MONKEYS_AT,MONKEYS_AT,MONKEYS_AT,EJML,IDENTIFIER},
null,1);
checkMessages("/TEST.java:1: A backslash in a JML comment expects to be followed by a valid identifier",6);
}
/** Test a bad backslash */
@Test public void testLineComment11a() {
helpScanner("//@@\\@x@@\nrequires ",
new ITokenKind[]{ERROR,MONKEYS_AT,IDENTIFIER,MONKEYS_AT,MONKEYS_AT,EJML,IDENTIFIER},
null,1);
checkMessages("/TEST.java:1: A backslash in a JML comment expects to be followed by a valid identifier",5);
}
@Test public void testMultiLine() {
helpScanner("/*@ requires\nrequires@*/",
new ITokenKind[]{REQUIRES,REQUIRES,EJML},
null);
}
@Test public void testMultiLine1() {
helpScanner("/*@ requires\n requires@*/",
new ITokenKind[]{REQUIRES,REQUIRES,EJML},
null);
}
@Test public void testMultiLine2() {
helpScanner("/*@ requires\n@requires@*/",
new ITokenKind[]{REQUIRES,REQUIRES,EJML},
null);
}
@Test public void testMultiLine3() {
helpScanner("/*@ requires\n@@@requires@*/",
new ITokenKind[]{REQUIRES,REQUIRES,EJML},
null);
}
@Test public void testMultiLine4() {
helpScanner("/*@ requires\n @requires@*/",
new ITokenKind[]{REQUIRES,REQUIRES,EJML},
null);
}
@Test public void testMultiLine5() {
helpScanner("/*@ requires\n @@@requires@*/",
new ITokenKind[]{REQUIRES,REQUIRES,EJML},
null);
}
@Test public void testMultiLineError() {
helpScanner("/*@ \\result\n @@@\\xyz@*/",
new ITokenKind[]{BSRESULT,ERROR,EJML,EOF},
new int[]{4,11,17,21,21,24,24,24},
1);
checkMessages("/TEST.java:2: This backslash token is unknown: \\xyz",6);
}
@Test public void testInformalComment() {
helpScanner("/*@ \\result(* requires *)*/",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,EJML},
new int[]{4,11,11,25,25,27},
0);
}
@Test public void testInformalComment2() {
helpScanner("/*@ \\result(* requires *****)*/",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,EJML},
new int[]{4,11,11,29,29,31},
0);
}
@Test public void testInformalComment3() {
helpScanner("/*@ \\result(* requires **** *)*/",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,EJML},
new int[]{4,11,11,30,30,32},
0);
}
// Testing an unclosed informal comment in a BLOCK comment
@Test public void testInformalComment4() {
helpScanner("/*@ \\result(* requires **** */",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,EJML},
new int[]{4,11,11,28,28,30},
1);
checkMessages("/TEST.java:1: The informal expression is not closed",13);
}
// Testing an unclosed informal comment in a BLOCK comment
@Test public void testInformalComment4a() {
helpScanner("/*@ \\result(* requires *\n*** */",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,EJML},
new int[]{4,11,11,29,29,31},
1);
checkMessages("/TEST.java:1: The informal expression is not closed",13);
}
// Testing an unclosed informal comment in a BLOCK comment
@Test public void testInformalComment4b() {
helpScanner("/*@ \\result(* requires *\n*** ",
new ITokenKind[]{ERROR,EOF},
null, //new int[]{4,11,11,30,30,31},
1);
checkMessages("/TEST.java:1: unclosed comment",1);
}
// Testing an unclosed informal comment in a LINE comment
@Test public void testInformalComment5() {
helpScanner("//@ \\result(* requires **** \n public",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,EJML,PUBLIC,EOF},
new int[]{4,11,11,28,28,29,30,36,36,36},
1);
checkMessages("/TEST.java:1: The informal expression is not closed",13);
}
// Testing an unclosed informal comment in a LINE comment
@Test public void testInformalComment5a() {
helpScanner("//@ \\result(* requires *****",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,EOF},
new int[]{4,11,11,28,28,28},
1);
checkMessages("/TEST.java:1: The informal expression is not closed",13);
}
// Testing an unclosed informal comment in a LINE comment
@Test public void testInformalComment6() {
helpScanner("//@ \\result(* requires ***\"*) \" requires\n",
new ITokenKind[]{BSRESULT,INFORMAL_COMMENT,ERROR,EOF},
new int[]{4,11,11,29,30,40,40,40}, // FIXME - check posiiton of EOF
1);
checkMessages("/TEST.java:1: unclosed string literal",31);
}
@Test public void testStringLiteral() {
Scanner sc = fac.newScanner("\"\\tA\\\\B\"", true);
sc.nextToken();
assertEquals(STRINGLITERAL,sc.token().kind);
assertEquals("\tA\\B",sc.token().stringVal());
}
@Test public void testCharLiteral() {
Scanner sc = fac.newScanner("\'\\t\'", true);
sc.nextToken();
assertEquals(CHARLITERAL,sc.token().kind);
assertEquals("\t",sc.token().stringVal());
}
@Test public void testIntLiteralWithUnderscore() {
String v = "123_456";
Scanner sc = fac.newScanner(v, true);
sc.nextToken();
assertEquals(INTLITERAL,sc.token().kind);
assertEquals("123456",sc.token().stringVal());
assertEquals(123456,Integer.parseInt(sc.token().stringVal()));
}
@Test public void testIntLiteralWithUnderscoreBin() {
String v = "0b0101_1010";
Scanner sc = fac.newScanner(v, true);
sc.nextToken();
assertEquals(INTLITERAL,sc.token().kind);
assertEquals("01011010",sc.token().stringVal());
assertEquals(90,Integer.parseInt(sc.token().stringVal(),2));
}
@Test public void testIntLiteralWithUnderscoreHex() {
String v = "0xDE_AF";
Scanner sc = fac.newScanner(v, true);
sc.nextToken();
assertEquals(INTLITERAL,sc.token().kind);
assertEquals("DEAF",sc.token().stringVal());
assertEquals(57007,Integer.parseInt(sc.token().stringVal(),16));
}
@Test public void testIntLiteralWithUnderscoreHexLong() {
String v = "0xDEAF_DEAF";
Scanner sc = fac.newScanner(v, true);
sc.nextToken();
assertEquals(INTLITERAL,sc.token().kind);
assertEquals("DEAFDEAF",sc.token().stringVal());
assertEquals(3736067759L,Long.parseLong(sc.token().stringVal(),16));
}
@Test public void testDotDot() {
helpScanner("//@..",
new ITokenKind[]{DOT_DOT,EOF},
new int[]{3,5,5,5},
0);
}
@Test public void testDotDot2() {
helpScanner("//@ modifies ..;",
new ITokenKind[]{ASSIGNABLE,DOT_DOT,SEMI,EOF},
null,
0);
}
@Test public void testDotDot2a() {
helpScanner("//@ 123..456;",
new ITokenKind[]{INTLITERAL,DOT_DOT,INTLITERAL,SEMI,EOF},
null,
0);
}
@Test public void testDotDot3() {
helpScanner("//@ modifies a[b .. c];",
new ITokenKind[]{ASSIGNABLE,IDENTIFIER,LBRACKET,IDENTIFIER,DOT_DOT,IDENTIFIER,RBRACKET,SEMI,EOF},
null,
0);
}
@Test public void testDotDot4() {
helpScanner("//@ modifies a[0..4];",
new ITokenKind[]{ASSIGNABLE,IDENTIFIER,LBRACKET,INTLITERAL,DOT_DOT,INTLITERAL,RBRACKET,SEMI,EOF},
null,
0);
}
@Test public void testDotDot4a() {
helpScanner("//@ modifies a[0 ..4];",
new ITokenKind[]{ASSIGNABLE,IDENTIFIER,LBRACKET,INTLITERAL,DOT_DOT,INTLITERAL,RBRACKET,SEMI,EOF},
null,
0);
}
@Test public void testDotDot5() {
helpScanner("//@ modifies ..234;",
new ITokenKind[]{ASSIGNABLE,DOT_DOT,INTLITERAL,SEMI,EOF},
null,
0);
}
@Test public void testDotDot6() {
helpScanner("//@ modifies .234;",
new ITokenKind[]{ASSIGNABLE,DOUBLELITERAL,SEMI,EOF},
null,
0);
}
@Test public void testDotDot7() {
helpScanner("//@ modifies 0.234;",
new ITokenKind[]{ASSIGNABLE,DOUBLELITERAL,SEMI,EOF},
null,
0);
}
@Test public void testDotDot8() {
helpScanner("//@ modifies a[0. .4];",
new ITokenKind[]{ASSIGNABLE,IDENTIFIER,LBRACKET,DOUBLELITERAL,DOUBLELITERAL,RBRACKET,SEMI,EOF},
null,
0);
}
@Test public void testDotDot9() {
helpScanner("//@ 0xApA\n ",
new ITokenKind[]{DOUBLELITERAL,IDENTIFIER,EJML,EOF},
null,
1);
checkMessages("/TEST.java:1: malformed floating point literal",5);
}
@Test public void testDotDot10() {
helpScanner("//@ 1.0eZ \n ",
new ITokenKind[]{DOUBLELITERAL,IDENTIFIER,EJML,EOF},
null,
1);
checkMessages("/TEST.java:1: malformed floating point literal",5);
}
@Test public void testDotDot11() {
helpScanner("//@ 0xA.0pZ\n ",
new ITokenKind[]{DOUBLELITERAL,IDENTIFIER,EJML,EOF},
null,
1);
checkMessages("/TEST.java:1: malformed floating point literal",5);
}
@Test public void testDotDot12() {
helpScanner("//@ 0xA.Z\n ",
new ITokenKind[]{DOUBLELITERAL,IDENTIFIER,EJML,EOF},
null,
1);
checkMessages("/TEST.java:1: malformed floating point literal",5);
}
@Test public void testConditionalKey1() {
helpScanner("//+POS@ requires\n /*+POS@ requires */",
new ITokenKind[]{EOF},
null);
}
@Test public void testConditionalKey2() {
helpScanner("//-NEG@ requires\n /*-NEG@ requires */",
new ITokenKind[]{REQUIRES,EJML,REQUIRES,EJML,EOF},
null);
}
@Test public void testConditionalKey3() {
keys = new String[]{"POS"};
helpScanner("//+POS@ requires\n /*+POS@ requires */",
new ITokenKind[]{REQUIRES,EJML,REQUIRES,EJML,EOF},
null);
}
@Test public void testConditionalKey4() {
keys = new String[]{"NEG"};
helpScanner("//-NEG@ requires\n /*-NEG@ requires */",
new ITokenKind[]{EOF},
null);
}
@Test public void testConditionalKey5() {
helpScanner("//-NEG+POS@ requires\n /*-NEG+POS@ requires */",
new ITokenKind[]{EOF},
null);
}
@Test public void testConditionalKey6() {
keys = new String[]{"POS"};
helpScanner("//-NEG+POS@ requires\n /*-NEG+POS@ requires */",
new ITokenKind[]{REQUIRES,EJML,REQUIRES,EJML,EOF},
null);
}
@Test public void testConditionalKey7() {
keys = new String[]{"NEG"};
helpScanner("//-NEG+POS@ requires\n /*-NEG+POS@ requires */",
new ITokenKind[]{EOF},
null);
}
@Test public void testConditionalKey8() {
keys = new String[]{"NEG","POS"};
helpScanner("//-NEG+POS@ requires\n /*-NEG+POS@ requires */",
new ITokenKind[]{EOF},
null);
}
@Test public void testConditionalKey9() {
helpScanner("//+@ requires\n /*+@ requires */",
new ITokenKind[]{REQUIRES,EJML,REQUIRES,EJML,EOF},
null);
}
@Test public void testConditionalKey10() {
helpScanner("//-@ requires\n /*-@ requires */",
new ITokenKind[]{EOF},
null);
}
}