001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2005-2006 Robert Grimm
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.parser;
020:
021: import java.util.ArrayList;
022:
023: import xtc.Constants;
024:
025: import xtc.tree.Node;
026:
027: /**
028: * A grammar module dependency. Note that two module dependencies are
029: * equal if they describe the same module.
030: *
031: * @author Robert Grimm
032: * @version $Revision: 1.15 $
033: */
034: public abstract class ModuleDependency extends Node {
035:
036: /** The name of the dependent module. */
037: public ModuleName module;
038:
039: /** The arguments to the dependent module. */
040: public ModuleList arguments;
041:
042: /** The optional target module name. */
043: public ModuleName target;
044:
045: /**
046: * Create a new module dependency. If the specified arguments are
047: * <code>null</code>, they are replaced with an empty module list.
048: * If the specified target equals the module name, it is replaced by
049: * <code>null</code>.
050: *
051: * @param module The module name.
052: * @param arguments The arguments.
053: * @param target The target module name.
054: */
055: public ModuleDependency(ModuleName module, ModuleList arguments,
056: ModuleName target) {
057: this .module = module;
058: if (null == arguments) {
059: this .arguments = new ModuleList(
060: new ArrayList<ModuleName>(0));
061: } else {
062: this .arguments = arguments;
063: }
064: if (module.equals(target)) {
065: this .target = null;
066: } else {
067: this .target = target;
068: }
069: }
070:
071: public int hashCode() {
072: if (null == target) {
073: return module.hashCode();
074: } else {
075: return target.hashCode();
076: }
077: }
078:
079: public boolean equals(Object o) {
080: if (this == o)
081: return true;
082: if (!(o instanceof ModuleDependency))
083: return false;
084: ModuleDependency other = (ModuleDependency) o;
085: if (!module.equals(other.module))
086: return false;
087: if (null == target) {
088: if (null != other.target)
089: return false;
090: } else {
091: if (!target.equals(other.target))
092: return false;
093: }
094: return arguments.equals(other.arguments);
095: }
096:
097: /**
098: * Determine whether this dependency is a {@link ModuleImport module
099: * import}.
100: *
101: * @return <code>true</code> if this dependency is an import.
102: */
103: public boolean isImport() {
104: return false;
105: }
106:
107: /**
108: * Determine whether this dependency is a {@link ModuleInstantiation
109: * module instantiation}.
110: *
111: * @return <code>true</code> if this dependency is an instantiation.
112: */
113: public boolean isInstantiation() {
114: return false;
115: }
116:
117: /**
118: * Determine whether this dependency is a {@link ModuleModification
119: * module modification}.
120: *
121: * @return <code>true</code> if this dependency is a modification.
122: */
123: public boolean isModification() {
124: return false;
125: }
126:
127: /**
128: * Get the visible name for this module dependency. The visible
129: * name is the qualifier available for nonterminals referencing
130: * productions in the dependent module.
131: *
132: * @return The visible name.
133: */
134: public ModuleName visibleName() {
135: return (null == target) ? module : target;
136: }
137:
138: /**
139: * Determine whether this module dependency is consistent with the
140: * specified dependency, which has been resolved previously.
141: *
142: * @param dep The previously resolved dependency.
143: * @return <code>true</code> if this module dependency is consistent
144: * with the specified one.
145: */
146: public boolean isConsistentWith(ModuleDependency dep) {
147: return ((!visibleName().equals(dep.visibleName()))
148: || this .equals(dep) || ((0 == arguments.size()) && (null == target)));
149: }
150:
151: /**
152: * Rename this module dependency. This method modifies this module
153: * dependency based on the specified module map. If any module name
154: * is renamed, the new module name's {@link Constants#ORIGINAL
155: * original} property is set to the original module name.
156: *
157: * @param renaming The module map.
158: * @return This module dependency.
159: */
160: public ModuleDependency rename(ModuleMap renaming) {
161: module = module.rename(renaming);
162: arguments = arguments.rename(renaming);
163: if (null != target) {
164: target = target.rename(renaming);
165: }
166: return this;
167: }
168:
169: }
|