changeset 33712 | fd1ce6d7ac63 |
parent 33710 | acb12d30a5ac |
child 33916 | 9b8030e8e0d9 |
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Nov 12 05:59:47 2015 +0530 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Nov 12 06:13:14 2015 +0530 @@ -55,12 +55,16 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; + +import javax.lang.model.element.ElementKind; import javax.lang.model.type.TypeKind; /** @@ -268,21 +272,34 @@ MethodSymbol sym = localContext.translatedSym; MethodType lambdaType = (MethodType) sym.type; - { + { /* Type annotation management: Based on where the lambda features, type annotations that + are interior to it, may at this point be attached to the enclosing method, or the first + constructor in the class, or in the enclosing class symbol or in the field whose + initializer is the lambda. In any event, gather up the annotations that belong to the + lambda and attach it to the implementation method. + */ + Symbol owner = localContext.owner; - ListBuffer<Attribute.TypeCompound> ownerTypeAnnos = new ListBuffer<>(); - ListBuffer<Attribute.TypeCompound> lambdaTypeAnnos = new ListBuffer<>(); + apportionTypeAnnotations(tree, + owner::getRawTypeAttributes, + owner::setTypeAttributes, + sym::setTypeAttributes); + - for (Attribute.TypeCompound tc : owner.getRawTypeAttributes()) { - if (tc.position.onLambda == tree) { - lambdaTypeAnnos.append(tc); - } else { - ownerTypeAnnos.append(tc); - } + boolean init; + if ((init = (owner.name == names.init)) || owner.name == names.clinit) { + owner = owner.owner; + apportionTypeAnnotations(tree, + init ? owner::getInitTypeAttributes : owner::getClassInitTypeAttributes, + init ? owner::setInitTypeAttributes : owner::setClassInitTypeAttributes, + sym::appendUniqueTypeAttributes); } - if (lambdaTypeAnnos.nonEmpty()) { - owner.setTypeAttributes(ownerTypeAnnos.toList()); - sym.setTypeAttributes(lambdaTypeAnnos.toList()); + if (localContext.self != null && localContext.self.getKind() == ElementKind.FIELD) { + owner = localContext.self; + apportionTypeAnnotations(tree, + owner::getRawTypeAttributes, + owner::setTypeAttributes, + sym::appendUniqueTypeAttributes); } } @@ -354,6 +371,29 @@ result = makeMetafactoryIndyCall(context, refKind, sym, indy_args); } + // where + // Reassign type annotations from the source that should really belong to the lambda + private void apportionTypeAnnotations(JCLambda tree, + Supplier<List<Attribute.TypeCompound>> source, + Consumer<List<Attribute.TypeCompound>> owner, + Consumer<List<Attribute.TypeCompound>> lambda) { + + ListBuffer<Attribute.TypeCompound> ownerTypeAnnos = new ListBuffer<>(); + ListBuffer<Attribute.TypeCompound> lambdaTypeAnnos = new ListBuffer<>(); + + for (Attribute.TypeCompound tc : source.get()) { + if (tc.position.onLambda == tree) { + lambdaTypeAnnos.append(tc); + } else { + ownerTypeAnnos.append(tc); + } + } + if (lambdaTypeAnnos.nonEmpty()) { + owner.accept(ownerTypeAnnos.toList()); + lambda.accept(lambdaTypeAnnos.toList()); + } + } + private JCIdent makeThis(Type type, Symbol owner) { VarSymbol _this = new VarSymbol(PARAMETER | FINAL | SYNTHETIC, names._this,