Example #1
0
 protected JL5Call_c reconstruct(Receiver target, List arguments, List typeArgs) {
   if (target != this.target
       || !CollectionUtil.equals(arguments, this.arguments)
       || !CollectionUtil.equals(typeArgs, this.typeArguments)) {
     JL5Call_c n = (JL5Call_c) copy();
     n.target = target;
     n.arguments = TypedList.copyAndCheck(arguments, Expr.class, true);
     n.typeArguments = TypedList.copyAndCheck(typeArgs, TypeNode.class, false);
     return n;
   }
   return this;
 }
Example #2
0
  /** Reconstruct the statement. */
  protected For_c reconstruct(List inits, Expr cond, List iters, Stmt body) {
    if (!CollectionUtil.equals(inits, this.inits)
        || cond != this.cond
        || !CollectionUtil.equals(iters, this.iters)
        || body != this.body) {
      For_c n = (For_c) copy();
      n.inits = TypedList.copyAndCheck(inits, ForInit.class, true);
      n.cond = cond;
      n.iters = TypedList.copyAndCheck(iters, ForUpdate.class, true);
      n.body = body;
      return n;
    }

    return this;
  }
Example #3
0
 /** Reconstruct the statement expression. */
 protected StmtExpr_c reconstruct(List<Stmt> statements, Expr result) {
   if (!CollectionUtil.allEqual(statements, this.statements) || result != this.result) {
     StmtExpr_c n = (StmtExpr_c) copy();
     n.statements = TypedList.copyAndCheck(statements, Stmt.class, true);
     n.result = result;
     return n;
   }
   return this;
 }
  /** Returns true if the procedure has the given formal parameter types. */
  public boolean hasFormals(
      List<Type> otherFormalTypes,
      List<TypeVariable> otherTypeVariables,
      List<Type> typeArguments,
      Context context) {
    if (isGeneric() != isGeneric(otherTypeVariables)) return false;
    if (formalTypes().size() != otherFormalTypes.size()) return false;
    if (isGeneric() && typeVariables().size() != otherTypeVariables.size()) return false;

    if (!CollectionUtil.allElementwise(
        this.typeVariables(), otherTypeVariables, new TypeVariableEquals(context))) {
      return false;
    }

    if (!CollectionUtil.allElementwise(
        this.formalTypes(), otherFormalTypes, new TypeEquals(context))) {
      return false;
    }

    return true;
  }
  /**
   * Find a type object in the context of the class.
   *
   * @param name The name to search for.
   */
  public Named find(Matcher<Named> matcher, Context context) throws SemanticException {
    Name name = matcher.name();

    if (Report.should_report(TOPICS, 2)) Report.report(2, "Looking for " + name + " in " + this);

    if (!(type instanceof ClassType)) {
      throw new NoClassException(name.toString(), type);
    }

    ClassType type = (ClassType) this.type;

    Named m = null;

    QName fullName = null;
    QName rawName = null;

    if (type.isGloballyAccessible()) {
      fullName = QName.make(type.fullName(), name);
      QName q = ts.getTransformedClassName(type.def());
      rawName = QName.make(q.qualifier(), Name.make(q.name() + "$" + name));
    }

    if (fullName != null) {
      // First check the system resolver.
      m = ts.systemResolver().check(fullName);

      // Try the raw class file name.
      if (m == null) {
        m = ts.systemResolver().check(rawName);
      }

      if (m == null) {
        // Go to disk, but only if there is no job for the type.
        // If there is a job, all members should be in the resolver
        // already.
        boolean useLoadedResolver = true;

        if (type instanceof ParsedTypeObject) {
          ParsedTypeObject pto = (ParsedTypeObject) type;
          if (pto.job() != null) {
            useLoadedResolver = false;
          }
        }

        if (useLoadedResolver) {
          try {
            m = ts.systemResolver().find(rawName);
          } catch (SemanticException e) {
            // Not found; will fall through to error handling code
          }
        }
      }

      // If we found something, verify that it matches.
      if (m != null) {
        try {
          m = matcher.instantiate(m);
        } catch (SemanticException e) {
          // Doesn't match; try again.
          m = null;
        }
      }
    }

    // Check if the member was explicitly declared.
    if (m == null) {
      m = type.memberTypeMatching(matcher);
    }

    // If we found something, make sure it's accessible.
    if (m instanceof ClassType) {
      ClassType mt = (ClassType) m;

      if (!mt.isMember()) {
        throw new SemanticException(
            "Class " + mt + " is not a member class, " + " but was found in " + type + ".");
      }

      if (!mt.outer().equals((Object) type)) {
        throw new SemanticException(
            "Class " + mt + " is not a member class " + " of " + type + ".");
      }

      return mt;
    }

    if (m instanceof MemberInstance) {
      MemberInstance<?> mi = (MemberInstance<?>) m;

      if (!mi.container().equals((Object) type)) {
        throw new SemanticException("Type " + mi + " is not a member " + " of " + type + ".");
      }
    }

    if (m != null) {
      if (!canAccess(m, context.currentClassDef(), context)) {
        throw new SemanticException("Cannot access member type \"" + m + "\".");
      }
      return m;
    }

    // If we struck out, try the super types.

    // Collect all members of the super types.
    // Use a Set to eliminate duplicates.
    Set<Named> acceptable = new HashSet<Named>();

    if (type.superClass() != null) {
      Type sup = type.superClass();
      if (sup instanceof ClassType) {
        Resolver r = ts.classContextResolver((ClassType) sup, context);
        try {
          Named n = r.find(matcher);
          acceptable.add(n);
        } catch (SemanticException e) {
        }
      }
    }

    for (Iterator<Type> i = type.interfaces().iterator(); i.hasNext(); ) {
      Type sup = (Type) i.next();
      if (sup instanceof ClassType) {
        Resolver r = ts.classContextResolver((ClassType) sup, context);
        try {
          Named n = r.find(matcher);
          acceptable.add(n);
        } catch (SemanticException e) {
        }
      }
    }

    if (acceptable.size() == 0) {
      throw new NoClassException(name.toString(), type);
    } else if (acceptable.size() > 1) {
      Set<Type> containers = new HashSet<Type>(acceptable.size());
      for (Named n : acceptable) {
        if (n instanceof MemberInstance) {
          MemberInstance<?> mi = (MemberInstance<?>) n;
          containers.add(mi.container());
        }
      }

      if (containers.size() == 2) {
        Iterator<Type> i = containers.iterator();
        Type t1 = (Type) i.next();
        Type t2 = (Type) i.next();
        throw new SemanticException(
            "Member \""
                + name
                + "\" of "
                + type
                + " is ambiguous; it is defined in both "
                + t1
                + " and "
                + t2
                + ".");
      } else if (containers.size() == 0) {
        throw new SemanticException("Member \"" + name + "\" of " + type + " is ambiguous.");
      } else {
        throw new SemanticException(
            "Member \""
                + name
                + "\" of "
                + type
                + " is ambiguous; it is defined in "
                + CollectionUtil.listToString(new ArrayList<Type>(containers))
                + ".");
      }
    }

    assert acceptable.size() == 1;

    Named t = acceptable.iterator().next();

    if (Report.should_report(TOPICS, 2)) Report.report(2, "Found member type " + t);

    return t;
  }
 public String signature() {
   return container + "(" + CollectionUtil.listToString(formalTypes) + ")";
 }
