Skip to content

8358772: Template-Framework Library: Primitive Types #25672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public record Hook(String name) {
* @return A {@link Token} that captures the anchoring of the scope and the list of validated {@link Token}s.
*/
public Token anchor(Object... tokens) {
return new HookAnchorToken(this, Token.parse(tokens));
return new HookAnchorToken(this, TokenParser.parse(tokens));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ static <T1, T2, T3> Template.ThreeArgs<T1, T2, T3> make(String arg1Name, String
* @throws IllegalArgumentException if the list of tokens contains an unexpected object.
*/
static TemplateBody body(Object... tokens) {
return new TemplateBody(Token.parse(tokens));
return new TemplateBody(TokenParser.parse(tokens));
}

/**
Expand Down
45 changes: 3 additions & 42 deletions test/hotspot/jtreg/compiler/lib/template_framework/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,11 @@

package compiler.lib.template_framework;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

/**
* The {@link Template#body} and {@link Hook#anchor} are given a list of tokens, which are either
* {@link Token}s or {@link String}s or some permitted boxed primitives. These are then parsed
* and all non-{@link Token}s are converted to {@link StringToken}s. The parsing also flattens
* {@link List}s.
* {@link Token}s or {@link String}s or some permitted boxed primitives.
*/
sealed interface Token permits StringToken,
public sealed interface Token permits StringToken,
TemplateToken,
TemplateToken.ZeroArgs,
TemplateToken.OneArg,
Expand All @@ -42,37 +36,4 @@ sealed interface Token permits StringToken,
HookAnchorToken,
HookInsertToken,
AddNameToken,
NothingToken
{
static List<Token> parse(Object[] objects) {
if (objects == null) {
throw new IllegalArgumentException("Unexpected tokens: null");
}
List<Token> outputList = new ArrayList<>();
parseToken(Arrays.asList(objects), outputList);
return outputList;
}

private static void parseList(List<?> inputList, List<Token> outputList) {
for (Object o : inputList) {
parseToken(o, outputList);
}
}

private static void parseToken(Object o, List<Token> outputList) {
if (o == null) {
throw new IllegalArgumentException("Unexpected token: null");
}
switch (o) {
case Token t -> outputList.add(t);
case String s -> outputList.add(new StringToken(Renderer.format(s)));
case Integer s -> outputList.add(new StringToken(Renderer.format(s)));
case Long s -> outputList.add(new StringToken(Renderer.format(s)));
case Double s -> outputList.add(new StringToken(Renderer.format(s)));
case Float s -> outputList.add(new StringToken(Renderer.format(s)));
case Boolean s -> outputList.add(new StringToken(Renderer.format(s)));
case List<?> l -> parseList(l, outputList);
default -> throw new IllegalArgumentException("Unexpected token: " + o);
}
}
}
NothingToken {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package compiler.lib.template_framework;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

/**
* Helper class for {@link Token}, to keep the parsing methods package private.
*
* <p>
* The {@link Template#body} and {@link Hook#anchor} are given a list of tokens, which are either
* {@link Token}s or {@link String}s or some permitted boxed primitives. These are then parsed
* and all non-{@link Token}s are converted to {@link StringToken}s. The parsing also flattens
* {@link List}s.
*/
final class TokenParser {
static List<Token> parse(Object[] objects) {
if (objects == null) {
throw new IllegalArgumentException("Unexpected tokens: null");
}
List<Token> outputList = new ArrayList<>();
parseToken(Arrays.asList(objects), outputList);
return outputList;
}

private static void parseList(List<?> inputList, List<Token> outputList) {
for (Object o : inputList) {
parseToken(o, outputList);
}
}

private static void parseToken(Object o, List<Token> outputList) {
if (o == null) {
throw new IllegalArgumentException("Unexpected token: null");
}
switch (o) {
case Token t -> outputList.add(t);
case String s -> outputList.add(new StringToken(Renderer.format(s)));
case Integer s -> outputList.add(new StringToken(Renderer.format(s)));
case Long s -> outputList.add(new StringToken(Renderer.format(s)));
case Double s -> outputList.add(new StringToken(Renderer.format(s)));
case Float s -> outputList.add(new StringToken(Renderer.format(s)));
case Boolean s -> outputList.add(new StringToken(Renderer.format(s)));
case List<?> l -> parseList(l, outputList);
default -> throw new IllegalArgumentException("Unexpected token: " + o);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package compiler.lib.template_framework.library;

import java.util.List;

import compiler.lib.template_framework.DataName;
import compiler.lib.template_framework.Template;

/**
* The {@link CodeGenerationDataNameType} extends the {@link DataName.Type} with
* additional functionality for code generation. These types with their extended
* functionality can be used with many other code generation facilities in the
* library, such as generating random {@code Expression}s.
*/
public interface CodeGenerationDataNameType extends DataName.Type {

/**
* This method provides a random constant value for the type, which can
* be used as a token inside a {@link Template}.
*
* @return A random constant value.
*/
Object con();

/**
* The byte {@link PrimitiveType}.
*
* @return The byte {@link PrimitiveType}.
*/
static PrimitiveType bytes() { return PrimitiveType.BYTES; }

/**
* The short {@link PrimitiveType}.
*
* @return The short {@link PrimitiveType}.
*/
static PrimitiveType shorts() { return PrimitiveType.SHORTS; }

/**
* The char {@link PrimitiveType}.
*
* @return The char {@link PrimitiveType}.
*/
static PrimitiveType chars() { return PrimitiveType.CHARS; }

/**
* The int {@link PrimitiveType}.
*
* @return The int {@link PrimitiveType}.
*/
static PrimitiveType ints() { return PrimitiveType.INTS; }

/**
* The long {@link PrimitiveType}.
*
* @return The long {@link PrimitiveType}.
*/
static PrimitiveType longs() { return PrimitiveType.LONGS; }

/**
* The float {@link PrimitiveType}.
*
* @return The float {@link PrimitiveType}.
*/
static PrimitiveType floats() { return PrimitiveType.FLOATS; }

/**
* The double {@link PrimitiveType}.
*
* @return The double {@link PrimitiveType}.
*/
static PrimitiveType doubles() { return PrimitiveType.DOUBLES; }

/**
* The boolean {@link PrimitiveType}.
*
* @return The boolean {@link PrimitiveType}.
*/
static PrimitiveType booleans() { return PrimitiveType.BOOLEANS; }

/**
* List of all {@link PrimitiveType}s.
*/
List<PrimitiveType> PRIMITIVE_TYPES = List.of(
bytes(),
chars(),
shorts(),
ints(),
longs(),
floats(),
doubles(),
booleans()
);

/**
* List of all integral {@link PrimitiveType}s (byte, char, short, int, long).
*/
List<PrimitiveType> INTEGRAL_TYPES = List.of(
bytes(),
chars(),
shorts(),
ints(),
longs()
);

/**
* List of all subword {@link PrimitiveType}s (byte, char, short).
*/
List<PrimitiveType> SUBWORD_TYPES = List.of(
bytes(),
chars(),
shorts()
);

/**
* List of all floating {@link PrimitiveType}s (float, double).
*/
List<PrimitiveType> FLOATING_TYPES = List.of(
floats(),
doubles()
);

/**
* List of all integral and floating {@link PrimitiveType}s.
*/
List<PrimitiveType> INTEGRAL_AND_FLOATING_TYPES = List.of(
bytes(),
chars(),
shorts(),
ints(),
longs(),
floats(),
doubles()
);
}
Loading