/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.types; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import polyglot.util.InternalCompilerError; import polyglot.util.StringUtil; /** * A <code>PackageContextResolver</code> is responsible for looking up types * and packages in a package by name. */ public class PackageContextResolver extends AbstractAccessControlResolver { protected Package p; /** * Create a package context resolver. * @param ts The type system. * @param p The package in whose context to search. */ public PackageContextResolver(TypeSystem ts, Package p) { super(ts); this.p = p; } /** * The package in whose context to search. */ public Package package_() { return p; } /** * Find a type object by name. * @param name Name of the class or package to find. * */ public List<Type> find(Matcher<Type> matcher, Context context) throws SemanticException { Name name = matcher.name(); List<Type> tl = null; try { tl = ts.systemResolver().find(QName.make(p.fullName(), name)); } catch (NoClassException e) { // Rethrow if some _other_ class or package was not found. if (!e.getClassName().equals(p.fullName() + "." + name)) { throw e; } } if (tl != null) { List<Type> newTL = new ArrayList<Type>(); for (Type n : tl) { if (! canAccess(n, context)) { throw new SemanticException("Cannot access " + n + " from " + context.currentClassDef() + "."); } try { n = matcher.instantiate(n); } catch (SemanticException e) { n = null; } if (n != null) newTL.add(n); } if (newTL.isEmpty()) { tl = null; } else { tl = newTL; } } return tl; } protected boolean canAccess(Type n, Context context) { if (n instanceof ClassType) { return context == null || ts.classAccessible(((ClassType) n).def(), context); } return true; } public String toString() { return "(package-context " + p.toString() + ")"; } }