From bd74278f058a7d76e42dbca1405f5f3d48433902 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 25 Oct 2023 13:34:33 +0100 Subject: [PATCH] Add support for constant expressions --- .../source/tree/ConstantExpressionTree.java | 42 ++++++ .../classes/com/sun/source/tree/Tree.java | 5 + .../com/sun/source/tree/TreeVisitor.java | 8 ++ .../sun/source/util/SimpleTreeVisitor.java | 14 ++ .../com/sun/source/util/TreeScanner.java | 14 ++ .../com/sun/tools/javac/code/Flags.java | 2 +- .../com/sun/tools/javac/comp/Attr.java | 14 ++ .../sun/tools/javac/comp/TransConstants.java | 132 ++---------------- .../classes/com/sun/tools/javac/jvm/Code.java | 4 +- .../com/sun/tools/javac/jvm/PoolConstant.java | 15 ++ .../sun/tools/javac/parser/JavacParser.java | 9 +- .../com/sun/tools/javac/tree/JCTree.java | 30 ++++ .../com/sun/tools/javac/tree/TreeCopier.java | 7 + .../com/sun/tools/javac/tree/TreeMaker.java | 6 + .../com/sun/tools/javac/tree/TreeScanner.java | 4 + .../sun/tools/javac/tree/TreeTranslator.java | 5 + .../javac/records/RecordCompilationTests.java | 2 +- 17 files changed, 188 insertions(+), 125 deletions(-) create mode 100644 src/jdk.compiler/share/classes/com/sun/source/tree/ConstantExpressionTree.java diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/ConstantExpressionTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/ConstantExpressionTree.java new file mode 100644 index 0000000000000..43f462f70d43a --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/ConstantExpressionTree.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 com.sun.source.tree; + +/** + * A tree node for a constant expression. + * + * For example: + *
+ *   const expression
+ * 
+ */ +public interface ConstantExpressionTree extends ExpressionTree { + /** + * Returns the initializer of the constant expression. + * @return the initializer of the constant expression. + */ + ExpressionTree getExpression(); +} diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java index cf3853035db79..0fddb8c2c4ec3 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java @@ -227,6 +227,11 @@ public enum Kind { */ PARENTHESIZED(ParenthesizedTree.class), + /** + * Used for instances of {@link ConstantExpressionTree}. + */ + CONSTANT_EXPRESSION(ConstantExpressionTree.class), + /** * Used for instances of {@link BindingPatternTree}. * diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java b/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java index 855783f65a4a3..67baaafc65bed 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java @@ -379,6 +379,14 @@ public interface TreeVisitor { */ R visitParenthesized(ParenthesizedTree node, P p); + /** + * Visits a {@code ConstantExpressionTree} node. + * @param node the node being visited + * @param p a parameter value + * @return a result value + */ + R visitConstantExpression(ConstantExpressionTree node, P p); + /** * Visits a {@code ReturnTree} node. * @param node the node being visited diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java index 569b38478b041..405e31df7fa31 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java @@ -544,6 +544,20 @@ public R visitParenthesized(ParenthesizedTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ + @Override + public R visitConstantExpression(ConstantExpressionTree node, P p) { + return defaultAction(node, p); + } + /** * {@inheritDoc} * diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java b/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java index 69d23172cf649..843cff6e0c5e1 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java @@ -662,6 +662,20 @@ public R visitParenthesized(ParenthesizedTree node, P p) { return scan(node.getExpression(), p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ + @Override + public R visitConstantExpression(ConstantExpressionTree node, P p) { + return scan(node.getExpression(), p); + } + /** * {@inheritDoc} * diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java index ad65876b9d10d..8856654aed349 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java @@ -435,7 +435,7 @@ public static String toSource(long flags) { ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT | SEALED | NON_SEALED, InterfaceMethodMask = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT, AnnotationTypeElementMask = ABSTRACT | PUBLIC, - LocalVarFlags = FINAL | PARAMETER | STATIC, + LocalVarFlags = FINAL | PARAMETER, ReceiverParamFlags = PARAMETER; public static Set asModifierSet(long flags) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 4b44be198d15d..2d58cc7777892 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -3974,6 +3974,20 @@ public void visitParens(JCParens tree) { log.error(tree.pos(), Errors.IllegalParenthesizedExpression); } + public void visitConstExpr(JCConstExpr tree) { + Env initEnv = env.dup(tree); + try { + initEnv.info.staticLevel++; + Type owntype = attribTree(tree.expr, initEnv, resultInfo); + result = check(tree, owntype, pkind(), resultInfo); + Symbol sym = TreeInfo.symbol(tree); + if (sym != null && sym.kind.matches(KindSelector.TYP_PCK) && sym.kind != Kind.ERR) + log.error(tree.pos(), Errors.IllegalParenthesizedExpression); + } finally { + initEnv.info.staticLevel--; + } + } + public void visitAssign(JCAssign tree) { Type owntype = attribTree(tree.lhs, env.dup(tree), varAssignmentInfo); Type capturedType = capture(owntype); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransConstants.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransConstants.java index ede46cacb7fa2..43d5d657012cf 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransConstants.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransConstants.java @@ -25,12 +25,8 @@ package com.sun.tools.javac.comp; -import com.sun.tools.javac.code.Scope; -import com.sun.tools.javac.code.Scope.WriteableScope; -import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.DynamicVarSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; -import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.MethodType; @@ -38,29 +34,20 @@ import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCConstExpr; import com.sun.tools.javac.tree.JCTree.JCExpression; -import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; -import com.sun.tools.javac.tree.JCTree.JCNewClass; -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeMaker; -import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.TreeTranslator; -import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; -import java.util.HashMap; -import java.util.Map; - import static com.sun.tools.javac.code.Flags.PRIVATE; import static com.sun.tools.javac.code.Flags.STATIC; import static com.sun.tools.javac.code.Flags.SYNTHETIC; -import static com.sun.tools.javac.code.Kinds.Kind.MTH; public class TransConstants extends TreeTranslator { @@ -97,45 +84,11 @@ protected TransConstants(Context context) { */ Env attrEnv; - /** A table mapping static local symbols to their desugared counterparts. - */ - Map staticLocalsTable; - ListBuffer pendingClassDefs; - public void visitVarDef(JCVariableDecl tree) { - if (tree.sym.isStatic() && tree.sym.owner.kind == MTH) { - if (isSplittableStaticLocal(tree)) { - splitStaticLocalInit(tree); - } else { - liftStaticLocal(tree); - } - // do not emit the variable declaration - result = make.Skip(); - } else { - super.visitVarDef(tree); - } - } - - @Override - public void visitIdent(JCIdent tree) { - if (staticLocalsTable != null && staticLocalsTable.containsKey(tree.sym)) { - Symbol translatedSym = staticLocalsTable.get(tree.sym); - result = make.Ident(translatedSym); - } else { - super.visitIdent(tree); - } - } - @Override - public void visitMethodDef(JCMethodDecl tree) { - Map prevStaticLocalsTable = staticLocalsTable; - try { - staticLocalsTable = new HashMap<>(); - super.visitMethodDef(tree); - } finally { - staticLocalsTable = prevStaticLocalsTable; - } + public void visitConstExpr(JCConstExpr tree) { + result = splitConstant(tree); } @Override @@ -153,48 +106,21 @@ public void visitClassDef(JCClassDecl tree) { } } - boolean isSplittableStaticLocal(JCVariableDecl tree) { - return tree.sym.isFinal() && - !hasAnonClassDefs(tree); - } - - boolean hasAnonClassDefs(JCTree tree) { - class AnonClassFinder extends TreeScanner { - boolean anonFound; - - @Override - public void visitNewClass(JCNewClass tree) { - if (tree.def != null) { - anonFound = true; - } - super.visitNewClass(tree); - } - - @Override - public void visitClassDef(JCClassDecl tree) { - // do not recurse - } - } - AnonClassFinder anonClassFinder = new AnonClassFinder(); - tree.accept(anonClassFinder); - return anonClassFinder.anonFound; - } - - private void splitStaticLocalInit(JCVariableDecl tree) { - Assert.checkNonNull(tree.init); + private JCExpression splitConstant(JCConstExpr tree) { + Name constName = names.fromString("const") + .append('$', names.fromString(String.valueOf(pendingClassDefs.size()))); // create synthetic init symbol MethodSymbol initSym = new MethodSymbol( STATIC | SYNTHETIC | PRIVATE, - tree.name.append('$', names.fromString("init")), + constName.append('$', names.fromString("init")), new MethodType(List.nil(), tree.type, List.nil(), syms.methodClass), currentClass.sym); - enterSynthetic(tree.pos(), initSym, currentClass.sym.members()); + currentClass.sym.members().enter(initSym); // create synthetic init tree - JCExpression initExpr = translate(tree.init); + JCExpression initExpr = translate(tree.expr); JCMethodDecl initDef = make.MethodDef(initSym, make.Block(0, List.of(make.Return(initExpr)))); pendingClassDefs.add(initDef); - // drop original init - tree.init = null; + List lazyInit_staticArgTypes = List.of(syms.methodHandleLookupType, syms.stringType, syms.classType, @@ -204,43 +130,9 @@ private void splitStaticLocalInit(JCVariableDecl tree) { names.invoke, lazyInit_staticArgTypes, List.nil()); // set a constant value that points to a dynamic symbol, so that Gen can emit the correct ldc - DynamicVarSymbol condySym = new DynamicVarSymbol(tree.name, currentClass.sym, bsm.asHandle(), tree.type, + DynamicVarSymbol condySym = new DynamicVarSymbol(constName, currentClass.sym, bsm.asHandle(), tree.type, new LoadableConstant[] { initSym.asHandle() }); - staticLocalsTable.put(tree.sym, condySym); - } - - private void liftStaticLocal(JCVariableDecl tree) { - Assert.checkNonNull(tree.init); - // create synthetic init symbol - VarSymbol liftedSym = new VarSymbol( - STATIC | SYNTHETIC | PRIVATE, - makeSyntheticName(tree.name.append('$', names.fromString("static")), currentClass.sym.members()), - tree.sym.type, currentClass.sym); - enterSynthetic(tree.pos(), liftedSym, currentClass.sym.members()); - // create synthetic init tree - JCExpression initExpr = translate(tree.init); - JCVariableDecl liftedDecl = make.VarDef(liftedSym, initExpr); - pendingClassDefs.add(liftedDecl); - staticLocalsTable.put(tree.sym, liftedSym); - } - - // copied from Lower - private void enterSynthetic(DiagnosticPosition pos, Symbol sym, WriteableScope s) { - s.enter(sym); - } - - private Name makeSyntheticName(Name name, Scope s) { - do { - name = name.append( - target.syntheticNameChar(), - names.empty); - } while (lookupSynthetic(name, s) != null); - return name; - } - - private Symbol lookupSynthetic(Name name, Scope s) { - Symbol sym = s.findFirst(name); - return (sym==null || (sym.flags()&SYNTHETIC)==0) ? null : sym; + return make.Ident(condySym); } /** Translate a toplevel class and return a list consisting of diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java index 382c47935d353..aab6c9e9650da 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java @@ -401,7 +401,9 @@ void postop() { */ public void emitLdc(LoadableConstant constant) { int od = poolWriter.putConstant(constant); - if (od <= 255) { + if (LoadableConstant.isLongOrDouble(constant)) { + emitop2(ldc2w, od, constant); + } else if (od <= 255) { emitop1(ldc1, od, constant); } else { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java index 2077efc188826..b4d0716920ac1 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java @@ -25,9 +25,12 @@ package com.sun.tools.javac.jvm; +import com.sun.tools.javac.code.Symbol.DynamicVarSymbol; import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.code.Types.UniqueType; +import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant.BasicConstant; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Pair; @@ -117,6 +120,18 @@ public Object poolKey(Types types) { return data; } } + + static boolean isLongOrDouble(LoadableConstant constant) { + return switch (constant) { + case DynamicVarSymbol dynamicVar -> + dynamicVar.type.hasTag(TypeTag.LONG) || + dynamicVar.type.hasTag(TypeTag.DOUBLE); + case BasicConstant bc -> + bc.tag == ClassFile.CONSTANT_Long || + bc.tag == ClassFile.CONSTANT_Double; + default -> false; + }; + } } /** diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index f1f7c439d6371..cca57bb24f32f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -1330,6 +1330,12 @@ protected JCExpression term3() { } } else return illegal(); break; + case CONST: + accept(CONST); + selectExprMode(); + t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec))); + t = toP(F.at(pos).ConstExpr(t)); + break; case LPAREN: if (typeArgs == null && isMode(EXPR)) { ParensResult pres = analyzeParens(); @@ -2818,8 +2824,7 @@ List blockStatement() { case ASSERT: return List.of(parseSimpleStatement()); case MONKEYS_AT: - case FINAL: - case STATIC: { + case FINAL: { dc = token.docComment(); JCModifiers mods = modifiersOpt(); if (isDeclaration()) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java index 8607703ce367e..38237c1b7271d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -225,6 +225,10 @@ public enum Tag { */ PARENS, + /** Constant expressions, of type ConstExpr. + */ + CONSTEXPR, + /** Assignment expressions, of type Assign. */ ASSIGN, @@ -2046,6 +2050,31 @@ public Tag getTag() { } } + /** + * A parenthesized subexpression ( ... ) + */ + public static class JCConstExpr extends JCExpression implements ConstantExpressionTree { + public JCExpression expr; + protected JCConstExpr(JCExpression expr) { + this.expr = expr; + } + @Override + public void accept(Visitor v) { v.visitConstExpr(this); } + + @DefinedBy(Api.COMPILER_TREE) + public Kind getKind() { return Kind.CONSTANT_EXPRESSION; } + @DefinedBy(Api.COMPILER_TREE) + public JCExpression getExpression() { return expr; } + @Override @DefinedBy(Api.COMPILER_TREE) + public R accept(TreeVisitor v, D d) { + return v.visitConstantExpression(this, d); + } + @Override + public Tag getTag() { + return CONSTEXPR; + } + } + /** * A assignment with "=". */ @@ -3569,6 +3598,7 @@ public abstract static class Visitor { public void visitNewArray(JCNewArray that) { visitTree(that); } public void visitLambda(JCLambda that) { visitTree(that); } public void visitParens(JCParens that) { visitTree(that); } + public void visitConstExpr(JCConstExpr that) { visitTree(that); } public void visitAssign(JCAssign that) { visitTree(that); } public void visitAssignop(JCAssignOp that) { visitTree(that); } public void visitUnary(JCUnary that) { visitTree(that); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java index 4d15bb8f9aec2..3b73b47d6ba05 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -356,6 +356,13 @@ public JCTree visitParenthesized(ParenthesizedTree node, P p) { return M.at(t.pos).Parens(expr); } + @DefinedBy(Api.COMPILER_TREE) + public JCTree visitConstantExpression(ConstantExpressionTree node, P p) { + JCConstExpr t = (JCConstExpr) node; + JCExpression expr = copy(t.expr, p); + return M.at(t.pos).ConstExpr(expr); + } + @DefinedBy(Api.COMPILER_TREE) public JCTree visitReturn(ReturnTree node, P p) { JCReturn t = (JCReturn) node; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 7cd0df9295b4b..056999a479d0b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -449,6 +449,12 @@ public JCParens Parens(JCExpression expr) { return tree; } + public JCConstExpr ConstExpr(JCExpression expr) { + JCConstExpr tree = new JCConstExpr(expr); + tree.pos = pos; + return tree; + } + public JCAssign Assign(JCExpression lhs, JCExpression rhs) { JCAssign tree = new JCAssign(lhs, rhs); tree.pos = pos; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java index 2639be58ada45..3817f6d039e1a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java @@ -276,6 +276,10 @@ public void visitParens(JCParens tree) { scan(tree.expr); } + public void visitConstExpr(JCConstExpr tree) { + scan(tree.expr); + } + public void visitAssign(JCAssign tree) { scan(tree.lhs); scan(tree.rhs); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java index a3b7e4fc5d67f..5fd5c3f734b1e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java @@ -324,6 +324,11 @@ public void visitParens(JCParens tree) { result = tree; } + public void visitConstExpr(JCConstExpr tree) { + tree.expr = translate(tree.expr); + result = tree; + } + public void visitAssign(JCAssign tree) { tree.lhs = translate(tree.lhs); tree.rhs = translate(tree.rhs); diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java index 028b3af84bfef..5f20459832428 100644 --- a/test/langtools/tools/javac/records/RecordCompilationTests.java +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java @@ -574,7 +574,7 @@ static U m(String param) { // can't be explicitly static for (String s : List.of("static record RR() { }", "static interface I {}", "static enum E { A }")) { - assertOK("class R { void m() { #S } }".replaceFirst("#S", s)); + assertFail("compiler.err.illegal.start.of.expr", "class R { void m() { #S } }".replaceFirst("#S", s)); } // but static fields can be accessed