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;
}