diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index f026209aba4..f3ea43f17aa 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -46,7 +46,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.RejectedExecutionException; import java.util.stream.Stream; -import jdk.internal.javac.PreviewFeature; import jdk.internal.misc.CarrierThreadLocal; import jdk.internal.module.ServicesCatalog; import jdk.internal.reflect.ConstantPool; @@ -420,19 +419,16 @@ public interface JavaLangAccess { /** * Get the coder for the supplied character. */ - @PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES) long stringConcatCoder(char value); /** * Update lengthCoder for StringBuilder. */ - @PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES) long stringBuilderConcatMix(long lengthCoder, StringBuilder sb); /** * Prepend StringBuilder content. - */ - @PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES) + */ long stringBuilderConcatPrepend(long lengthCoder, byte[] buf, StringBuilder sb); /** diff --git a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java index 75a628310b9..e9a9fdeb138 100644 --- a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java +++ b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java @@ -67,8 +67,7 @@ public @interface PreviewFeature { // not used, but required for interim javac to not warn. VIRTUAL_THREADS, FOREIGN, - - @JEP(number=430, title="String Templates") + @JEP(number=459, title="String Templates", status="Second Preview") STRING_TEMPLATES, @JEP(number=445, title="Unnamed Classes and Instance Main Methods") UNNAMED_CLASSES, 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 e33929b1936..9150c4cf4b0 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 @@ -177,6 +177,7 @@ public interface Tree { /** * Used for instances of {@link StringTemplateTree}. + * @since 21 */ @PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES, reflective=true) TEMPLATE(StringTemplateTree.class), 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 4b73728f55e..d01625ff4b0 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 @@ -264,6 +264,7 @@ public interface TreeVisitor { * @param node the node being visited * @param p a parameter value * @return a result value + * @since 21 */ @PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES, reflective=true) R visitStringTemplate(StringTemplateTree node, P p); 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 0aaf6c8c07d..22a2e479a80 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 @@ -634,6 +634,7 @@ public class SimpleTreeVisitor implements TreeVisitor { * @param node {@inheritDoc} * @param p {@inheritDoc} * @return the result of {@code defaultAction} + * @since 21 */ @Override @PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES, reflective=true) 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 69d23172cf6..fc3a7823914 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 @@ -783,6 +783,7 @@ public class TreeScanner implements TreeVisitor { * @param node {@inheritDoc} * @param p {@inheritDoc} * @return the result of scanning + * @since 21 */ @Override @PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES, reflective=true) 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 189ce74b115..33a751aac7e 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 @@ -5024,12 +5024,11 @@ public class Attr extends JCTree.Visitor { public void visitStringTemplate(JCStringTemplate tree) { JCExpression processor = tree.processor; - Type resultType = syms.stringTemplateType; - - if (processor != null) { - resultType = attribTree(processor, env, new ResultInfo(KindSelector.VAL, Type.noType)); - resultType = chk.checkProcessorType(processor, resultType, env); - } + Type processorType = attribTree(processor, env, new ResultInfo(KindSelector.VAL, Type.noType)); + chk.checkProcessorType(processor, processorType, env); + Type processMethodType = getProcessMethodType(tree, processorType); + tree.processMethodType = processMethodType; + Type resultType = processMethodType.getReturnType(); Env localEnv = env.dup(tree, env.info.dup()); @@ -5039,10 +5038,16 @@ public class Attr extends JCTree.Visitor { tree.type = resultType; result = resultType; - check(tree, resultType, KindSelector.VAL, resultInfo); } + private Type getProcessMethodType(JCStringTemplate tree, Type processorType) { + MethodSymbol processSymbol = rs.resolveInternalMethod(tree.pos(), + env, types.skipTypeVars(processorType, false), + names.process, List.of(syms.stringTemplateType), List.nil()); + return types.memberType(processorType, processSymbol); + } + public void visitTypeIdent(JCPrimitiveTypeTree tree) { result = check(tree, syms.typeOfTag[tree.typetag.ordinal()], KindSelector.TYP, resultInfo); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index d92a8807542..d05d5e2f510 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -4370,8 +4370,7 @@ public class Check { if (typeArguments.size() == 2) { resultType = typeArguments.head; } else { - log.error(DiagnosticFlag.RESOLVE_ERROR, processor.pos, - Errors.ProcessorTypeCannotBeARawType(processorType.tsym)); + resultType = syms.objectType; } } else { log.error(DiagnosticFlag.RESOLVE_ERROR, processor.pos, diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index 2fe5183bb11..4a23bda0ea8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1678,23 +1678,8 @@ public class Flow { @Override public void visitStringTemplate(JCStringTemplate tree) { - JCExpression processor = tree.processor; - - if (processor != null) { - scan(processor); - Type interfaceType = types.asSuper(processor.type, syms.processorType.tsym); - - if (interfaceType != null) { - List typeArguments = interfaceType.getTypeArguments(); - - if (typeArguments.size() == 2) { - Type throwType = typeArguments.tail.head; - - if (throwType != null) { - markThrown(tree, throwType); - } - } - } + for (Type thrown : tree.processMethodType.getThrownTypes()) { + markThrown(tree, thrown); } scan(tree.expressions); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransLiterals.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransLiterals.java index 2ec6ef206a8..fef3a6c0526 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransLiterals.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransLiterals.java @@ -254,7 +254,12 @@ public final class TransLiterals extends TreeTranslator { } boolean isNamedProcessor(Name name) { - if (processor instanceof JCIdent ident && ident.sym instanceof VarSymbol varSym) { + Symbol sym = switch (processor) { + case JCIdent ident -> ident.sym; + case JCFieldAccess access -> access.sym; + default -> null; + }; + if (sym instanceof VarSymbol varSym) { if (varSym.flags() == (Flags.PUBLIC | Flags.FINAL | Flags.STATIC) && varSym.name == name && types.isSameType(varSym.owner.type, syms.stringTemplateType)) { @@ -265,8 +270,7 @@ public final class TransLiterals extends TreeTranslator { } boolean isLinkageProcessor() { - return processor != null && - !useValuesList && + return !useValuesList && types.isSubtype(processor.type, syms.linkageType) && processor.type.isFinal() && TreeInfo.symbol(processor) instanceof VarSymbol varSymbol && @@ -278,7 +282,7 @@ public final class TransLiterals extends TreeTranslator { JCExpression result; make.at(tree.pos); - if (processor == null || isNamedProcessor(names.RAW)) { + if (isNamedProcessor(names.RAW)) { result = newStringTemplate(); } else if (isNamedProcessor(names.STR)) { result = concatExpression(fragments, expressions); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index d378c9fae10..b485370da27 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1354,10 +1354,6 @@ compiler.err.text.block.template.is.not.well.formed=\ compiler.err.processor.missing.from.string.template.expression=\ processor missing from string template expression -# 0: symbol -compiler.err.processor.type.cannot.be.a.raw.type=\ - processor type cannot be a raw type: {0} - # 0: symbol compiler.err.not.a.processor.type=\ not a processor type: {0} 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 8607703ce36..fcb73c59686 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 @@ -2488,6 +2488,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public JCExpression processor; public List fragments; public List expressions; + public Type processMethodType; protected JCStringTemplate(JCExpression processor, List fragments, diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java index 7398b5ea384..06a8f6f143f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -1480,9 +1480,7 @@ public class Pretty extends JCTree.Visitor { try { JCExpression processor = tree.processor; print("["); - if (processor != null) { - printExpr(processor); - } + printExpr(processor); print("]"); print("\"" + tree.fragments.stream().collect(Collectors.joining("\\{}")) + "\""); print("("); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 40dc8042a06..13932560434 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -548,11 +548,7 @@ public class TreeInfo { } case STRING_TEMPLATE: { JCStringTemplate node = (JCStringTemplate) tree; - if (node.processor == null) { - return node.pos; - } else { - return getStartPos(node.processor); - } + return node.processor == null ? node.pos : getStartPos(node.processor); } case ERRONEOUS: { JCErroneous node = (JCErroneous)tree; diff --git a/test/langtools/tools/javac/diags/examples/StringTemplateNotProcessor.java b/test/langtools/tools/javac/diags/examples/StringTemplateNotProcessor.java index 8f7a75409ff..cd71f7df7e1 100644 --- a/test/langtools/tools/javac/diags/examples/StringTemplateNotProcessor.java +++ b/test/langtools/tools/javac/diags/examples/StringTemplateNotProcessor.java @@ -22,6 +22,8 @@ */ // key: compiler.note.preview.filename + // key: compiler.err.cant.resolve.location.args + // key: compiler.misc.location // key: compiler.note.preview.recompile // key: compiler.err.not.a.processor.type // options: --enable-preview -source ${jdk.version} diff --git a/test/langtools/tools/javac/diags/examples/StringTemplateRawProcessor.java b/test/langtools/tools/javac/diags/examples/StringTemplateRawProcessor.java index c6205fbb4f2..9ab344fb021 100644 --- a/test/langtools/tools/javac/diags/examples/StringTemplateRawProcessor.java +++ b/test/langtools/tools/javac/diags/examples/StringTemplateRawProcessor.java @@ -25,7 +25,6 @@ // key: compiler.note.preview.recompile // key: compiler.misc.unexpected.ret.val // key: compiler.err.prob.found.req - // key: compiler.err.processor.type.cannot.be.a.raw.type // options: --enable-preview -source ${jdk.version} import java.lang.*;