mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
Implement subtyping for primitive types in templates
This commit is contained in:
parent
b7346c307f
commit
a0ebfef24b
@ -129,8 +129,8 @@ public final class Operations {
|
||||
ops.add(Expression.make(type, "(", type, " + ", type, ")"));
|
||||
ops.add(Expression.make(type, "(", type, " - ", type, ")"));
|
||||
ops.add(Expression.make(type, "(", type, " * ", type, ")"));
|
||||
ops.add(Expression.make(type, "(", type, " / ", type, ")"));
|
||||
ops.add(Expression.make(type, "(", type, " % ", type, ")"));
|
||||
ops.add(Expression.make(type, "(", type, " / ", type, ")", WITH_ARITHMETIC_EXCEPTION));
|
||||
ops.add(Expression.make(type, "(", type, " % ", type, ")", WITH_ARITHMETIC_EXCEPTION));
|
||||
|
||||
// Relational / Comparison Operators
|
||||
ops.add(Expression.make(BOOLEANS, "(", type, " == ", type, ")"));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 2026, 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
|
||||
@ -71,7 +71,22 @@ public final class PrimitiveType implements CodeGenerationDataNameType {
|
||||
|
||||
@Override
|
||||
public boolean isSubtypeOf(DataName.Type other) {
|
||||
return (other instanceof PrimitiveType pt) && pt.kind == kind;
|
||||
// Implement other >: this according to JLS §4.10.1.
|
||||
if (other instanceof PrimitiveType pt) {
|
||||
if (pt.kind == Kind.BOOLEAN || kind == Kind.BOOLEAN) {
|
||||
// Boolean does not have a supertype and only itself as a subtype.
|
||||
return pt.kind == kind;
|
||||
}
|
||||
if (pt.kind == Kind.CHAR || kind == Kind.CHAR) {
|
||||
// Char does not have a subtype, but .
|
||||
// The following is correct for the subtype relation to floats, since chars are 16 bits wide and floats 32 bits or more.
|
||||
return pt.kind == kind || (pt.byteSize() > this.byteSize() && this.kind != Kind.BYTE);
|
||||
}
|
||||
return (pt.isFloating() && !this.isFloating()) || // Due to float >: long, all integers are subtypes of floating point types.
|
||||
(pt.isFloating() == this.isFloating() && pt.byteSize() >= this.byteSize()); // Generally, narrower types are subtypes of wider types.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 2026, 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
|
||||
@ -48,6 +48,7 @@ import static compiler.lib.template_framework.Template.let;
|
||||
import static compiler.lib.template_framework.Template.$;
|
||||
import static compiler.lib.template_framework.Template.addDataName;
|
||||
import static compiler.lib.template_framework.DataName.Mutability.MUTABLE;
|
||||
import static compiler.lib.template_framework.DataName.Mutability.MUTABLE_OR_IMMUTABLE;
|
||||
|
||||
import compiler.lib.template_framework.library.Hooks;
|
||||
import compiler.lib.template_framework.library.CodeGenerationDataNameType;
|
||||
@ -129,7 +130,8 @@ public class TestPrimitiveTypes {
|
||||
}
|
||||
|
||||
// Finally, test the type by creating some DataNames (variables), and sampling
|
||||
// from them. There should be no cross-over between the types.
|
||||
// from them. Sampling exactly should not lead to any conversion and sampling
|
||||
// subtypes should only lead to widening conversions.
|
||||
// IMPORTANT: since we are adding the DataName via an inserted Template, we
|
||||
// must chose a "transparentScope", so that the DataName escapes. If we
|
||||
// instead chose "scope", the test would fail, because it later
|
||||
@ -150,6 +152,14 @@ public class TestPrimitiveTypes {
|
||||
"""
|
||||
));
|
||||
|
||||
var assignmentTemplate = Template.make("lhsType", (PrimitiveType lhsType) -> scope(
|
||||
dataNames(MUTABLE).exactOf(lhsType).sampleAndLetAs("lhs"),
|
||||
dataNames(MUTABLE_OR_IMMUTABLE).subtypeOf(lhsType).sampleAndLetAs("rhs"),
|
||||
"""
|
||||
#lhs = #rhs;
|
||||
"""
|
||||
));
|
||||
|
||||
var namesTemplate = Template.make(() -> scope(
|
||||
"""
|
||||
public static void test_names() {
|
||||
@ -161,10 +171,16 @@ public class TestPrimitiveTypes {
|
||||
).toList()
|
||||
),
|
||||
"""
|
||||
// Now sample:
|
||||
// Sample exactly:
|
||||
""",
|
||||
Collections.nCopies(10,
|
||||
CodeGenerationDataNameType.PRIMITIVE_TYPES.stream().map(sampleTemplate::asToken).toList()
|
||||
),
|
||||
"""
|
||||
// Sample subtypes:
|
||||
""",
|
||||
Collections.nCopies(10,
|
||||
CodeGenerationDataNameType.PRIMITIVE_TYPES.stream().map(assignmentTemplate::asToken).toList()
|
||||
)
|
||||
)),
|
||||
"""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user