Ejemplo n.º 1
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;
          }
        });
  }