/** format a CDATA region, preserving indenting within the CDATA */ private void formatCDATA(TypedPosition region, StringBuffer buffer) throws BadLocationException { LineWalker lineWalker = new LineWalker(fDocument, region, fPositions); LineInfo info = lineWalker.nextLine(); int firstIndent = getIndent(info.offset); info.trimData(); int writeOffset = writeLine(info.data, fInitialIndent, fIndentLevel, buffer); info.setWriteOffset(writeOffset); fLineInfos.add(info); while (lineWalker.hasMoreLines()) { info = lineWalker.nextLine(); int indentDelta = getIndent(info.data) - firstIndent; String line = info.trimData(); if (line.length() > 0) { int indent = indentDelta > 0 ? fInitialIndent + indentDelta : fInitialIndent; writeOffset = writeLine(info.data, indent, fIndentLevel, buffer); info.setWriteOffset(writeOffset); fLineInfos.add(info); } else { buffer.append(fLineDelimiter); } } }
/** * format a tag. Attributes, if starting on a new line, are given an additional indent TODO update * this comment for the new magical multiline handline */ protected void formatTag(TypedPosition tposition, StringBuffer buffer, boolean collapseAlways) throws BadLocationException { LineWalker lineWalker = new LineWalker(fDocument, tposition, fPositions); if (lineWalker.isMultiline() && (fPreferences.wrapLongTags() || collapseAlways)) // if (false) { formatMultiLineStartTag(lineWalker, buffer); return; } int count = 0; boolean first = true; while (lineWalker.hasMoreLines()) { LineInfo info = lineWalker.nextLine(); String line = info.trimData(); if (line.length() > 0) { int indentLevel = count > 0 ? fIndentLevel + 1 : fIndentLevel; int writeOffset = writeLine(info.data, fInitialIndent, indentLevel, buffer); info.setWriteOffset(writeOffset); fLineInfos.add(info); count++; } } }
public void setUp() { fileInfo = new FileInfo("package", "filename"); LineInfo li = new LineInfo(); li.setExecCount(1); li.setInstrumented(true); li.setSourceLine("abc"); fileInfo.addLine(li); }
public Object clone() { LineInfo lineInfo = new LineInfo( this.fileId, this.inputStartLine, this.repeatCount, this.outputStartLine, this.outputLineIncrement); lineInfo.setFileInfo(this.fileInfo); return lineInfo; }
/** * default formatting. Everything is aligned, one indent level above the nearest enclosing opening * element, if any */ protected void formatDefault(TypedPosition region, StringBuffer buffer) throws BadLocationException { LineWalker lineWalker = new LineWalker(fDocument, region, fPositions); boolean alreadyKept = false; while (lineWalker.hasMoreLines()) { LineInfo info = lineWalker.nextLine(); if (info.isEmpty()) { info.setWriteOffset(writeEmpty(buffer)); fLineInfos.add(info); } else { String line = info.trimData(); if (line.length() > 0) { int off = writeLine(info.data, fInitialIndent, fIndentLevel, buffer); info.setWriteOffset(off); fLineInfos.add(info); } else if (fPreferences.preserveBlankLines() && !alreadyKept) { int off = writeLine("", fInitialIndent, fIndentLevel, buffer); info.setWriteOffset(off); fLineInfos.add(info); // buffer.append(fLineDelimiter); alreadyKept = true; } else { int off = writeEmpty(buffer); info.setWriteOffset(off); fLineInfos.add(info); } } } }
/** * A wrapper for the lower-level <code>markTokensImpl</code> method that is called to split a line * up into tokens. * * @param line The line * @param lineIndex The line number */ public Token markTokens(Segment line, int lineIndex) { if (lineIndex >= length) { throw new IllegalArgumentException("Tokenizing invalid line: " + lineIndex); } lastToken = null; LineInfo info = lineInfo[lineIndex]; LineInfo prev; if (lineIndex == 0) prev = null; else prev = lineInfo[lineIndex - 1]; byte oldToken = info.token; byte token = markTokensImpl(prev == null ? Token.NULL : prev.token, line, lineIndex); info.token = token; /* * This is a foul hack. It stops nextLineRequested from being cleared if the same line is marked twice. * * Why is this necessary? It's all JEditTextArea's fault. When something is inserted into the text, firing a document event, the insertUpdate() method shifts the caret (if necessary) by the amount inserted. * * All caret movement is handled by the select() method, which eventually pipes the new position to scrollTo() and calls repaint(). * * Note that at this point in time, the new line hasn't yet been painted; the caret is moved first. * * scrollTo() calls offsetToX(), which tokenizes the line unless it is being called on the last line painted (in which case it uses the text area's painter cached token list). What scrollTo() does next is irrelevant. * * After scrollTo() has done it's job, repaint() is called, and eventually we end up in paintLine(), whose job is to paint the changed line. It, too, calls markTokens(). * * The problem was that if the line started a multiline token, the first markTokens() (done in offsetToX()) would set nextLineRequested (because the line end token had changed) but the second would clear it (because the line was the same that * time) and therefore paintLine() would never know that it needed to repaint subsequent lines. * * This bug took me ages to track down, that's why I wrote all the relevant info down so that others wouldn't duplicate it. */ if (!(lastLine == lineIndex && nextLineRequested)) nextLineRequested = (oldToken != token); lastLine = lineIndex; addToken(0, Token.END); return firstToken; }
/** * Inserts the specified string into the source at the current location * * @param str the string to insert. */ public void insert(String str) { LineInfo line = lines.get(lineno - 1); int originalColno = colno; if (line.edits == null) { line.edits = new ArrayList<Integer>(); } Iterator<Integer> iter = line.edits.iterator(); // Adjust colno to account for prior insertions while (iter.hasNext()) { int offset = iter.next(); int count = iter.next(); if (offset <= colno) { colno += count; } else { break; } } // insert the string at position colno line.str = line.str.substring(0, colno) + str + line.str.substring(colno); line.edits.add(originalColno); line.edits.add(str.length()); modified = true; }
protected void formatMultiLineStartTag(LineWalker lineWalker, StringBuffer buffer) throws BadLocationException { LineInfo info = lineWalker.nextLine(); String line = info.trimDataLeadingAndTrailing(); int count = 0; // get the first non empty line while (line.length() <= 0 && lineWalker.hasMoreLines()) { info = lineWalker.nextLine(); line = info.trimDataLeadingAndTrailing(); } if (line.length() > 0) { // format the first line int indentLevel = fIndentLevel; int writeOffset = writeLine(info.data, fInitialIndent, indentLevel, buffer, false); info.setWriteOffset(writeOffset); fLineInfos.add(info); count++; } while (lineWalker.hasMoreLines()) { info = lineWalker.nextLine(); line = info.trimDataLeadingAndTrailing(); if (line.length() > 0) { int writeOffset = append(info.data, buffer); info.setWriteOffset(writeOffset); fLineInfos.add(info); count++; } } if (count > 0) buffer.append(fLineDelimiter); }
protected Object doFormat(TypedPosition partition) throws BadLocationException { // determine the enclosing element and the appropriate indent TypedPositionWalker walker = new TypedPositionWalker(fDocumentPositions, fOffset); for (TypedPosition tposition = walker.previous(); tposition != null; tposition = walker.previous()) { String type = tposition.getType(); if (type == ITypeConstants.TAG || type == ITypeConstants.EMPTYTAG) { fInitialIndent = getIndent(tposition.getOffset()); if (type != ITypeConstants.EMPTYTAG) fIndentLevel++; break; } else if (type == ITypeConstants.ENDTAG) { fInitialIndent = getIndent(tposition.getOffset()); break; } } // walk through the partitions and format walker = new TypedPositionWalker(fDocumentPositions, fOffset, partition.length); StringBuffer buffer = new StringBuffer(); TypedPosition tposition = walker.next(); while (tposition != null) { String type = tposition.getType(); if (type == ITypeConstants.TAG || type == ITypeConstants.EMPTYTAG) { formatTag(tposition, buffer, false); if (type == ITypeConstants.TAG) fIndentLevel++; } else if (type == ITypeConstants.ENDTAG) { if (fIndentLevel > 0) fIndentLevel--; formatTag(tposition, buffer, true); } else if (type == ITypeConstants.DECL) { XMLNode artifact = (XMLNode) tposition; String content = artifact.getContent(); if (content.indexOf("DOCTYPE") >= 0) { formatTag(tposition, buffer, true); } else { formatCDATA(tposition, buffer); } } else if (type == ITypeConstants.COMMENT) { formatDefault(tposition, buffer); } else if (type == ITypeConstants.TEXT) { formatDefault(tposition, buffer); } else if (type == ITypeConstants.PI) { formatTag(tposition, buffer, true); } tposition = walker.next(); } // finally, have the line infos update the positions array Iterator it = fLineInfos.iterator(); while (it.hasNext()) { LineInfo info = (LineInfo) it.next(); info.updatePositions(); } return buffer.toString(); }