/* Alloy Analyzer 4 -- Copyright (c) 2006-2009, Felix Chang * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package edu.mit.csail.sdg.alloy4compiler.ast; import edu.mit.csail.sdg.alloy4.ErrorSyntax; import edu.mit.csail.sdg.alloy4.Pos; import edu.mit.csail.sdg.alloy4.Util; /** Immutable; reresents a scope in a "run" or "check" command. * * <p> <b>Invariant:</b> sig != null * <p> <b>Invariant:</b> endingScope >= startingScope >= 0 * <p> <b>Invariant:</b> increment > 0 */ public class CommandScope { /** The position in the original source file where this scope was declared; can be Pos.UNKNOWN if unknown. */ public final Pos pos; /** The sig whose scope is being given by this CommandScope object. */ public final Sig sig; /** True iff the scope is an exact scope. */ public final boolean isExact; /** The starting scope. */ public final int startingScope; /** The ending scope; if this sig is not a growing sig, then this.startingScope==this.endingScope. */ public final int endingScope; /** The scope increment; if this sig is not a growing sig, then this.increment is ignored. */ public final int increment; /** Construct a new CommandScope object. * @param sig - the sig for this scope * @param isExact - true iff the scope is intended to be exact * @param scope - the scope * @throws ErrorSyntax if scope is less than zero */ public CommandScope(Sig sig, boolean isExact, int scope) throws ErrorSyntax { this(null, sig, isExact, scope, scope, 1); } /** Construct a new CommandScope object. * @param pos - the position where this scope is given * @param sig - the sig for this scope * @param isExact - true iff the scope is intended to be exact * @param startingScope - the starting scope * @param endingScope - the ending scope (if this sig is not intended to be growable, then startingScope should equal endingScope) * @param increment - the scope increment (if this sig is not intended to be growable, then this field is ignored) * @throws ErrorSyntax if startingScope is less than zero * @throws ErrorSyntax if endingScope is less than startingScope * @throws ErrorSyntax if increment is less than one */ public CommandScope(Pos pos, Sig sig, boolean isExact, int startingScope, int endingScope, int increment) throws ErrorSyntax { if (pos == null) pos = Pos.UNKNOWN; if (sig == null) throw new NullPointerException(); if (startingScope < 0) throw new ErrorSyntax(pos, "Sig "+sig+" cannot have a negative starting scope ("+startingScope+")"); if (endingScope < 0) throw new ErrorSyntax(pos, "Sig "+sig+" cannot have a negative ending scope ("+endingScope+")"); if (endingScope < startingScope) throw new ErrorSyntax(pos, "Sig "+sig+" cannot have an ending scope ("+endingScope+") smaller than its starting scope ("+startingScope+")"); if (startingScope == endingScope) increment = 1; if (increment < 1) throw new ErrorSyntax(pos, "Sig "+sig+"'s increment value cannot be "+increment+".\nThe increment must be 1 or greater."); this.pos = pos; this.sig = sig; this.isExact = isExact; this.startingScope = startingScope; this.endingScope = endingScope; this.increment = increment; } /** {@inheritDoc} */ @Override public String toString() { return (isExact ? "exactly " : "") + startingScope + (endingScope!=startingScope ? (".."+endingScope) : "") + (increment > 1 ? (":"+increment) : "") + " " + Util.tail(sig.label); } }