< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java

Print this page

        

*** 23,37 **** * questions. */ package com.sun.tools.javac.comp; - import com.sun.tools.javac.code.Symbol.MethodHandleSymbol; import com.sun.tools.javac.code.Types.SignatureGenerator.InvalidSignatureException; - import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator; --- 23,36 ---- * questions. */ package com.sun.tools.javac.comp; import com.sun.tools.javac.code.Types.SignatureGenerator.InvalidSignatureException; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.Fragments; + import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator;
*** 59,83 **** --- 58,88 ---- import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; + import java.util.Objects; import java.util.Optional; 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 static com.sun.tools.javac.jvm.Pool.DynamicMethod; import javax.lang.model.element.ElementKind; import javax.lang.model.type.TypeKind; + import com.sun.tools.javac.code.Type.IntersectionClassType; + import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError; import com.sun.tools.javac.main.Option; + import com.sun.tools.javac.code.Source; + import com.sun.tools.javac.code.Symbol.DynamicVarSymbol; /** * This pass desugars lambda expressions into static methods * * <p><b>This is NOT part of any supported API.
*** 166,175 **** --- 171,186 ---- debugLinesOrVars = options.isSet(Option.G) || options.isSet(Option.G_CUSTOM, "lines") || options.isSet(Option.G_CUSTOM, "vars"); verboseDeduplication = options.isSet("debug.dumpLambdaToMethodDeduplication"); deduplicateLambdas = options.getBoolean("deduplicateLambdas", true); + Source source = Source.instance(context); + // format: -XDforNonCapturingLambda=generateCondy, which is the default, or -XDforNonCapturingLambda=generateIndy + String condyOp = options.get("forNonCapturingLambda"); + condyForLambda = condyOp != null ? + condyOp.equals("generateCondy") : + Feature.CONDY_FOR_LAMBDA.allowedInSource(source); } // </editor-fold> class DedupedLambda { private final MethodSymbol symbol;
*** 210,220 **** */ private ListBuffer<JCTree> appendedMethodList; private Map<DedupedLambda, DedupedLambda> dedupedLambdas; ! private Map<Object, DynamicMethodSymbol> dynMethSyms = new HashMap<>(); /** * list of deserialization cases */ private final Map<String, ListBuffer<JCStatement>> deserializeCases; --- 221,231 ---- */ private ListBuffer<JCTree> appendedMethodList; private Map<DedupedLambda, DedupedLambda> dedupedLambdas; ! private Map<DynamicMethod, DynamicMethodSymbol> dynMethSyms = new HashMap<>(); /** * list of deserialization cases */ private final Map<String, ListBuffer<JCStatement>> deserializeCases;
*** 435,446 **** } //then, determine the arguments to the indy call List<JCExpression> indy_args = translate(syntheticInits.toList(), localContext.prev); //convert to an invokedynamic call ! result = makeMetafactoryIndyCall(context, sym.asHandle(), indy_args); } // where // Reassign type annotations from the source that should really belong to the lambda private void apportionTypeAnnotations(JCLambda tree, --- 446,460 ---- } //then, determine the arguments to the indy call List<JCExpression> indy_args = translate(syntheticInits.toList(), localContext.prev); + //build a sam instance using an indy call to the meta-factory + int refKind = referenceKind(sym); + //convert to an invokedynamic call ! 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,
*** 481,491 **** public void visitReference(JCMemberReference tree) { ReferenceTranslationContext localContext = (ReferenceTranslationContext)context; //first determine the method symbol to be used to generate the sam instance //this is either the method reference symbol, or the bridged reference symbol ! MethodSymbol refSym = (MethodSymbol)tree.sym; //the qualifying expression is treated as a special captured arg JCExpression init; switch(tree.kind) { --- 495,505 ---- public void visitReference(JCMemberReference tree) { ReferenceTranslationContext localContext = (ReferenceTranslationContext)context; //first determine the method symbol to be used to generate the sam instance //this is either the method reference symbol, or the bridged reference symbol ! Symbol refSym = tree.sym; //the qualifying expression is treated as a special captured arg JCExpression init; switch(tree.kind) {
*** 515,525 **** List<JCExpression> indy_args = init==null? List.nil() : translate(List.of(init), localContext.prev); //build a sam instance using an indy call to the meta-factory ! result = makeMetafactoryIndyCall(localContext, refSym.asHandle(), indy_args); } /** * Translate identifiers within a lambda to the mapped identifier * @param tree --- 529,539 ---- List<JCExpression> indy_args = init==null? List.nil() : translate(List.of(init), localContext.prev); //build a sam instance using an indy call to the meta-factory ! result = makeMetafactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args); } /** * Translate identifiers within a lambda to the mapped identifier * @param tree
*** 601,610 **** --- 615,639 ---- LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context; if (context != null && lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) { tree.init = translate(tree.init); tree.sym = (VarSymbol) lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym); result = tree; + } else if (context != null && lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) { + JCExpression init = translate(tree.init); + VarSymbol xsym = (VarSymbol)lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym); + int prevPos = make.pos; + try { + result = make.at(tree).VarDef(xsym, init); + } finally { + make.at(prevPos); + } + // Replace the entered symbol for this variable + WriteableScope sc = tree.sym.owner.members(); + if (sc != null) { + sc.remove(tree.sym); + sc.enter(xsym); + } } else { super.visitVarDef(tree); } }
*** 743,763 **** JCNewClass makeNewClass(Type ctype, List<JCExpression> args) { return makeNewClass(ctype, args, rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.nil())); } ! private void addDeserializationCase(MethodHandleSymbol refSym, Type targetType, MethodSymbol samSym, ! DiagnosticPosition pos, List<LoadableConstant> staticArgs, MethodType indyType) { String functionalInterfaceClass = classSig(targetType); String functionalInterfaceMethodName = samSym.getSimpleName().toString(); String functionalInterfaceMethodSignature = typeSig(types.erasure(samSym.type)); String implClass = classSig(types.erasure(refSym.owner.type)); String implMethodName = refSym.getQualifiedName().toString(); String implMethodSignature = typeSig(types.erasure(refSym.type)); ! JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), ! make.Literal(refSym.referenceKind())); ListBuffer<JCExpression> serArgs = new ListBuffer<>(); int i = 0; for (Type t : indyType.getParameterTypes()) { List<JCExpression> indexAsArg = new ListBuffer<JCExpression>().append(make.Literal(i)).toList(); List<Type> argTypes = new ListBuffer<Type>().append(syms.intType).toList(); --- 772,791 ---- JCNewClass makeNewClass(Type ctype, List<JCExpression> args) { return makeNewClass(ctype, args, rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.nil())); } ! private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym, ! DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) { String functionalInterfaceClass = classSig(targetType); String functionalInterfaceMethodName = samSym.getSimpleName().toString(); String functionalInterfaceMethodSignature = typeSig(types.erasure(samSym.type)); String implClass = classSig(types.erasure(refSym.owner.type)); String implMethodName = refSym.getQualifiedName().toString(); String implMethodSignature = typeSig(types.erasure(refSym.type)); ! JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), make.Literal(implMethodKind)); ListBuffer<JCExpression> serArgs = new ListBuffer<>(); int i = 0; for (Type t : indyType.getParameterTypes()) { List<JCExpression> indexAsArg = new ListBuffer<JCExpression>().append(make.Literal(i)).toList(); List<Type> argTypes = new ListBuffer<Type>().append(syms.intType).toList();
*** 770,784 **** "getFunctionalInterfaceClass", functionalInterfaceClass), "getFunctionalInterfaceMethodName", functionalInterfaceMethodName), "getFunctionalInterfaceMethodSignature", functionalInterfaceMethodSignature), "getImplClass", implClass), "getImplMethodSignature", implMethodSignature), ! make.Return(makeIndyCall( pos, syms.lambdaMetafactory, names.altMetafactory, ! staticArgs, indyType, serArgs.toList(), samSym.name)), null); ListBuffer<JCStatement> stmts = kInfo.deserializeCases.get(implMethodName); if (stmts == null) { stmts = new ListBuffer<>(); kInfo.deserializeCases.put(implMethodName, stmts); --- 798,812 ---- "getFunctionalInterfaceClass", functionalInterfaceClass), "getFunctionalInterfaceMethodName", functionalInterfaceMethodName), "getFunctionalInterfaceMethodSignature", functionalInterfaceMethodSignature), "getImplClass", implClass), "getImplMethodSignature", implMethodSignature), ! make.Return(makeDynamicCall( pos, syms.lambdaMetafactory, names.altMetafactory, ! staticArgs, targetType, indyType, serArgs.toList(), samSym.name)), null); ListBuffer<JCStatement> stmts = kInfo.deserializeCases.get(implMethodName); if (stmts == null) { stmts = new ListBuffer<>(); kInfo.deserializeCases.put(implMethodName, stmts);
*** 1085,1101 **** /** * Generate an indy method call to the meta factory */ private JCExpression makeMetafactoryIndyCall(TranslationContext<?> context, ! MethodHandleSymbol refSym, List<JCExpression> indy_args) { JCFunctionalExpression tree = context.tree; //determine the static bsm args MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.target.tsym); ! List<LoadableConstant> staticArgs = List.of( typeToMethodType(samSym.type), ! ((MethodSymbol)refSym).asHandle(), typeToMethodType(tree.getDescriptorType(types))); //computed indy arg types ListBuffer<Type> indy_args_types = new ListBuffer<>(); for (JCExpression arg : indy_args) { --- 1113,1129 ---- /** * Generate an indy method call to the meta factory */ private JCExpression makeMetafactoryIndyCall(TranslationContext<?> context, ! int refKind, Symbol refSym, List<JCExpression> indy_args) { JCFunctionalExpression tree = context.tree; //determine the static bsm args MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.target.tsym); ! List<Object> staticArgs = List.of( typeToMethodType(samSym.type), ! new Pool.MethodHandle(refKind, refSym, types), typeToMethodType(tree.getDescriptorType(types))); //computed indy arg types ListBuffer<Type> indy_args_types = new ListBuffer<>(); for (JCExpression arg : indy_args) {
*** 1110,1129 **** Name metafactoryName = context.needsAltMetafactory() ? names.altMetafactory : names.metafactory; if (context.needsAltMetafactory()) { ! ListBuffer<Type> markers = new ListBuffer<>(); List<Type> targets = tree.target.isIntersection() ? types.directSupertypes(tree.target) : List.nil(); for (Type t : targets) { t = types.erasure(t); if (t.tsym != syms.serializableType.tsym && t.tsym != tree.type.tsym && t.tsym != syms.objectType.tsym) { ! markers.append(t); } } int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0; boolean hasMarkers = markers.nonEmpty(); boolean hasBridges = context.bridges.nonEmpty(); --- 1138,1157 ---- Name metafactoryName = context.needsAltMetafactory() ? names.altMetafactory : names.metafactory; if (context.needsAltMetafactory()) { ! ListBuffer<Object> markers = new ListBuffer<>(); List<Type> targets = tree.target.isIntersection() ? types.directSupertypes(tree.target) : List.nil(); for (Type t : targets) { t = types.erasure(t); if (t.tsym != syms.serializableType.tsym && t.tsym != tree.type.tsym && t.tsym != syms.objectType.tsym) { ! markers.append(t.tsym); } } int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0; boolean hasMarkers = markers.nonEmpty(); boolean hasBridges = context.bridges.nonEmpty();
*** 1131,1205 **** flags |= FLAG_MARKERS; } if (hasBridges) { flags |= FLAG_BRIDGES; } ! staticArgs = staticArgs.append(LoadableConstant.Int(flags)); if (hasMarkers) { ! staticArgs = staticArgs.append(LoadableConstant.Int(markers.length())); ! staticArgs = staticArgs.appendList(List.convert(LoadableConstant.class, markers.toList())); } if (hasBridges) { ! staticArgs = staticArgs.append(LoadableConstant.Int(context.bridges.length() - 1)); for (Symbol s : context.bridges) { Type s_erasure = s.erasure(types); if (!types.isSameType(s_erasure, samSym.erasure(types))) { ! staticArgs = staticArgs.append(((MethodType)s.erasure(types))); } } } if (context.isSerializable()) { int prevPos = make.pos; try { make.at(kInfo.clazz); ! addDeserializationCase(refSym, tree.type, samSym, tree, staticArgs, indyType); } finally { make.at(prevPos); } } } ! return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args, samSym.name); } /** * Generate an indy method call with given name, type and static bootstrap * arguments types */ private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName, ! List<LoadableConstant> staticArgs, MethodType indyType, List<JCExpression> indyArgs, ! Name methName) { int prevPos = make.pos; try { make.at(pos); ! List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType, ! syms.stringType, ! syms.methodTypeType).appendList(staticArgs.map(types::constantType)); Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site, bsmName, bsm_staticArgs, List.nil()); DynamicMethodSymbol dynSym = new DynamicMethodSymbol(methName, syms.noSymbol, ! ((MethodSymbol)bsm).asHandle(), indyType, ! staticArgs.toArray(new LoadableConstant[staticArgs.length()])); JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName); DynamicMethodSymbol existing = kInfo.dynMethSyms.putIfAbsent( ! dynSym.poolKey(types), dynSym); qualifier.sym = existing != null ? existing : dynSym; qualifier.type = indyType.getReturnType(); JCMethodInvocation proxyCall = make.Apply(List.nil(), qualifier, indyArgs); proxyCall.type = indyType.getReturnType(); return proxyCall; } finally { make.at(prevPos); } } // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer"> /** * This visitor collects information about translation of a lambda expression. * More specifically, it keeps track of the enclosing contexts and captured locals --- 1159,1333 ---- flags |= FLAG_MARKERS; } if (hasBridges) { flags |= FLAG_BRIDGES; } ! staticArgs = staticArgs.append(flags); if (hasMarkers) { ! staticArgs = staticArgs.append(markers.length()); ! staticArgs = staticArgs.appendList(markers.toList()); } if (hasBridges) { ! staticArgs = staticArgs.append(context.bridges.length() - 1); for (Symbol s : context.bridges) { Type s_erasure = s.erasure(types); if (!types.isSameType(s_erasure, samSym.erasure(types))) { ! staticArgs = staticArgs.append(s.erasure(types)); } } } if (context.isSerializable()) { int prevPos = make.pos; try { make.at(kInfo.clazz); ! addDeserializationCase(refKind, refSym, tree.type, samSym, tree, staticArgs, indyType); } finally { make.at(prevPos); } } } ! return makeDynamicCall(tree, syms.lambdaMetafactory, ! metafactoryName, staticArgs, tree.type, indyType, indy_args, samSym.name); ! } ! ! private JCExpression makeDynamicCall(DiagnosticPosition pos, Type site, Name bsmName, ! List<Object> staticArgs, Type interfaceType, MethodType indyType, List<JCExpression> indyArgs, ! Name methName) { ! return condyForLambda && ! !context.needsAltMetafactory() && ! indyArgs.isEmpty() ? ! makeCondy(pos, site, bsmName, staticArgs, interfaceType, methName) : ! makeIndyCall(pos, site, bsmName, staticArgs, indyType, indyArgs, methName); ! } ! ! /* this extra flag should be temporary and used as long as it's not possible to do the build ! * due to the lack of support for condy in the current version of ASM present in the build ! */ ! private final boolean condyForLambda; ! ! private JCExpression makeCondy(DiagnosticPosition pos, Type site, Name bsmName, ! List<Object> staticArgs, Type interfaceType, Name methName) { ! int prevPos = make.pos; ! try { ! make.at(pos); ! List<Type> bsm_staticArgs = List.of(syms.methodHandlesLookupType, ! syms.stringType, ! syms.classType).appendList(bsmStaticArgToTypes(staticArgs)); ! ! Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site, ! bsmName, bsm_staticArgs, List.nil()); ! ! DynamicVarSymbol dynSym = new DynamicVarSymbol(methName, ! syms.noSymbol, ! bsm.isStatic() ? ! ClassFile.REF_invokeStatic : ! ClassFile.REF_invokeVirtual, ! (MethodSymbol)bsm, ! interfaceType, ! staticArgs.toArray()); ! ! JCIdent ident = make.Ident(dynSym); ! ident.type = interfaceType; ! ! return ident; ! } finally { ! make.at(prevPos); ! } } /** * Generate an indy method call with given name, type and static bootstrap * arguments types */ private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName, ! List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs, ! Name methName) { int prevPos = make.pos; try { make.at(pos); ! List<Type> bsm_staticArgs = List.of(syms.methodHandlesLookupType, ! syms.stringType, ! syms.methodTypeType).appendList(bsmStaticArgToTypes(staticArgs)); Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site, bsmName, bsm_staticArgs, List.nil()); DynamicMethodSymbol dynSym = new DynamicMethodSymbol(methName, syms.noSymbol, ! bsm.isStatic() ? ! ClassFile.REF_invokeStatic : ! ClassFile.REF_invokeVirtual, ! (MethodSymbol)bsm, indyType, ! staticArgs.toArray()); JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName); DynamicMethodSymbol existing = kInfo.dynMethSyms.putIfAbsent( ! new DynamicMethod(dynSym, types), dynSym); qualifier.sym = existing != null ? existing : dynSym; qualifier.type = indyType.getReturnType(); JCMethodInvocation proxyCall = make.Apply(List.nil(), qualifier, indyArgs); proxyCall.type = indyType.getReturnType(); return proxyCall; } finally { make.at(prevPos); } } + //where + private List<Type> bsmStaticArgToTypes(List<Object> args) { + ListBuffer<Type> argtypes = new ListBuffer<>(); + for (Object arg : args) { + argtypes.append(bsmStaticArgToType(arg)); + } + return argtypes.toList(); + } + + private Type bsmStaticArgToType(Object arg) { + Assert.checkNonNull(arg); + if (arg instanceof ClassSymbol) { + return syms.classType; + } else if (arg instanceof Integer) { + return syms.intType; + } else if (arg instanceof Long) { + return syms.longType; + } else if (arg instanceof Float) { + return syms.floatType; + } else if (arg instanceof Double) { + return syms.doubleType; + } else if (arg instanceof String) { + return syms.stringType; + } else if (arg instanceof Pool.MethodHandle) { + return syms.methodHandleType; + } else if (arg instanceof MethodType) { + return syms.methodTypeType; + } else { + Assert.error("bad static arg " + arg.getClass()); + return null; + } + } + + /** + * Get the opcode associated with this method reference + */ + private int referenceKind(Symbol refSym) { + if (refSym.isConstructor()) { + return ClassFile.REF_newInvokeSpecial; + } else { + if (refSym.isStatic()) { + return ClassFile.REF_invokeStatic; + } else if ((refSym.flags() & PRIVATE) != 0) { + return ClassFile.REF_invokeSpecial; + } else if (refSym.enclClass().isInterface()) { + return ClassFile.REF_invokeInterface; + } else { + return ClassFile.REF_invokeVirtual; + } + } + } // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer"> /** * This visitor collects information about translation of a lambda expression. * More specifically, it keeps track of the enclosing contexts and captured locals
*** 1555,1564 **** --- 1683,1695 ---- ltc.addSymbol(tree.sym, LOCAL_VAR); } // Check for type variables (including as type arguments). // If they occur within class nested in a lambda, mark for erasure Type type = tree.sym.asType(); + if (inClassWithinLambda() && !types.isSameType(types.erasure(type), type)) { + ltc.addSymbol(tree.sym, TYPE_VAR); + } } List<Frame> prevStack = frameStack; try { if (tree.sym.owner.kind == MTH) {
*** 1924,1951 **** assignedTo = self = null; break; } // This symbol will be filled-in in complete ! if (owner.kind == MTH) { ! final MethodSymbol originalOwner = (MethodSymbol)owner.clone(owner.owner); ! this.translatedSym = new MethodSymbol(SYNTHETIC | PRIVATE, null, null, owner.enclClass()) { ! @Override ! public MethodSymbol originalEnclosingMethod() { ! return originalOwner; ! } ! }; ! } else { ! this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass()); ! } translatedSymbols = new EnumMap<>(LambdaSymbolKind.class); translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(LOCAL_VAR, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(CAPTURED_OUTER_THIS, new LinkedHashMap<Symbol, Symbol>()); freeVarProcessedLocalClasses = new HashSet<>(); } /** --- 2055,2074 ---- assignedTo = self = null; break; } // This symbol will be filled-in in complete ! this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass()); ! translatedSymbols = new EnumMap<>(LambdaSymbolKind.class); translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(LOCAL_VAR, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>()); translatedSymbols.put(CAPTURED_OUTER_THIS, new LinkedHashMap<Symbol, Symbol>()); + translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>()); freeVarProcessedLocalClasses = new HashSet<>(); } /**
*** 2034,2043 **** --- 2157,2176 ---- Symbol ret; switch (skind) { case CAPTURED_THIS: ret = sym; // self represented break; + case TYPE_VAR: + // Just erase the type var + ret = new VarSymbol(sym.flags(), sym.name, + types.erasure(sym.type), sym.owner); + + /* this information should also be kept for LVT generation at Gen + * a Symbol with pos < startPos won't be tracked. + */ + ((VarSymbol)ret).pos = ((VarSymbol)sym).pos; + break; case CAPTURED_VAR: ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, sym.name, types.erasure(sym.type), translatedSym) { @Override public Symbol baseSymbol() { //keep mapping with original captured symbol
*** 2232,2241 **** --- 2365,2381 ---- ReferenceTranslationContext(JCMemberReference tree) { super(tree); this.isSuper = tree.hasKind(ReferenceKind.SUPER); } + /** + * Get the opcode associated with this method reference + */ + int referenceKind() { + return LambdaToMethod.this.referenceKind(tree.sym); + } + boolean needsVarArgsConversion() { return tree.varargsElement != null; } /**
*** 2330,2340 **** enum LambdaSymbolKind { PARAM, // original to translated lambda parameters LOCAL_VAR, // original to translated lambda locals CAPTURED_VAR, // variables in enclosing scope to translated synthetic parameters CAPTURED_THIS, // class symbols to translated synthetic parameters (for captured member access) ! CAPTURED_OUTER_THIS; // used when `this' capture is illegal, but outer this capture is legit (JDK-8129740) boolean propagateAnnotations() { switch (this) { case CAPTURED_VAR: case CAPTURED_THIS: --- 2470,2481 ---- enum LambdaSymbolKind { PARAM, // original to translated lambda parameters LOCAL_VAR, // original to translated lambda locals CAPTURED_VAR, // variables in enclosing scope to translated synthetic parameters CAPTURED_THIS, // class symbols to translated synthetic parameters (for captured member access) ! CAPTURED_OUTER_THIS, // used when `this' capture is illegal, but outer this capture is legit (JDK-8129740) ! TYPE_VAR; // original to translated lambda type variables boolean propagateAnnotations() { switch (this) { case CAPTURED_VAR: case CAPTURED_THIS:
< prev index next >