--- old/src/share/classes/com/sun/tools/javac/comp/Attr.java 2009-12-27 19:02:17.000000000 +0100 +++ new/src/share/classes/com/sun/tools/javac/comp/Attr.java 2009-12-27 19:02:17.000000000 +0100 @@ -26,7 +26,6 @@ package com.sun.tools.javac.comp; import java.util.*; -import java.util.Set; import javax.lang.model.element.ElementKind; import javax.tools.JavaFileObject; @@ -81,6 +80,7 @@ final Types types; final JCDiagnostic.Factory diags; final Annotate annotate; + final LambdaFlow lambdaFlow; public static Attr instance(Context context) { Attr instance = context.get(attrKey); @@ -105,6 +105,7 @@ types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); annotate = Annotate.instance(context); + lambdaFlow = LambdaFlow.instance(context); Options options = Options.instance(context); @@ -646,7 +647,7 @@ // JLS ??? chk.checkOverride(tree, m); - // Create a new environment with local scope + // Create fresh environment with local scope // for attributing the method. Env localEnv = memberEnter.methodEnv(tree, env); @@ -2087,6 +2088,19 @@ } 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.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 @@ -2122,6 +2136,9 @@ 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; } @@ -2697,6 +2714,108 @@ syms.boundClass), TYP, pkind, pt); } + + @Override + public void visitFunctionType(JCFunctionType tree) { + JCExpression returnTypeExpr = tree.returnType; + Type returnType = attribType(returnTypeExpr, env); + returnTypeExpr.type = returnType; + + ListBuffer parameterTypes = ListBuffer.lb(); + for (List 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.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.of(_return)); + } + JCMethodDecl method = make.MethodDef( + make.Modifiers(m.flags()), + null, + null, + List.nil(), + tree.parameters, + null, + List.nil(), + body, + null); + method.sym = m; + + Lint lint = env.info.lint.augment(List.nil(), flags); + Lint prevLint = chk.setLint(lint); + try { + // Create a new environment with a new scope + // for attributing the fake method. + Env localEnv = memberEnter.methodEnv(method, env); + localEnv.info.lint = lint; + + // enter parameter symbol and attribute them + ListBuffer params = new ListBuffer(); + ListBuffer paramTypes = new ListBuffer(); + for (List 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.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);