/** Loads member classes using a TopLevelResolver that can only handle top-level classes. */
public class MemberClassResolver implements TopLevelResolver {
  protected TypeSystem ts;
  protected TopLevelResolver inner;
  protected boolean allowRawClasses;
  protected Set<String> nocache;

  protected static final Collection<String> report_topics =
      CollectionUtil.list(Report.types, Report.resolver, Report.loader, "mcr");

  /**
   * Create a member class resolver.
   *
   * @param ts The type system
   * @param inner The resolver for top-level classes
   */
  public MemberClassResolver(TypeSystem ts, TopLevelResolver inner, boolean allowRawClasses) {
    this.ts = ts;
    this.inner = inner;
    this.allowRawClasses = allowRawClasses;
    this.nocache = new HashSet<String>();
  }

  @Override
  public boolean packageExists(String name) {
    return inner.packageExists(name);
  }

  /** Find a type by name. */
  @Override
  public Named find(String name) throws SemanticException {
    if (Report.should_report(report_topics, 3)) Report.report(3, "MemberCR.find(" + name + ")");

    if (nocache.contains(name)) {
      throw new NoClassException(name);
    }

    Named n = ts.systemResolver().check(name);

    if (n != null) {
      return n;
    }

    SemanticException error = null;

    // First, just try the long name.
    try {
      if (Report.should_report(report_topics, 2))
        Report.report(2, "MCR: loading " + name + " from " + inner);
      return inner.find(name);
    } catch (SemanticException e) {
      if (Report.should_report(report_topics, 2)) Report.report(2, "MCR: " + e.getMessage());
      if (StringUtil.isNameShort(name)) {
        throw e;
      }
      error = e;
    }

    boolean install = true;

    // Now try the prefix of the name and look for a member class
    // within it named with the suffix.
    String prefix = StringUtil.getPackageComponent(name);
    String suffix = StringUtil.getShortNameComponent(name);

    // Try the full name of the prefix first, then the raw class name,
    // so that encoded type information and source files are preferred
    // to the raw class file.
    try {
      if (Report.should_report(report_topics, 2)) Report.report(2, "MCR: loading prefix " + prefix);

      n = find(prefix);

      // This may be called during deserialization; n's
      // member classes might not be initialized yet.
      if (n instanceof ParsedTypeObject) {
        return findMember(n, suffix);
      }
    } catch (SemanticException e) {
    }

    if (install) {
      nocache.add(name);
    }

    throw error;
  }

  protected Named findMember(Named container, String name) throws SemanticException {
    if (container instanceof ClassType) {
      ClassType ct = (ClassType) container;

      if (Report.should_report(report_topics, 2)) Report.report(2, "MCR: found prefix " + ct);

      // Uncomment if we should search superclasses
      // return ct.resolver().find(name);
      Named n = ct.memberClassNamed(name);

      if (n != null) {
        if (Report.should_report(report_topics, 2))
          Report.report(2, "MCR: found member of " + ct + ": " + n);
        return n;
      }
    }

    throw new NoClassException(container.fullName() + "." + name);
  }
}