582 Warner warn) { |
582 Warner warn) { |
583 MethodResolutionContext prevContext = currentResolutionContext; |
583 MethodResolutionContext prevContext = currentResolutionContext; |
584 try { |
584 try { |
585 currentResolutionContext = new MethodResolutionContext(); |
585 currentResolutionContext = new MethodResolutionContext(); |
586 currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK; |
586 currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK; |
|
587 if (env.tree.hasTag(JCTree.Tag.REFERENCE)) { |
|
588 //method/constructor references need special check class |
|
589 //to handle inference variables in 'argtypes' (might happen |
|
590 //during an unsticking round) |
|
591 currentResolutionContext.methodCheck = |
|
592 new MethodReferenceCheck(resultInfo.checkContext.inferenceContext()); |
|
593 } |
587 MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase; |
594 MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase; |
588 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, |
595 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, |
589 step.isBoxingRequired(), step.isVarargsRequired(), warn); |
596 step.isBoxingRequired(), step.isVarargsRequired(), warn); |
590 } |
597 } |
591 finally { |
598 finally { |
771 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { |
778 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { |
772 //do nothing - actual always compatible to formals |
779 //do nothing - actual always compatible to formals |
773 } |
780 } |
774 }; |
781 }; |
775 |
782 |
|
783 List<Type> dummyArgs(int length) { |
|
784 ListBuffer<Type> buf = ListBuffer.lb(); |
|
785 for (int i = 0 ; i < length ; i++) { |
|
786 buf.append(Type.noType); |
|
787 } |
|
788 return buf.toList(); |
|
789 } |
|
790 |
776 /** |
791 /** |
777 * Main method applicability routine. Given a list of actual types A, |
792 * Main method applicability routine. Given a list of actual types A, |
778 * a list of formal types F, determines whether the types in A are |
793 * a list of formal types F, determines whether the types in A are |
779 * compatible (by method invocation conversion) with the types in F. |
794 * compatible (by method invocation conversion) with the types in F. |
780 * |
795 * |
833 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, |
848 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, |
834 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { |
849 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { |
835 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { |
850 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { |
836 MethodCheckDiag methodDiag = varargsCheck ? |
851 MethodCheckDiag methodDiag = varargsCheck ? |
837 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; |
852 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; |
|
853 |
|
854 @Override |
|
855 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
|
856 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); |
|
857 } |
|
858 }; |
|
859 return new MethodResultInfo(to, checkContext); |
|
860 } |
|
861 |
|
862 @Override |
|
863 public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) { |
|
864 return new MostSpecificCheck(strict, actuals); |
|
865 } |
|
866 }; |
|
867 |
|
868 class MethodReferenceCheck extends AbstractMethodCheck { |
|
869 |
|
870 InferenceContext pendingInferenceContext; |
|
871 |
|
872 MethodReferenceCheck(InferenceContext pendingInferenceContext) { |
|
873 this.pendingInferenceContext = pendingInferenceContext; |
|
874 } |
|
875 |
|
876 @Override |
|
877 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { |
|
878 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); |
|
879 mresult.check(pos, actual); |
|
880 } |
|
881 |
|
882 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, |
|
883 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { |
|
884 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { |
|
885 MethodCheckDiag methodDiag = varargsCheck ? |
|
886 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; |
|
887 |
|
888 @Override |
|
889 public boolean compatible(Type found, Type req, Warner warn) { |
|
890 found = pendingInferenceContext.asFree(found); |
|
891 req = infer.returnConstraintTarget(found, req); |
|
892 return super.compatible(found, req, warn); |
|
893 } |
838 |
894 |
839 @Override |
895 @Override |
840 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
896 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
841 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); |
897 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); |
842 } |
898 } |
2574 JCMemberReference referenceTree, |
2630 JCMemberReference referenceTree, |
2575 Type site, |
2631 Type site, |
2576 Name name, List<Type> argtypes, |
2632 Name name, List<Type> argtypes, |
2577 List<Type> typeargtypes, |
2633 List<Type> typeargtypes, |
2578 boolean boxingAllowed, |
2634 boolean boxingAllowed, |
2579 MethodCheck methodCheck) { |
2635 MethodCheck methodCheck, |
|
2636 InferenceContext inferenceContext) { |
2580 MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; |
2637 MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; |
2581 |
2638 |
2582 ReferenceLookupHelper boundLookupHelper; |
2639 ReferenceLookupHelper boundLookupHelper; |
2583 if (!name.equals(names.init)) { |
2640 if (!name.equals(names.init)) { |
2584 //method reference |
2641 //method reference |
2597 //step 1 - bound lookup |
2654 //step 1 - bound lookup |
2598 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup()); |
2655 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup()); |
2599 Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper); |
2656 Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper); |
2600 |
2657 |
2601 //step 2 - unbound lookup |
2658 //step 2 - unbound lookup |
2602 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(); |
2659 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); |
2603 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup()); |
2660 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup()); |
2604 Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper); |
2661 Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper); |
2605 |
2662 |
2606 //merge results |
2663 //merge results |
2607 Pair<Symbol, ReferenceLookupHelper> res; |
2664 Pair<Symbol, ReferenceLookupHelper> res; |
2737 |
2794 |
2738 /** |
2795 /** |
2739 * Returns an unbound version of this lookup helper. By default, this |
2796 * Returns an unbound version of this lookup helper. By default, this |
2740 * method returns an dummy lookup helper. |
2797 * method returns an dummy lookup helper. |
2741 */ |
2798 */ |
2742 ReferenceLookupHelper unboundLookup() { |
2799 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { |
2743 //dummy loopkup helper that always return 'methodNotFound' |
2800 //dummy loopkup helper that always return 'methodNotFound' |
2744 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { |
2801 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { |
2745 @Override |
2802 @Override |
2746 ReferenceLookupHelper unboundLookup() { |
2803 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { |
2747 return this; |
2804 return this; |
2748 } |
2805 } |
2749 @Override |
2806 @Override |
2750 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { |
2807 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { |
2751 return methodNotFound; |
2808 return methodNotFound; |
2791 return findMethod(env, site, name, argtypes, typeargtypes, |
2848 return findMethod(env, site, name, argtypes, typeargtypes, |
2792 phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name)); |
2849 phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name)); |
2793 } |
2850 } |
2794 |
2851 |
2795 @Override |
2852 @Override |
2796 ReferenceLookupHelper unboundLookup() { |
2853 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { |
2797 if (TreeInfo.isStaticSelector(referenceTree.expr, names) && |
2854 if (TreeInfo.isStaticSelector(referenceTree.expr, names) && |
2798 argtypes.nonEmpty() && |
2855 argtypes.nonEmpty() && |
2799 (argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) { |
2856 (argtypes.head.hasTag(NONE) || |
|
2857 types.isSubtypeUnchecked(inferenceContext.asFree(argtypes.head), site))) { |
2800 return new UnboundMethodReferenceLookupHelper(referenceTree, name, |
2858 return new UnboundMethodReferenceLookupHelper(referenceTree, name, |
2801 site, argtypes, typeargtypes, maxPhase); |
2859 site, argtypes, typeargtypes, maxPhase); |
2802 } else { |
2860 } else { |
2803 return super.unboundLookup(); |
2861 return super.unboundLookup(inferenceContext); |
2804 } |
2862 } |
2805 } |
2863 } |
2806 |
2864 |
2807 @Override |
2865 @Override |
2808 ReferenceKind referenceKind(Symbol sym) { |
2866 ReferenceKind referenceKind(Symbol sym) { |