1 /* |
1 /* |
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
32 import java.util.Locale; |
32 import java.util.Locale; |
33 import java.util.Map; |
33 import java.util.Map; |
34 import java.util.Set; |
34 import java.util.Set; |
35 import java.util.WeakHashMap; |
35 import java.util.WeakHashMap; |
36 |
36 |
|
37 import javax.lang.model.type.TypeKind; |
|
38 |
37 import com.sun.tools.javac.code.Attribute.RetentionPolicy; |
39 import com.sun.tools.javac.code.Attribute.RetentionPolicy; |
38 import com.sun.tools.javac.code.Lint.LintCategory; |
40 import com.sun.tools.javac.code.Lint.LintCategory; |
39 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; |
41 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; |
40 import com.sun.tools.javac.comp.Check; |
42 import com.sun.tools.javac.comp.Check; |
41 import com.sun.tools.javac.jvm.ClassReader; |
43 import com.sun.tools.javac.jvm.ClassReader; |
42 import com.sun.tools.javac.util.*; |
44 import com.sun.tools.javac.util.*; |
43 import com.sun.tools.javac.util.List; |
|
44 import static com.sun.tools.javac.code.BoundKind.*; |
45 import static com.sun.tools.javac.code.BoundKind.*; |
45 import static com.sun.tools.javac.code.Flags.*; |
46 import static com.sun.tools.javac.code.Flags.*; |
46 import static com.sun.tools.javac.code.Scope.*; |
47 import static com.sun.tools.javac.code.Scope.*; |
47 import static com.sun.tools.javac.code.Symbol.*; |
48 import static com.sun.tools.javac.code.Symbol.*; |
48 import static com.sun.tools.javac.code.Type.*; |
49 import static com.sun.tools.javac.code.Type.*; |
352 |
353 |
353 public Symbol getSymbol() { |
354 public Symbol getSymbol() { |
354 return descSym; |
355 return descSym; |
355 } |
356 } |
356 |
357 |
357 public Type getType(Type origin) { |
358 public Type getType(Type site) { |
358 return memberType(origin, descSym); |
359 if (capture(site) != site) { |
|
360 Type formalInterface = site.tsym.type; |
|
361 ListBuffer<Type> typeargs = ListBuffer.lb(); |
|
362 List<Type> actualTypeargs = site.getTypeArguments(); |
|
363 //simply replace the wildcards with its bound |
|
364 for (Type t : formalInterface.getTypeArguments()) { |
|
365 if (actualTypeargs.head.hasTag(WILDCARD)) { |
|
366 WildcardType wt = (WildcardType)actualTypeargs.head; |
|
367 typeargs.append(wt.type); |
|
368 } else { |
|
369 typeargs.append(actualTypeargs.head); |
|
370 } |
|
371 actualTypeargs = actualTypeargs.tail; |
|
372 } |
|
373 site = subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList()); |
|
374 if (!chk.checkValidGenericType(site)) { |
|
375 //if the inferred functional interface type is not well-formed, |
|
376 //or if it's not a subtype of the original target, issue an error |
|
377 throw failure(diags.fragment("no.suitable.functional.intf.inst", site)); |
|
378 } |
|
379 } |
|
380 return memberType(site, descSym); |
359 } |
381 } |
360 } |
382 } |
361 |
383 |
362 class Entry { |
384 class Entry { |
363 final FunctionDescriptor cachedDescRes; |
385 final FunctionDescriptor cachedDescRes; |
390 |
412 |
391 /** |
413 /** |
392 * Compute the function descriptor associated with a given functional interface |
414 * Compute the function descriptor associated with a given functional interface |
393 */ |
415 */ |
394 public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError { |
416 public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError { |
395 if (!origin.isInterface()) { |
417 if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) { |
396 //t must be an interface |
418 //t must be an interface |
397 throw failure("not.a.functional.intf"); |
419 throw failure("not.a.functional.intf", origin); |
398 } |
420 } |
399 |
421 |
400 final ListBuffer<Symbol> abstracts = ListBuffer.lb(); |
422 final ListBuffer<Symbol> abstracts = ListBuffer.lb(); |
401 for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { |
423 for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { |
402 Type mtype = memberType(origin.type, sym); |
424 Type mtype = memberType(origin.type, sym); |
404 (sym.name == abstracts.first().name && |
426 (sym.name == abstracts.first().name && |
405 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) { |
427 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) { |
406 abstracts.append(sym); |
428 abstracts.append(sym); |
407 } else { |
429 } else { |
408 //the target method(s) should be the only abstract members of t |
430 //the target method(s) should be the only abstract members of t |
409 throw failure("not.a.functional.intf.1", |
431 throw failure("not.a.functional.intf.1", origin, |
410 diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin)); |
432 diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin)); |
411 } |
433 } |
412 } |
434 } |
413 if (abstracts.isEmpty()) { |
435 if (abstracts.isEmpty()) { |
414 //t must define a suitable non-generic method |
436 //t must define a suitable non-generic method |
415 throw failure("not.a.functional.intf.1", |
437 throw failure("not.a.functional.intf.1", origin, |
416 diags.fragment("no.abstracts", Kinds.kindName(origin), origin)); |
438 diags.fragment("no.abstracts", Kinds.kindName(origin), origin)); |
417 } else if (abstracts.size() == 1) { |
439 } else if (abstracts.size() == 1) { |
418 return new FunctionDescriptor(abstracts.first()); |
440 return new FunctionDescriptor(abstracts.first()); |
419 } else { // size > 1 |
441 } else { // size > 1 |
420 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); |
442 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); |
551 return true; |
573 return true; |
552 } catch (FunctionDescriptorLookupError ex) { |
574 } catch (FunctionDescriptorLookupError ex) { |
553 return false; |
575 return false; |
554 } |
576 } |
555 } |
577 } |
|
578 |
|
579 public boolean isFunctionalInterface(Type site) { |
|
580 try { |
|
581 findDescriptorType(site); |
|
582 return true; |
|
583 } catch (FunctionDescriptorLookupError ex) { |
|
584 return false; |
|
585 } |
|
586 } |
556 // </editor-fold> |
587 // </editor-fold> |
557 |
588 |
558 /** |
589 /** |
559 * Scope filter used to skip methods that should be ignored (such as methods |
590 * Scope filter used to skip methods that should be ignored (such as methods |
560 * overridden by j.l.Object) during function interface conversion/marker interface checks |
591 * overridden by j.l.Object) during function interface conversion/marker interface checks |
652 return result; |
683 return result; |
653 } |
684 } |
654 //where |
685 //where |
655 private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) { |
686 private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) { |
656 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) { |
687 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) { |
|
688 t = t.unannotatedType(); |
|
689 s = s.unannotatedType(); |
657 if (((ArrayType)t).elemtype.isPrimitive()) { |
690 if (((ArrayType)t).elemtype.isPrimitive()) { |
658 return isSameType(elemtype(t), elemtype(s)); |
691 return isSameType(elemtype(t), elemtype(s)); |
659 } else { |
692 } else { |
660 return isSubtypeUnchecked(elemtype(t), elemtype(s), warn); |
693 return isSubtypeUnchecked(elemtype(t), elemtype(s), warn); |
661 } |
694 } |
677 } |
710 } |
678 return false; |
711 return false; |
679 } |
712 } |
680 |
713 |
681 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { |
714 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { |
682 if (t.tag != ARRAY || isReifiable(t)) return; |
715 if (t.tag != ARRAY || isReifiable(t)) |
|
716 return; |
|
717 t = t.unannotatedType(); |
|
718 s = s.unannotatedType(); |
683 ArrayType from = (ArrayType)t; |
719 ArrayType from = (ArrayType)t; |
684 boolean shouldWarn = false; |
720 boolean shouldWarn = false; |
685 switch (s.tag) { |
721 switch (s.tag) { |
686 case ARRAY: |
722 case ARRAY: |
687 ArrayType to = (ArrayType)s; |
723 ArrayType to = (ArrayType)s; |
707 } |
743 } |
708 final public boolean isSubtypeNoCapture(Type t, Type s) { |
744 final public boolean isSubtypeNoCapture(Type t, Type s) { |
709 return isSubtype(t, s, false); |
745 return isSubtype(t, s, false); |
710 } |
746 } |
711 public boolean isSubtype(Type t, Type s, boolean capture) { |
747 public boolean isSubtype(Type t, Type s, boolean capture) { |
|
748 if (t == s) |
|
749 return true; |
|
750 |
|
751 t = t.unannotatedType(); |
|
752 s = s.unannotatedType(); |
|
753 |
712 if (t == s) |
754 if (t == s) |
713 return true; |
755 return true; |
714 |
756 |
715 if (s.isPartial()) |
757 if (s.isPartial()) |
716 return isSuperType(s, t); |
758 return isSuperType(s, t); |
1978 } |
2021 } |
1979 |
2022 |
1980 @Override |
2023 @Override |
1981 public Type visitErrorType(ErrorType t, Boolean recurse) { |
2024 public Type visitErrorType(ErrorType t, Boolean recurse) { |
1982 return t; |
2025 return t; |
|
2026 } |
|
2027 |
|
2028 @Override |
|
2029 public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { |
|
2030 return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse)); |
1983 } |
2031 } |
1984 }; |
2032 }; |
1985 |
2033 |
1986 private Mapping erasureFun = new Mapping ("erasure") { |
2034 private Mapping erasureFun = new Mapping ("erasure") { |
1987 public Type apply(Type t) { return erasure(t); } |
2035 public Type apply(Type t) { return erasure(t); } |
2921 * The rank of a class is the length of the longest path between |
2969 * The rank of a class is the length of the longest path between |
2922 * the class and java.lang.Object in the class inheritance |
2970 * the class and java.lang.Object in the class inheritance |
2923 * graph. Undefined for all but reference types. |
2971 * graph. Undefined for all but reference types. |
2924 */ |
2972 */ |
2925 public int rank(Type t) { |
2973 public int rank(Type t) { |
|
2974 t = t.unannotatedType(); |
2926 switch(t.tag) { |
2975 switch(t.tag) { |
2927 case CLASS: { |
2976 case CLASS: { |
2928 ClassType cls = (ClassType)t; |
2977 ClassType cls = (ClassType)t; |
2929 if (cls.rank_field < 0) { |
2978 if (cls.rank_field < 0) { |
2930 Name fullname = cls.tsym.getQualifiedName(); |
2979 Name fullname = cls.tsym.getQualifiedName(); |
3622 if (capturedEncl != t.getEnclosingType()) { |
3671 if (capturedEncl != t.getEnclosingType()) { |
3623 Type type1 = memberType(capturedEncl, t.tsym); |
3672 Type type1 = memberType(capturedEncl, t.tsym); |
3624 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments()); |
3673 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments()); |
3625 } |
3674 } |
3626 } |
3675 } |
|
3676 t = t.unannotatedType(); |
3627 ClassType cls = (ClassType)t; |
3677 ClassType cls = (ClassType)t; |
3628 if (cls.isRaw() || !cls.isParameterized()) |
3678 if (cls.isRaw() || !cls.isParameterized()) |
3629 return cls; |
3679 return cls; |
3630 |
3680 |
3631 ClassType G = (ClassType)cls.asElement().asType(); |
3681 ClassType G = (ClassType)cls.asElement().asType(); |
4140 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); } |
4190 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); } |
4141 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); } |
4191 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); } |
4142 public R visitForAll(ForAll t, S s) { return visitType(t, s); } |
4192 public R visitForAll(ForAll t, S s) { return visitType(t, s); } |
4143 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } |
4193 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } |
4144 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } |
4194 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } |
|
4195 // Pretend annotations don't exist |
|
4196 public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); } |
4145 } |
4197 } |
4146 |
4198 |
4147 /** |
4199 /** |
4148 * A default visitor for symbols. All visitor methods except |
4200 * A default visitor for symbols. All visitor methods except |
4149 * visitSymbol are implemented by delegating to visitSymbol. Concrete |
4201 * visitSymbol are implemented by delegating to visitSymbol. Concrete |