495 * are mapped to themselves, in order to have a richer diagnostic |
495 * are mapped to themselves, in order to have a richer diagnostic |
496 * representation. Remaining deferred types are attributed using |
496 * representation. Remaining deferred types are attributed using |
497 * a default expected type (j.l.Object). |
497 * a default expected type (j.l.Object). |
498 */ |
498 */ |
499 private Type recover(DeferredType dt) { |
499 private Type recover(DeferredType dt) { |
500 dt.check(new RecoveryInfo()); |
500 dt.check(attr.new RecoveryInfo(deferredAttrContext)); |
501 switch (TreeInfo.skipParens(dt.tree).getTag()) { |
501 switch (TreeInfo.skipParens(dt.tree).getTag()) { |
502 case LAMBDA: |
502 case LAMBDA: |
503 case REFERENCE: |
503 case REFERENCE: |
504 case CONDEXPR: |
504 case CONDEXPR: |
505 //propagate those deferred types to the |
505 //propagate those deferred types to the |
507 return dt; |
507 return dt; |
508 default: |
508 default: |
509 return super.apply(dt); |
509 return super.apply(dt); |
510 } |
510 } |
511 } |
511 } |
512 |
|
513 class RecoveryInfo extends ResultInfo { |
|
514 |
|
515 public RecoveryInfo() { |
|
516 attr.super(Kinds.VAL, Type.recoveryType, new Check.NestedCheckContext(chk.basicHandler) { |
|
517 @Override |
|
518 public DeferredAttrContext deferredAttrContext() { |
|
519 return deferredAttrContext; |
|
520 } |
|
521 @Override |
|
522 public boolean compatible(Type found, Type req, Warner warn) { |
|
523 return true; |
|
524 } |
|
525 @Override |
|
526 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
|
527 //do nothing |
|
528 } |
|
529 }); |
|
530 } |
|
531 |
|
532 @Override |
|
533 protected Type check(DiagnosticPosition pos, Type found) { |
|
534 return chk.checkNonVoid(pos, super.check(pos, found)); |
|
535 } |
|
536 } |
|
537 } |
512 } |
538 |
513 |
539 /** |
514 /** |
540 * Retrieves the list of inference variables that need to be inferred before |
515 * Retrieves the list of inference variables that need to be inferred before |
541 * an AST node can be type-checked |
516 * an AST node can be type-checked |
542 */ |
517 */ |
543 @SuppressWarnings("fallthrough") |
518 @SuppressWarnings("fallthrough") |
544 List<Type> stuckVars(JCExpression tree, ResultInfo resultInfo) { |
519 List<Type> stuckVars(JCTree tree, ResultInfo resultInfo) { |
545 switch (tree.getTag()) { |
520 if (resultInfo.pt.tag == NONE || resultInfo.pt.isErroneous()) { |
546 case LAMBDA: |
521 return List.nil(); |
547 case REFERENCE: |
522 } else { |
548 Assert.error("not supported yet"); |
523 StuckChecker sc = new StuckChecker(resultInfo); |
549 default: |
524 sc.scan(tree); |
550 return List.nil(); |
525 return List.from(sc.stuckVars); |
|
526 } |
|
527 } |
|
528 |
|
529 /** |
|
530 * This visitor is used to check that structural expressions conform |
|
531 * to their target - this step is required as inference could end up |
|
532 * inferring types that make some of the nested expressions incompatible |
|
533 * with their corresponding instantiated target |
|
534 */ |
|
535 class StuckChecker extends TreeScanner { |
|
536 |
|
537 Type pt; |
|
538 Filter<JCTree> treeFilter; |
|
539 Infer.InferenceContext inferenceContext; |
|
540 Set<Type> stuckVars = new HashSet<Type>(); |
|
541 |
|
542 final Filter<JCTree> argsFilter = new Filter<JCTree>() { |
|
543 public boolean accepts(JCTree t) { |
|
544 switch (t.getTag()) { |
|
545 case CONDEXPR: |
|
546 case LAMBDA: |
|
547 case PARENS: |
|
548 case REFERENCE: |
|
549 return true; |
|
550 default: |
|
551 return false; |
|
552 } |
|
553 } |
|
554 }; |
|
555 |
|
556 final Filter<JCTree> lambdaBodyFilter = new Filter<JCTree>() { |
|
557 public boolean accepts(JCTree t) { |
|
558 switch (t.getTag()) { |
|
559 case BLOCK: case CASE: case CATCH: case DOLOOP: |
|
560 case FOREACHLOOP: case FORLOOP: case RETURN: |
|
561 case SYNCHRONIZED: case SWITCH: case TRY: case WHILELOOP: |
|
562 return true; |
|
563 default: |
|
564 return false; |
|
565 } |
|
566 } |
|
567 }; |
|
568 |
|
569 StuckChecker(ResultInfo resultInfo) { |
|
570 this.pt = resultInfo.pt; |
|
571 this.inferenceContext = resultInfo.checkContext.inferenceContext(); |
|
572 this.treeFilter = argsFilter; |
|
573 } |
|
574 |
|
575 @Override |
|
576 public void scan(JCTree tree) { |
|
577 if (tree != null && treeFilter.accepts(tree)) { |
|
578 super.scan(tree); |
|
579 } |
|
580 } |
|
581 |
|
582 @Override |
|
583 public void visitLambda(JCLambda tree) { |
|
584 Type prevPt = pt; |
|
585 Filter<JCTree> prevFilter = treeFilter; |
|
586 try { |
|
587 if (inferenceContext.inferenceVars().contains(pt)) { |
|
588 stuckVars.add(pt); |
|
589 } |
|
590 if (!types.isFunctionalInterface(pt.tsym)) { |
|
591 return; |
|
592 } |
|
593 Type descType = types.findDescriptorType(pt); |
|
594 List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes()); |
|
595 if (!TreeInfo.isExplicitLambda(tree) && |
|
596 freeArgVars.nonEmpty()) { |
|
597 stuckVars.addAll(freeArgVars); |
|
598 } |
|
599 pt = descType.getReturnType(); |
|
600 if (tree.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) { |
|
601 scan(tree.getBody()); |
|
602 } else { |
|
603 treeFilter = lambdaBodyFilter; |
|
604 super.visitLambda(tree); |
|
605 } |
|
606 } finally { |
|
607 pt = prevPt; |
|
608 treeFilter = prevFilter; |
|
609 } |
|
610 } |
|
611 |
|
612 @Override |
|
613 public void visitReference(JCMemberReference tree) { |
|
614 scan(tree.expr); |
|
615 if (inferenceContext.inferenceVars().contains(pt)) { |
|
616 stuckVars.add(pt); |
|
617 return; |
|
618 } |
|
619 if (!types.isFunctionalInterface(pt.tsym)) { |
|
620 return; |
|
621 } |
|
622 Type descType = types.findDescriptorType(pt); |
|
623 List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes()); |
|
624 stuckVars.addAll(freeArgVars); |
|
625 } |
|
626 |
|
627 @Override |
|
628 public void visitReturn(JCReturn tree) { |
|
629 Filter<JCTree> prevFilter = treeFilter; |
|
630 try { |
|
631 treeFilter = argsFilter; |
|
632 if (tree.expr != null) { |
|
633 scan(tree.expr); |
|
634 } |
|
635 } finally { |
|
636 treeFilter = prevFilter; |
|
637 } |
551 } |
638 } |
552 } |
639 } |
553 } |
640 } |