1 /*
  2  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 import org.testng.Assert;
 25 import org.testng.annotations.DataProvider;
 26 import org.testng.annotations.Test;
 27 
 28 import java.lang.reflect.code.parser.impl.Scanner;
 29 import java.lang.reflect.code.parser.impl.Tokens;
 30 import java.util.ArrayList;
 31 import java.util.List;
 32 
 33 import static java.lang.reflect.code.parser.impl.Tokens.TokenKind.*;
 34 
 35 /*
 36  * @test
 37  * @modules java.base/java.lang.reflect.code.parser.impl
 38  * @run testng TestScanner
 39  */
 40 
 41 public class TestScanner {
 42 
 43     @DataProvider
 44     Object[][] data() {
 45         return new Object[][] {
 46                 {"java.lang.Integer", List.of(IDENTIFIER, DOT, IDENTIFIER, DOT, IDENTIFIER)},
 47                 {"java.lang.Integer", List.of("java", DOT, "lang", DOT, "Integer")},
 48                 {"a<a<a, a>,a<a, a>>", List.of("a", LT,
 49                         "a", LT, "a", COMMA, "a", GT,
 50                         COMMA,
 51                         "a", LT, "a", COMMA, "a", GT,
 52                         GT)},
 53                 {"_->(){}[],.=><?:;+-&^@", List.of(
 54                         UNDERSCORE,
 55                         ARROW,
 56                         LPAREN,
 57                         RPAREN,
 58                         LBRACE,
 59                         RBRACE,
 60                         LBRACKET,
 61                         RBRACKET,
 62                         COMMA,
 63                         DOT,
 64                         EQ,
 65                         GT,
 66                         LT,
 67                         QUES,
 68                         COLON,
 69                         SEMI,
 70                         PLUS,
 71                         SUB,
 72                         AMP,
 73                         CARET,
 74                         MONKEYS_AT
 75                         )},
 76                 {"%1 %a %_1", List.of(VALUE_IDENTIFIER, VALUE_IDENTIFIER, VALUE_IDENTIFIER)},
 77                 {"%1 %a %_1", List.of("%1", "%a", "%_1")},
 78                 {"\"abc\\n\"", List.of(STRINGLITERAL)},
 79                 {"\"abc \\b \\f \\n \\r \\t \\' \\\" \\\\\"", List.of("abc \b \f \n \r \t \' \" \\")},
 80         };
 81     }
 82 
 83     @Test(dataProvider = "data")
 84     public void test(String content, List<Object> expectedTokens) {
 85         Scanner.Factory factory = Scanner.factory();
 86 
 87         Scanner s = factory.newScanner(content);
 88         s.nextToken();
 89         List<Tokens.Token> actualTokens = new ArrayList<>();
 90         while (s.token().kind != EOF) {
 91             actualTokens.add(s.token());
 92             s.nextToken();
 93         }
 94 
 95         Assert.assertEquals(actualTokens.size(), expectedTokens.size());
 96         for (int i = 0; i < expectedTokens.size(); i++) {
 97             Object e = expectedTokens.get(i);
 98             Tokens.Token a = actualTokens.get(i);
 99             if (e instanceof Tokens.TokenKind t) {
100                 Assert.assertEquals(a.kind, t);
101             } else if (e instanceof String v) {
102                 String as = switch (a.kind.tag) {
103                     case NAMED -> a.name();
104                     case STRING, NUMERIC -> a.stringVal();
105                     case DEFAULT -> a.kind.name;
106                 };
107                 Assert.assertEquals(as, v);
108             } else {
109                 assert false;
110             }
111         }
112     }
113 }