src/share/classes/com/sun/tools/javac/comp/Attr.java

Print this page

        

*** 24,34 **** */ package com.sun.tools.javac.comp; import java.util.*; - import java.util.Set; import javax.lang.model.element.ElementKind; import javax.tools.JavaFileObject; import com.sun.tools.javac.code.*; import com.sun.tools.javac.jvm.*; --- 24,33 ----
*** 79,88 **** --- 78,88 ---- final Enter enter; final Target target; final Types types; final JCDiagnostic.Factory diags; final Annotate annotate; + final LambdaFlow lambdaFlow; public static Attr instance(Context context) { Attr instance = context.get(attrKey); if (instance == null) instance = new Attr(context);
*** 103,112 **** --- 103,113 ---- cfolder = ConstFold.instance(context); target = Target.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); annotate = Annotate.instance(context); + lambdaFlow = LambdaFlow.instance(context); Options options = Options.instance(context); Source source = Source.instance(context); allowGenerics = source.allowGenerics();
*** 644,654 **** // If we override any other methods, check that we do so properly. // JLS ??? chk.checkOverride(tree, m); ! // Create a new environment with local scope // for attributing the method. Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env); localEnv.info.lint = lint; --- 645,655 ---- // If we override any other methods, check that we do so properly. // JLS ??? chk.checkOverride(tree, m); ! // Create fresh environment with local scope // for attributing the method. Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env); localEnv.info.lint = lint;
*** 2085,2094 **** --- 2086,2108 ---- sym = rs.access(sym, pos, site, name, true); return sym; } case WILDCARD: throw new AssertionError(tree); + case FUNCTION: + if (name == names.invoke) { + MethodType mType = (MethodType) site; + // method invoke is a method + MethodType methodInvoke = new MethodType(METHOD, + mType.argtypes, + mType.restype, + List.<Type>nil(), + syms.methodClass); + return new MethodSymbol(PUBLIC | ABSTRACT, name, methodInvoke, syms.methodHandleType.tsym); + } + return rs.resolveQualifiedMethod( + pos, env, syms.methodHandleType, name, pt.getParameterTypes(), pt.getTypeArguments()); case TYPEVAR: // Normally, site.getUpperBound() shouldn't be null. // It should only happen during memberEnter/attribBase // when determining the super type which *must* be // done before attributing the type variables. In
*** 2120,2129 **** --- 2134,2146 ---- Type arg = types.boxedClass(site).type; t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym); return new VarSymbol( STATIC | PUBLIC | FINAL, names._class, t, site.tsym); } else { + new Throwable().printStackTrace(); + System.out.println("cant deref "+site+" "+site.tag+" "+METHOD); + log.error(pos, "cant.deref", site); return syms.errSymbol; } } }
*** 2696,2705 **** --- 2713,2824 ---- tree.kind.kind, syms.boundClass), TYP, pkind, pt); } + @Override + public void visitFunctionType(JCFunctionType tree) { + JCExpression returnTypeExpr = tree.returnType; + Type returnType = attribType(returnTypeExpr, env); + returnTypeExpr.type = returnType; + + ListBuffer<Type> parameterTypes = ListBuffer.lb(); + for (List<JCExpression> l = tree.parameterTypes; l.nonEmpty(); l = l.tail) { + JCExpression typeExpr = l.head; + Type type = chk.checkNonVoid(typeExpr.pos(), attribType(typeExpr, env)); + typeExpr.type = type; + parameterTypes.append(type); + } + + result = tree.type = new MethodType(FUNCTION, + parameterTypes.toList(), + returnType, + List.<Type>nil(), + syms.methodClass); + } + + @Override + public void visitLambda(JCLambda tree) { + long flags = Flags.LAMBDA; + if ((env.enclMethod.mods.flags & STATIC) !=0) { + flags |= STATIC; + } + + MethodSymbol m = new MethodSymbol(flags, null, null, env.enclClass.sym); + tree.sym = m; + + // create a fake method + JCBlock body; + if (tree.bodyOrExpr.getTag() == JCTree.BLOCK) { + body = (JCBlock) tree.bodyOrExpr; + } else { + JCReturn _return = make.Return((JCExpression)tree.bodyOrExpr); + body = make.Block(0, List.<JCStatement>of(_return)); + } + JCMethodDecl method = make.MethodDef( + make.Modifiers(m.flags()), + null, + null, + List.<JCTypeParameter>nil(), + tree.parameters, + null, + List.<JCExpression>nil(), + body, + null); + method.sym = m; + + Lint lint = env.info.lint.augment(List.<Attribute.Compound>nil(), flags); + Lint prevLint = chk.setLint(lint); + try { + // Create a new environment with a new scope + // for attributing the fake method. + Env<AttrContext> localEnv = memberEnter.methodEnv(method, env); + localEnv.info.lint = lint; + + // enter parameter symbol and attribute them + ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>(); + ListBuffer<Type> paramTypes = new ListBuffer<Type>(); + for (List<JCVariableDecl> l = method.params; l.nonEmpty(); l = l.tail) { + JCVariableDecl param = l.head; + memberEnter.memberEnter(param, localEnv); + paramTypes.append(param.vartype.type); + + params.append(param.sym); + param.type = param.vartype.type; + } + + MethodType functionType = new MethodType(METHOD, + paramTypes.toList(), + Type.noType, + List.<Type>nil(), + syms.methodClass); + + m.params = params.toList(); + m.type = functionType; + + // Attribute body or expression, compute return type + Type returnType; + if (tree.bodyOrExpr.getTag() == JCTree.BLOCK) { + attribStat(method.body, localEnv); + returnType = lambdaFlow.inferReturnType(method.body); + } else { + returnType = attribExpr(tree.bodyOrExpr, localEnv); + } + + //System.out.println("infered return type "+returnType); + + functionType.restype = returnType; + functionType.tag = FUNCTION; + + localEnv.info.scope.leave(); + result = tree.type = functionType; + } + finally { + chk.setLint(prevLint); + } + } + public void visitAnnotation(JCAnnotation tree) { log.error(tree.pos(), "annotation.not.valid.for.type", pt); result = tree.type = syms.errType; }