Skip to content

Commit

Permalink
8315457: Implement JEP 459: String Templates (Second Preview)
Browse files Browse the repository at this point in the history
Reviewed-by: jlahoda, alanb, vromero
  • Loading branch information
JimLaskey committed Nov 17, 2023
1 parent 5522656 commit 9902d2e
Show file tree
Hide file tree
Showing 16 changed files with 34 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
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;
Expand Down Expand Up @@ -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);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ public enum Feature {
// 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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ public enum Kind {

/**
* Used for instances of {@link StringTemplateTree}.
* @since 21
*/
@PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES, reflective=true)
TEMPLATE(StringTemplateTree.class),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ public interface TreeVisitor<R,P> {
* @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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ public R visitInstanceOf(InstanceOfTree node, P p) {
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code defaultAction}
* @since 21
*/
@Override
@PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES, reflective=true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@ public R visitAnyPattern(AnyPatternTree node, P p) {
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of scanning
* @since 21
*/
@Override
@PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES, reflective=true)
Expand Down
19 changes: 12 additions & 7 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
Original file line number Diff line number Diff line change
Expand Up @@ -5024,12 +5024,11 @@ Type litType(TypeTag tag) {

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<AttrContext> localEnv = env.dup(tree, env.info.dup());

Expand All @@ -5039,10 +5038,16 @@ public void visitStringTemplate(JCStringTemplate tree) {

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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4370,8 +4370,7 @@ public Type checkProcessorType(JCExpression processor, Type resultType, Env<Attr
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,
Expand Down
19 changes: 2 additions & 17 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
Original file line number Diff line number Diff line change
Expand Up @@ -1678,23 +1678,8 @@ public void visitIf(JCIf tree) {

@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<Type> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,12 @@ JCExpression bsmProcessCall() {
}

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)) {
Expand All @@ -265,8 +270,7 @@ boolean isNamedProcessor(Name name) {
}

boolean isLinkageProcessor() {
return processor != null &&
!useValuesList &&
return !useValuesList &&
types.isSubtype(processor.type, syms.linkageType) &&
processor.type.isFinal() &&
TreeInfo.symbol(processor) instanceof VarSymbol varSymbol &&
Expand All @@ -278,7 +282,7 @@ JCExpression visit() {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2488,6 +2488,7 @@ public static class JCStringTemplate extends JCExpression implements StringTempl
public JCExpression processor;
public List<String> fragments;
public List<JCExpression> expressions;
public Type processMethodType;

protected JCStringTemplate(JCExpression processor,
List<String> fragments,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1480,9 +1480,7 @@ public void visitStringTemplate(JCStringTemplate tree) {
try {
JCExpression processor = tree.processor;
print("[");
if (processor != null) {
printExpr(processor);
}
printExpr(processor);
print("]");
print("\"" + tree.fragments.stream().collect(Collectors.joining("\\{}")) + "\"");
print("(");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,11 +548,7 @@ public static int getStartPos(JCTree tree) {
}
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;
Expand Down

1 comment on commit 9902d2e

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.