Пример #1
0
 private SNode searchInSuperTypes(SNode subType, CoercionMatcher superType, boolean isWeak) {
   StructuralNodeSet<?> frontier = new StructuralNodeSet();
   StructuralNodeSet<?> newFrontier = new StructuralNodeSet();
   StructuralNodeSet<?> yetPassed = new StructuralNodeSet();
   frontier.add(subType);
   while (!frontier.isEmpty()) {
     Set<SNode> yetPassedRaw = new THashSet<SNode>();
     // collecting a set of frontier's ancestors
     StructuralNodeSet<?> ancestors = new StructuralNodeSet();
     for (SNode node : frontier) {
       mySubTyping.collectImmediateSuperTypes(node, isWeak, ancestors, null);
       yetPassedRaw.add(node);
     }
     ArrayList<SNode> ancestorsSorted;
     ancestorsSorted = new ArrayList<SNode>(ancestors);
     Collections.sort(
         ancestorsSorted,
         new Comparator<SNode>() {
           public int compare(SNode o1, SNode o2) {
             return TypesUtil.depth(o2) - TypesUtil.depth(o1);
           }
         });
     List<SNode> results = new ArrayList<SNode>();
     for (SNode ancestor : ancestorsSorted) {
       if (superType.matchesWith(ancestor)) {
         results.add(ancestor);
       }
     }
     if (!results.isEmpty()) {
       if (results.size() > 1) {
         results = mySubTyping.eliminateSuperTypes(results);
       }
       if (!results.isEmpty()) {
         return results.get(0);
       }
     }
     for (SNode passedNodeRaw : yetPassedRaw) {
       yetPassed.add(passedNodeRaw);
     }
     for (SNode passedNode : yetPassed) {
       ancestors.removeStructurally(passedNode);
     }
     for (SNode ancestor : ancestors) {
       Pair<Boolean, SNode> answer =
           getCoerceCacheAnswer(ancestor, superType.getMatchingPattern(), isWeak);
       if (answer != null) {
         if (answer.o1 && answer.o2 == null) {
           // System.out.println("coerce optimized");
           continue;
         }
       }
       newFrontier.addStructurally(ancestor);
       yetPassed.addStructurally(ancestor);
     }
     frontier = newFrontier;
     newFrontier = new StructuralNodeSet();
   }
   return null;
 }
Пример #2
0
  public SNode coerceSubTypingNew(
      final SNode subtype,
      final IMatchingPattern pattern,
      final boolean isWeak,
      final State state) {
    if (subtype == null) return null;
    if (pattern.match(subtype)) return subtype;
    if (!CoerceUtil.canBeCoerced(subtype, pattern.getConceptFQName())) return null;
    if ("jetbrains.mps.lang.typesystem.structure.MeetType".equals(subtype.getConceptFqName())) {
      List<SNode> children = subtype.getChildren("argument");
      for (SNode child : children) {
        SNode result = coerceSubTypingNew(child, pattern, isWeak, state);
        if (result != null) return result;
      }
      return null;
    }
    final TypeCheckingContextNew typeCheckingContext =
        state == null ? null : state.getTypeCheckingContext();
    if ("jetbrains.mps.lang.typesystem.structure.JoinType".equals(subtype.getConceptFqName())) {
      List<SNode> children = subtype.getChildren("argument");

      SNode lcs = mySubTyping.createLCS(children, typeCheckingContext);
      return coerceSubTypingNew(lcs, pattern, isWeak, state);
    }

    // asking the cache
    return NodeReadAccessCasterInEditor.runReadTransparentAction(
        new Computable<SNode>() {
          public SNode compute() {
            Pair<Boolean, SNode> answer = getCoerceCacheAnswer(subtype, pattern, isWeak);
            if (answer != null && answer.o1) {
              return answer.o2;
            }
            CoercionMatcher coercionMatcher = new CoercionMatcher(pattern);
            SNode result = searchInSuperTypes(subtype, coercionMatcher, isWeak);
            // writing to the cache
            SubtypingCache subtypingCache = myTypeChecker.getSubtypingCache();
            if (subtypingCache != null) {
              subtypingCache.cacheCoerce(subtype, pattern, result, isWeak);
            }
            subtypingCache = myTypeChecker.getGlobalSubtypingCache();
            if (subtypingCache != null) {
              subtypingCache.cacheCoerce(subtype, pattern, result, isWeak);
            }

            return result;
          }
        });
  }