Clover coverage report - DrJava Test Coverage (drjava-20110828-r5448)
Coverage timestamp: Sun Aug 28 2011 03:13:33 CDT
file stats: LOC: 269   Methods: 18
NCLOC: 107   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractReducedModel.java 56.7% 53.4% 66.7% 56.2%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.drjava.model.definitions.reducedmodel;
 38   
 39    /** A refactoring of the common code between ReducedModelComment and ReducedModelBrace. Both of the refactored classes
 40    * extend this class.
 41    * @version $Id: AbstractReducedModel.java 5437 2011-08-05 03:48:19Z rcartwright $
 42    * @author JavaPLT
 43    */
 44    public abstract class AbstractReducedModel implements ReducedModelStates {
 45   
 46    /** The character that represents the cursor in toString(). @see #toString() */
 47    public static final char PTR_CHAR = '#';
 48   
 49    /** The reduced model for a document is a list of ReducedTokens (braces and gaps). */
 50    volatile TokenList _tokens;
 51   
 52    /** Keeps track of cursor position in document. */
 53    TokenList.Iterator _cursor;
 54   
 55    /** Constructor. Creates a new reduced model with the cursor at the start of a blank "page." */
 56  3166 public AbstractReducedModel() {
 57  3166 _tokens = new TokenList();
 58  3166 _cursor = _tokens.getIterator();
 59    // we should be pointing to the head of the list
 60  3166 _cursor.setBlockOffset(0);
 61    }
 62   
 63    /** Get the offset into the current ReducedToken.
 64    * @return the number of characters into the token where the cursor sits
 65    */
 66  12307 int getBlockOffset() { return _cursor.getBlockOffset(); }
 67   
 68    /** Change the offset into the current ReducedToken.
 69    * @param offset the number of characters into the token to set the cursor
 70    */
 71  0 void setBlockOffset(int offset) { _cursor.setBlockOffset(offset); }
 72   
 73    /** Absolute offset for testing purposes. We don't keep track of absolute offset as it causes too much confusion
 74    * and trouble.
 75    */
 76  597 public int absOffset() { return absOffset(_cursor); }
 77   
 78    /** Absolute offset of the specified iterator. Inefficient so only used for testing purposes. */
 79  597 public int absOffset(TokenList.Iterator cursor) {
 80  597 int off = cursor.getBlockOffset();
 81  597 TokenList.Iterator it = cursor.copy();
 82  595 if (! it.atStart()) it.prev();
 83   
 84  597 while (! it.atStart()) {
 85  883 off += it.current().getSize();
 86  883 it.prev();
 87    }
 88  597 it.dispose();
 89  597 return off;
 90    }
 91   
 92  0 public int getLength() {
 93  0 TokenList.Iterator it = _tokens.getIterator();
 94  0 it.next();
 95  0 if (it.atEnd()) return 0;
 96  0 int len = 0;
 97  0 while (! it.atEnd()) {
 98  0 len += it.current().getSize();
 99  0 it.next();
 100    }
 101  0 it.dispose();
 102  0 return len;
 103    }
 104   
 105    /* @return the shadowing state of _cursor; only makes sense for ReducedModelComment. */
 106  0 public ReducedModelState getState() { return _cursor.getStateAtCurrent(); }
 107   
 108    /** A toString() replacement for testing - easier to read. */
 109  0 public String simpleString() {
 110  0 final StringBuilder val = new StringBuilder();
 111  0 ReducedToken tmp;
 112   
 113  0 TokenList.Iterator it = _tokens.getIterator();
 114  0 it.next(); // since we start at the head, which has no current item
 115   
 116  0 if (_cursor.atStart()) val.append(PTR_CHAR).append(_cursor.getBlockOffset());
 117   
 118  0 while (!it.atEnd()) {
 119  0 tmp = it.current();
 120   
 121  0 if (!_cursor.atStart() && !_cursor.atEnd() && (tmp == _cursor.current())) {
 122  0 val.append(PTR_CHAR).append(_cursor.getBlockOffset());
 123    }
 124   
 125  0 val.append('|').append(tmp).append('|').append(" ");
 126  0 it.next();
 127    }
 128   
 129  0 if (_cursor.atEnd()) val.append(PTR_CHAR).append(_cursor.getBlockOffset());
 130   
 131  0 val.append("|end|");
 132  0 it.dispose();
 133  0 return val.toString();
 134    }
 135   
 136    /** Inserts a character into the reduced model. A method to be implemented in each specific reduced sub-model. */
 137    public abstract void insertChar(char ch);
 138   
 139    /** Inserts a block of text into the reduced model which has no
 140    * special consideration in the reduced model.
 141    * <OL>
 142    * <li> atStart: if gap to right, augment first gap, else insert
 143    * <li> atEnd: if gap to left, augment left gap, else insert
 144    * <li> inside a gap: grow current gap, move offset by length
 145    * <li> inside a multiple character brace:
 146    * <ol>
 147    * <li> break current brace
 148    * <li> insert new gap
 149    * </ol>
 150    * <li> gap to left: grow that gap and set offset to zero
 151    * <li> gap to right: this case handled by inside gap (offset invariant)
 152    * <li> between two braces: insert new gap
 153    * @param length the length of the inserted text
 154    */
 155  117164 public void _insertGap( int length ) {
 156  117164 if (_cursor.atStart()) {
 157  1310 if (_gapToRight()) {
 158  0 _cursor.next();
 159  0 _augmentCurrentGap(length); //increases gap and moves offset
 160    }
 161  1310 else _insertNewGap(length);//inserts gap and goes to next item
 162    }
 163  115854 else if (_cursor.atEnd()) {
 164  112024 if (_gapToLeft()) {
 165  106367 _augmentGapToLeft(length);
 166    //increases the gap to the left and
 167    //cursor to next item in list leaving offset 0
 168    }
 169  5657 else _insertNewGap(length); //inserts gap and moves to next item
 170    }
 171    // should we insert a Gap in between the characters of a multiple char brace
 172  3830 else if ((_cursor.getBlockOffset() > 0) && _cursor.current().isMultipleCharBrace())
 173  9 insertGapBetweenMultiCharBrace(length);
 174    // inserting inside a Gap
 175  3821 else if (_cursor.current().isGap()) {
 176  3552 _cursor.current().grow(length);
 177  3552 _cursor.setBlockOffset(_cursor.getBlockOffset() + length);
 178    }
 179  269 else if (!_cursor.atFirstItem() && _cursor.prevItem().isGap())
 180    //already pointing to next item
 181  225 _cursor.prevItem().grow(length);
 182    else //between two braces
 183  44 _insertNewGap(length); //inserts a gap and goes to the next item
 184  117164 return;
 185    }
 186   
 187    /** Inserts a gap between a multiple character brace.
 188    * Because ReducedModelBrace does not keep track of multiple character
 189    * braces, only (),{}, and [], it differed in its implementation of
 190    * inserGap(int) from ReducedModelComment's. To pull out the otherwise
 191    * identical code and place it here, we created this function to do
 192    * something meaningful in ReducedModelComment and to throw an exception
 193    * in ReducedModelBrace.
 194    */
 195    protected abstract void insertGapBetweenMultiCharBrace(int length);
 196   
 197    /** Make a copy of the token list's iterator. */
 198  0 public TokenList.Iterator makeCopyCursor() { return _cursor.copy(); }
 199   
 200    /** Determines if there is a Gap immediately to the right of the cursor. */
 201  1310 protected boolean _gapToRight() {
 202    // Before using, make sure not at last, or tail.
 203  1310 return (! _tokens.isEmpty() && ! _cursor.atEnd() && ! _cursor.atLastItem() && _cursor.nextItem().isGap());
 204    }
 205   
 206    /** Determines if there is a gap immediately to the left of the cursor. */
 207  112024 protected boolean _gapToLeft() {
 208    // Before using, make sure not at first or head.
 209  112024 return (! _tokens.isEmpty() && ! _cursor.atStart() && ! _cursor.atFirstItem() && _cursor.prevItem().isGap());
 210    }
 211   
 212    /** Assuming there is a gap to the left, this function increases the size of that gap.
 213    * @param length the amount of increase
 214    */
 215  106367 protected void _augmentGapToLeft(int length) { _cursor.prevItem().grow(length); }
 216   
 217    /** Assuming there is a gap to the right, this function increases the size of that gap.
 218    * @param length the amount of increase
 219    */
 220  0 protected void _augmentCurrentGap(int length) {
 221  0 _cursor.current().grow(length);
 222  0 _cursor.setBlockOffset(length);
 223    }
 224   
 225    /** Helper function for _insertGap. Performs the actual insert and marks the offset appropriately.
 226    * @param length size of gap to insert
 227    */
 228  7020 protected void _insertNewGap(int length) {
 229  7020 _cursor.insert(new Gap(length, _cursor.getStateAtCurrent()));
 230  7020 _cursor.next();
 231  7020 _cursor.setBlockOffset(0);
 232    }
 233   
 234    /** Returns the state at the relLocation, where relLocation is the location relative to the walker.
 235    * @param relLocation distance from walker to get state at.
 236    */
 237    protected abstract ReducedModelState moveWalkerGetState(int relLocation);
 238   
 239    /** Resets the walker to the current position in document. */
 240    protected abstract void resetWalkerLocationToCursor();
 241   
 242    /** Get the ReducedToken currently pointed at by the cursor.
 243    * @return the current token
 244    */
 245  4661 protected ReducedToken current() { return _cursor.current(); }
 246   
 247    /** Move to the token immediately right. This function forwards its responsibilities to the cursor.
 248    * If the cursor is at the end, it will throw an exception.
 249    */
 250  4090 protected void next() { _cursor.next(); }
 251   
 252    /** Move to the token immediately left. This function forwards its responsibilities to the TokenList iterator. If the
 253    * cursor is at the start, it will throw an exception.
 254    */
 255  4090 protected void prev() { _cursor.prev(); }
 256   
 257    // Never used
 258    // /** Determines whether the char at index pos with text is the start of a comment: "/*" or "//" */
 259    // public static boolean isStartOfComment(String text, int pos) {
 260    // char currChar = text.charAt(pos);
 261    // if (currChar == '/') {
 262    // try {
 263    // char afterCurrChar = text.charAt(pos + 1);
 264    // if ((afterCurrChar == '/') || (afterCurrChar == '*')) return true;
 265    // } catch (StringIndexOutOfBoundsException e) { }
 266    // }
 267    // return false;
 268    // }
 269    }