/* * xtc - The eXTensible Compiler * Copyright (C) 2005-2006 Robert Grimm * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ package xtc.parser; import java.util.ArrayList; import xtc.Constants; import xtc.tree.Node; /** * A grammar module dependency. Note that two module dependencies are * equal if they describe the same module. * * @author Robert Grimm * @version $Revision: 1.16 $ */ public abstract class ModuleDependency extends Node { /** The name of the dependent module. */ public ModuleName module; /** The arguments to the dependent module. */ public ModuleList arguments; /** The optional target module name. */ public ModuleName target; /** * Create a new module dependency. If the specified arguments are * <code>null</code>, they are replaced with an empty module list. * If the specified target equals the module name, it is replaced by * <code>null</code>. * * @param module The module name. * @param arguments The arguments. * @param target The target module name. */ public ModuleDependency(ModuleName module, ModuleList arguments, ModuleName target) { this.module = module; if (null == arguments) { this.arguments = new ModuleList(new ArrayList<ModuleName>(0)); } else { this.arguments = arguments; } if (module.equals(target)) { this.target = null; } else { this.target = target; } } public int hashCode() { if (null == target) { return module.hashCode(); } else { return target.hashCode(); } } public boolean equals(Object o) { if (this == o) return true; if (! (o instanceof ModuleDependency)) return false; ModuleDependency other = (ModuleDependency)o; if (! module.equals(other.module)) return false; if (null == target) { if (null != other.target) return false; } else { if (! target.equals(other.target)) return false; } return arguments.equals(other.arguments); } /** * Determine whether this dependency is a {@link ModuleImport module * import}. * * @return <code>true</code> if this dependency is an import. */ public boolean isImport() { return false; } /** * Determine whether this dependency is a {@link ModuleInstantiation * module instantiation}. * * @return <code>true</code> if this dependency is an instantiation. */ public boolean isInstantiation() { return false; } /** * Determine whether this dependency is a {@link ModuleModification * module modification}. * * @return <code>true</code> if this dependency is a modification. */ public boolean isModification() { return false; } /** * Get the visible name for this module dependency. The visible * name is the qualifier available for nonterminals referencing * productions in the dependent module. * * @return The visible name. */ public ModuleName visibleName() { return (null == target)? module : target; } /** * Determine whether this module dependency is consistent with the * specified dependency, which has been resolved previously. * * @param dep The previously resolved dependency. * @return <code>true</code> if this module dependency is consistent * with the specified one. */ public boolean isConsistentWith(ModuleDependency dep) { return (! visibleName().equals(dep.visibleName()) || this.equals(dep) || (arguments.isEmpty() && null == target)); } /** * Rename this module dependency. This method modifies this module * dependency based on the specified module map. If any module name * is renamed, the new module name's {@link Constants#ORIGINAL * original} property is set to the original module name. * * @param renaming The module map. * @return This module dependency. */ public ModuleDependency rename(ModuleMap renaming) { module = module.rename(renaming); arguments = arguments.rename(renaming); if (null != target) { target = target.rename(renaming); } return this; } }