425 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types)))) |
425 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types)))) |
426 c = c.owner.enclClass(); |
426 c = c.owner.enclClass(); |
427 return c != null; |
427 return c != null; |
428 } |
428 } |
429 |
429 |
|
430 /** |
|
431 * Performs a recursive scan of a type looking for accessibility problems |
|
432 * from current attribution environment |
|
433 */ |
|
434 void checkAccessibleType(Env<AttrContext> env, Type t) { |
|
435 accessibilityChecker.visit(t, env); |
|
436 } |
|
437 |
|
438 /** |
|
439 * Accessibility type-visitor |
|
440 */ |
|
441 Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker = |
|
442 new Types.SimpleVisitor<Void, Env<AttrContext>>() { |
|
443 |
|
444 void visit(List<Type> ts, Env<AttrContext> env) { |
|
445 for (Type t : ts) { |
|
446 visit(t, env); |
|
447 } |
|
448 } |
|
449 |
|
450 public Void visitType(Type t, Env<AttrContext> env) { |
|
451 return null; |
|
452 } |
|
453 |
|
454 @Override |
|
455 public Void visitArrayType(ArrayType t, Env<AttrContext> env) { |
|
456 visit(t.elemtype, env); |
|
457 return null; |
|
458 } |
|
459 |
|
460 @Override |
|
461 public Void visitClassType(ClassType t, Env<AttrContext> env) { |
|
462 visit(t.getTypeArguments(), env); |
|
463 if (!isAccessible(env, t, true)) { |
|
464 accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true); |
|
465 } |
|
466 return null; |
|
467 } |
|
468 |
|
469 @Override |
|
470 public Void visitWildcardType(WildcardType t, Env<AttrContext> env) { |
|
471 visit(t.type, env); |
|
472 return null; |
|
473 } |
|
474 |
|
475 @Override |
|
476 public Void visitMethodType(MethodType t, Env<AttrContext> env) { |
|
477 visit(t.getParameterTypes(), env); |
|
478 visit(t.getReturnType(), env); |
|
479 visit(t.getThrownTypes(), env); |
|
480 return null; |
|
481 } |
|
482 }; |
|
483 |
430 /** Try to instantiate the type of a method so that it fits |
484 /** Try to instantiate the type of a method so that it fits |
431 * given type arguments and argument types. If succesful, return |
485 * given type arguments and argument types. If succesful, return |
432 * the method's instantiated type, else return null. |
486 * the method's instantiated type, else return null. |
433 * The instantiation will take into account an additional leading |
487 * The instantiation will take into account an additional leading |
434 * formal parameter if the method is an instance method seen as a member |
488 * formal parameter if the method is an instance method seen as a member |
748 } |
802 } |
749 |
803 |
750 public boolean compatible(Type found, Type req, Warner warn) { |
804 public boolean compatible(Type found, Type req, Warner warn) { |
751 return types.isSubtypeUnchecked(found, inferenceContext.asFree(req, types), warn); |
805 return types.isSubtypeUnchecked(found, inferenceContext.asFree(req, types), warn); |
752 } |
806 } |
753 |
|
754 public boolean allowBoxing() { |
|
755 return false; |
|
756 } |
|
757 } |
807 } |
758 |
808 |
759 /** |
809 /** |
760 * Subclass of method check context class that implements loose method conversion. |
810 * Subclass of method check context class that implements loose method conversion. |
761 * Loose method conversion checks compatibility between types using method conversion tests. |
811 * Loose method conversion checks compatibility between types using method conversion tests. |
767 super(handler, useVarargs, inferenceContext, deferredAttrContext, rsWarner); |
817 super(handler, useVarargs, inferenceContext, deferredAttrContext, rsWarner); |
768 } |
818 } |
769 |
819 |
770 public boolean compatible(Type found, Type req, Warner warn) { |
820 public boolean compatible(Type found, Type req, Warner warn) { |
771 return types.isConvertible(found, inferenceContext.asFree(req, types), warn); |
821 return types.isConvertible(found, inferenceContext.asFree(req, types), warn); |
772 } |
|
773 |
|
774 public boolean allowBoxing() { |
|
775 return true; |
|
776 } |
822 } |
777 } |
823 } |
778 |
824 |
779 /** |
825 /** |
780 * Create a method check context to be used during method applicability check |
826 * Create a method check context to be used during method applicability check |
790 |
836 |
791 class MethodResultInfo extends ResultInfo { |
837 class MethodResultInfo extends ResultInfo { |
792 |
838 |
793 DeferredAttr.DeferredAttrContext deferredAttrContext; |
839 DeferredAttr.DeferredAttrContext deferredAttrContext; |
794 |
840 |
795 public MethodResultInfo(Type pt, MethodCheckContext checkContext, DeferredAttr.DeferredAttrContext deferredAttrContext) { |
841 public MethodResultInfo(Type pt, CheckContext checkContext, DeferredAttr.DeferredAttrContext deferredAttrContext) { |
796 attr.super(VAL, pt, checkContext); |
842 attr.super(VAL, pt, checkContext); |
797 this.deferredAttrContext = deferredAttrContext; |
843 this.deferredAttrContext = deferredAttrContext; |
798 } |
844 } |
799 |
845 |
800 @Override |
846 @Override |
807 } |
853 } |
808 } |
854 } |
809 |
855 |
810 @Override |
856 @Override |
811 protected MethodResultInfo dup(Type newPt) { |
857 protected MethodResultInfo dup(Type newPt) { |
812 return new MethodResultInfo(newPt, (MethodCheckContext)checkContext, deferredAttrContext); |
858 return new MethodResultInfo(newPt, checkContext, deferredAttrContext); |
|
859 } |
|
860 |
|
861 @Override |
|
862 protected ResultInfo dup(CheckContext newContext) { |
|
863 return new MethodResultInfo(pt, newContext, deferredAttrContext); |
813 } |
864 } |
814 } |
865 } |
815 |
866 |
816 public static class InapplicableMethodException extends RuntimeException { |
867 public static class InapplicableMethodException extends RuntimeException { |
817 private static final long serialVersionUID = 0; |
868 private static final long serialVersionUID = 0; |
1018 return bestSoFar; |
1069 return bestSoFar; |
1019 } |
1070 } |
1020 Assert.check(sym.kind < AMBIGUOUS); |
1071 Assert.check(sym.kind < AMBIGUOUS); |
1021 try { |
1072 try { |
1022 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, |
1073 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, |
1023 allowBoxing, useVarargs, Warner.noWarnings); |
1074 allowBoxing, useVarargs, types.noWarnings); |
1024 if (!operator) |
1075 if (!operator) |
1025 currentResolutionContext.addApplicableCandidate(sym, mt); |
1076 currentResolutionContext.addApplicableCandidate(sym, mt); |
1026 } catch (InapplicableMethodException ex) { |
1077 } catch (InapplicableMethodException ex) { |
1027 if (!operator) |
1078 if (!operator) |
1028 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); |
1079 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); |
1919 return !site.isErroneous() && |
1970 return !site.isErroneous() && |
1920 !Type.isErroneous(argtypes) && |
1971 !Type.isErroneous(argtypes) && |
1921 (typeargtypes == null || !Type.isErroneous(typeargtypes)); |
1972 (typeargtypes == null || !Type.isErroneous(typeargtypes)); |
1922 } |
1973 } |
1923 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { |
1974 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { |
1924 if (syms.operatorNames.contains(name)) { |
1975 return (syms.operatorNames.contains(name)) ? |
1925 return argtypes; |
1976 argtypes : |
1926 } else { |
1977 Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym)); |
1927 Symbol msym = errSym.kind == WRONG_MTH ? |
1978 } |
1928 ((InapplicableSymbolError)errSym).errCandidate().sym : accessedSym; |
1979 |
1929 |
1980 class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap { |
1930 List<Type> argtypes2 = Type.map(argtypes, |
1981 |
1931 deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, msym, currentResolutionContext.step)); |
1982 public ResolveDeferredRecoveryMap(Symbol msym) { |
1932 |
1983 deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step); |
1933 if (msym != accessedSym) { |
1984 } |
1934 //fixup deferred type caches - this 'hack' is required because the symbol |
1985 |
1935 //returned by InapplicableSymbolError.access() will hide the candidate |
1986 @Override |
1936 //method symbol that can be used for lookups in the speculative cache, |
1987 protected Type typeOf(DeferredType dt) { |
1937 //causing problems in Attr.checkId() |
1988 Type res = super.typeOf(dt); |
1938 for (Type t : argtypes) { |
1989 if (!res.isErroneous()) { |
1939 if (t.hasTag(DEFERRED)) { |
1990 switch (TreeInfo.skipParens(dt.tree).getTag()) { |
1940 DeferredType dt = (DeferredType)t; |
1991 case LAMBDA: |
1941 dt.speculativeCache.dupAllTo(msym, accessedSym); |
1992 case REFERENCE: |
1942 } |
1993 return dt; |
|
1994 case CONDEXPR: |
|
1995 return res == Type.recoveryType ? |
|
1996 dt : res; |
1943 } |
1997 } |
1944 } |
1998 } |
1945 return argtypes2; |
1999 return res; |
1946 } |
2000 } |
1947 } |
2001 } |
1948 }; |
2002 }; |
1949 |
2003 |
1950 /** Check that sym is not an abstract method. |
2004 /** Check that sym is not an abstract method. |
2067 if (sym.kind >= AMBIGUOUS) { |
2121 if (sym.kind >= AMBIGUOUS) { |
2068 sym = super.access(env, pos, location, sym); |
2122 sym = super.access(env, pos, location, sym); |
2069 } else if (allowMethodHandles) { |
2123 } else if (allowMethodHandles) { |
2070 MethodSymbol msym = (MethodSymbol)sym; |
2124 MethodSymbol msym = (MethodSymbol)sym; |
2071 if (msym.isSignaturePolymorphic(types)) { |
2125 if (msym.isSignaturePolymorphic(types)) { |
2072 env.info.pendingResolutionPhase = BASIC; |
|
2073 return findPolymorphicSignatureInstance(env, sym, argtypes); |
2126 return findPolymorphicSignatureInstance(env, sym, argtypes); |
2074 } |
2127 } |
2075 } |
2128 } |
2076 return sym; |
2129 return sym; |
2077 } |
2130 } |
2084 * @param env Attribution environment |
2137 * @param env Attribution environment |
2085 * @param spMethod signature polymorphic method - i.e. MH.invokeExact |
2138 * @param spMethod signature polymorphic method - i.e. MH.invokeExact |
2086 * @param argtypes The required argument types |
2139 * @param argtypes The required argument types |
2087 */ |
2140 */ |
2088 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, |
2141 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, |
2089 Symbol spMethod, |
2142 final Symbol spMethod, |
2090 List<Type> argtypes) { |
2143 List<Type> argtypes) { |
2091 Type mtype = infer.instantiatePolymorphicSignatureInstance(env, |
2144 Type mtype = infer.instantiatePolymorphicSignatureInstance(env, |
2092 (MethodSymbol)spMethod, currentResolutionContext, argtypes); |
2145 (MethodSymbol)spMethod, currentResolutionContext, argtypes); |
2093 for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) { |
2146 for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) { |
2094 if (types.isSameType(mtype, sym.type)) { |
2147 if (types.isSameType(mtype, sym.type)) { |
2096 } |
2149 } |
2097 } |
2150 } |
2098 |
2151 |
2099 // create the desired method |
2152 // create the desired method |
2100 long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags; |
2153 long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags; |
2101 Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner); |
2154 Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) { |
|
2155 @Override |
|
2156 public Symbol baseSymbol() { |
|
2157 return spMethod; |
|
2158 } |
|
2159 }; |
2102 polymorphicSignatureScope.enter(msym); |
2160 polymorphicSignatureScope.enter(msym); |
2103 return msym; |
2161 return msym; |
2104 } |
2162 } |
2105 |
2163 |
2106 /** Resolve a qualified method identifier, throw a fatal error if not |
2164 /** Resolve a qualified method identifier, throw a fatal error if not |
2705 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; |
2763 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; |
2706 env1 = env1.outer; |
2764 env1 = env1.outer; |
2707 } |
2765 } |
2708 if (allowDefaultMethods && c.isInterface() && |
2766 if (allowDefaultMethods && c.isInterface() && |
2709 name == names._super && !isStatic(env) && |
2767 name == names._super && !isStatic(env) && |
2710 types.isDirectSuperInterface(c.type, env.enclClass.sym)) { |
2768 types.isDirectSuperInterface(c, env.enclClass.sym)) { |
2711 //this might be a default super call if one of the superinterfaces is 'c' |
2769 //this might be a default super call if one of the superinterfaces is 'c' |
2712 for (Type t : pruneInterfaces(env.enclClass.type)) { |
2770 for (Type t : pruneInterfaces(env.enclClass.type)) { |
2713 if (t.tsym == c) { |
2771 if (t.tsym == c) { |
2714 env.info.defaultSuperCallSite = t; |
2772 env.info.defaultSuperCallSite = t; |
2715 return new VarSymbol(0, names._super, |
2773 return new VarSymbol(0, names._super, |
3148 log.currentSource(), |
3206 log.currentSource(), |
3149 pos, |
3207 pos, |
3150 "cant.apply.symbols", |
3208 "cant.apply.symbols", |
3151 name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), |
3209 name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), |
3152 name == names.init ? site.tsym.name : name, |
3210 name == names.init ? site.tsym.name : name, |
3153 argtypes); |
3211 methodArguments(argtypes)); |
3154 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); |
3212 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); |
3155 } else { |
3213 } else { |
3156 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, |
3214 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, |
3157 location, site, name, argtypes, typeargtypes); |
3215 location, site, name, argtypes, typeargtypes); |
3158 } |
3216 } |