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

Print this page




2417     //where
2418         void preFlow(JCLambda tree) {
2419             new PostAttrAnalyzer() {
2420                 @Override
2421                 public void scan(JCTree tree) {
2422                     if (tree == null ||
2423                             (tree.type != null &&
2424                             tree.type == Type.stuckType)) {
2425                         //don't touch stuck expressions!
2426                         return;
2427                     }
2428                     super.scan(tree);
2429                 }
2430             }.scan(tree);
2431         }
2432 
2433         Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
2434 
2435             @Override
2436             public Type visitClassType(ClassType t, DiagnosticPosition pos) {
2437                 return t.isCompound() ?
2438                         visitIntersectionClassType((IntersectionClassType)t, pos) : t;
2439             }
2440 
2441             public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) {
2442                 Symbol desc = types.findDescriptorSymbol(makeNotionalInterface(ict));
2443                 Type target = null;
2444                 for (Type bound : ict.getExplicitComponents()) {
2445                     TypeSymbol boundSym = bound.tsym;
2446                     if (types.isFunctionalInterface(boundSym) &&
2447                             types.findDescriptorSymbol(boundSym) == desc) {
2448                         target = bound;
2449                     } else if (!boundSym.isInterface() || (boundSym.flags() & ANNOTATION) != 0) {
2450                         //bound must be an interface
2451                         reportIntersectionError(pos, "not.an.intf.component", boundSym);
2452                     }
2453                 }
2454                 return target != null ?
2455                         target :
2456                         ict.getExplicitComponents().head; //error recovery
2457             }
2458 
2459             private TypeSymbol makeNotionalInterface(IntersectionClassType ict) {
2460                 ListBuffer<Type> targs = new ListBuffer<>();
2461                 ListBuffer<Type> supertypes = new ListBuffer<>();
2462                 for (Type i : ict.interfaces_field) {
2463                     if (i.isParameterized()) {
2464                         targs.appendList(i.tsym.type.allparams());
2465                     }
2466                     supertypes.append(i.tsym.type);
2467                 }
2468                 IntersectionClassType notionalIntf =
2469                         (IntersectionClassType)types.makeCompoundType(supertypes.toList());
2470                 notionalIntf.allparams_field = targs.toList();
2471                 notionalIntf.tsym.flags_field |= INTERFACE;
2472                 return notionalIntf.tsym;
2473             }
2474 
2475             private void reportIntersectionError(DiagnosticPosition pos, String key, Object... args) {
2476                 resultInfo.checkContext.report(pos, diags.fragment("bad.intersection.target.for.functional.expr",
2477                         diags.fragment(key, args)));
2478             }
2479         };
2480 
2481         private Type fallbackDescriptorType(JCExpression tree) {
2482             switch (tree.getTag()) {
2483                 case LAMBDA:
2484                     JCLambda lambda = (JCLambda)tree;
2485                     List<Type> argtypes = List.nil();
2486                     for (JCVariableDecl param : lambda.params) {
2487                         argtypes = param.vartype != null ?
2488                                 argtypes.append(param.vartype.type) :
2489                                 argtypes.append(syms.errType);


4015             } else {
4016                 // if first bound was a class or interface, accept only interfaces
4017                 // as further bounds.
4018                 for (JCExpression bound : bounds.tail) {
4019                     bound.type = checkBase(bound.type, bound, env, false, true, false);
4020                     if (bound.type.isErroneous()) {
4021                         bounds = List.of(bound);
4022                     }
4023                     else if (bound.type.hasTag(CLASS)) {
4024                         chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet);
4025                     }
4026                 }
4027             }
4028         }
4029 
4030         if (bounds.length() == 0) {
4031             return syms.objectType;
4032         } else if (bounds.length() == 1) {
4033             return bounds.head.type;
4034         } else {
4035             Type owntype = types.makeCompoundType(TreeInfo.types(bounds));
4036             // ... the variable's bound is a class type flagged COMPOUND
4037             // (see comment for TypeVar.bound).
4038             // In this case, generate a class tree that represents the
4039             // bound class, ...
4040             JCExpression extending;
4041             List<JCExpression> implementing;
4042             if (!bounds.head.type.isInterface()) {
4043                 extending = bounds.head;
4044                 implementing = bounds.tail;
4045             } else {
4046                 extending = null;
4047                 implementing = bounds;
4048             }
4049             JCClassDecl cd = make.at(tree).ClassDef(
4050                 make.Modifiers(PUBLIC | ABSTRACT),
4051                 names.empty, List.<JCTypeParameter>nil(),
4052                 extending, implementing, List.<JCTree>nil());
4053 
4054             ClassSymbol c = (ClassSymbol)owntype.tsym;
4055             Assert.check((c.flags() & COMPOUND) != 0);




2417     //where
2418         void preFlow(JCLambda tree) {
2419             new PostAttrAnalyzer() {
2420                 @Override
2421                 public void scan(JCTree tree) {
2422                     if (tree == null ||
2423                             (tree.type != null &&
2424                             tree.type == Type.stuckType)) {
2425                         //don't touch stuck expressions!
2426                         return;
2427                     }
2428                     super.scan(tree);
2429                 }
2430             }.scan(tree);
2431         }
2432 
2433         Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
2434 
2435             @Override
2436             public Type visitClassType(ClassType t, DiagnosticPosition pos) {
2437                 return t.isIntersection() ?
2438                         visitIntersectionClassType((IntersectionClassType)t, pos) : t;
2439             }
2440 
2441             public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) {
2442                 Symbol desc = types.findDescriptorSymbol(makeNotionalInterface(ict));
2443                 Type target = null;
2444                 for (Type bound : ict.getExplicitComponents()) {
2445                     TypeSymbol boundSym = bound.tsym;
2446                     if (types.isFunctionalInterface(boundSym) &&
2447                             types.findDescriptorSymbol(boundSym) == desc) {
2448                         target = bound;
2449                     } else if (!boundSym.isInterface() || (boundSym.flags() & ANNOTATION) != 0) {
2450                         //bound must be an interface
2451                         reportIntersectionError(pos, "not.an.intf.component", boundSym);
2452                     }
2453                 }
2454                 return target != null ?
2455                         target :
2456                         ict.getExplicitComponents().head; //error recovery
2457             }
2458 
2459             private TypeSymbol makeNotionalInterface(IntersectionClassType ict) {
2460                 ListBuffer<Type> targs = new ListBuffer<>();
2461                 ListBuffer<Type> supertypes = new ListBuffer<>();
2462                 for (Type i : ict.interfaces_field) {
2463                     if (i.isParameterized()) {
2464                         targs.appendList(i.tsym.type.allparams());
2465                     }
2466                     supertypes.append(i.tsym.type);
2467                 }
2468                 IntersectionClassType notionalIntf = types.makeIntersectionType(supertypes.toList());

2469                 notionalIntf.allparams_field = targs.toList();
2470                 notionalIntf.tsym.flags_field |= INTERFACE;
2471                 return notionalIntf.tsym;
2472             }
2473 
2474             private void reportIntersectionError(DiagnosticPosition pos, String key, Object... args) {
2475                 resultInfo.checkContext.report(pos, diags.fragment("bad.intersection.target.for.functional.expr",
2476                         diags.fragment(key, args)));
2477             }
2478         };
2479 
2480         private Type fallbackDescriptorType(JCExpression tree) {
2481             switch (tree.getTag()) {
2482                 case LAMBDA:
2483                     JCLambda lambda = (JCLambda)tree;
2484                     List<Type> argtypes = List.nil();
2485                     for (JCVariableDecl param : lambda.params) {
2486                         argtypes = param.vartype != null ?
2487                                 argtypes.append(param.vartype.type) :
2488                                 argtypes.append(syms.errType);


4014             } else {
4015                 // if first bound was a class or interface, accept only interfaces
4016                 // as further bounds.
4017                 for (JCExpression bound : bounds.tail) {
4018                     bound.type = checkBase(bound.type, bound, env, false, true, false);
4019                     if (bound.type.isErroneous()) {
4020                         bounds = List.of(bound);
4021                     }
4022                     else if (bound.type.hasTag(CLASS)) {
4023                         chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet);
4024                     }
4025                 }
4026             }
4027         }
4028 
4029         if (bounds.length() == 0) {
4030             return syms.objectType;
4031         } else if (bounds.length() == 1) {
4032             return bounds.head.type;
4033         } else {
4034             Type owntype = types.makeIntersectionType(TreeInfo.types(bounds));
4035             // ... the variable's bound is a class type flagged COMPOUND
4036             // (see comment for TypeVar.bound).
4037             // In this case, generate a class tree that represents the
4038             // bound class, ...
4039             JCExpression extending;
4040             List<JCExpression> implementing;
4041             if (!bounds.head.type.isInterface()) {
4042                 extending = bounds.head;
4043                 implementing = bounds.tail;
4044             } else {
4045                 extending = null;
4046                 implementing = bounds;
4047             }
4048             JCClassDecl cd = make.at(tree).ClassDef(
4049                 make.Modifiers(PUBLIC | ABSTRACT),
4050                 names.empty, List.<JCTypeParameter>nil(),
4051                 extending, implementing, List.<JCTree>nil());
4052 
4053             ClassSymbol c = (ClassSymbol)owntype.tsym;
4054             Assert.check((c.flags() & COMPOUND) != 0);