/** * Make all inside partitions join in one comment, in particular remove all enclosing comment * tokens of the inside partitions. * * @param commentArea comment area region * @param partition first partition * @param docExtension document * @param factory EditFactory * @param List of edits to update the document * @throws BadLocationException * @throws BadPartitioningException */ private void handleInteriorPartition( IRegion commentArea, ITypedRegion partition, IDocumentExtension3 docExtension, Edit.EditFactory factory, List<Edit> edits) throws BadLocationException, BadPartitioningException { int commentAreaEnd = commentArea.getOffset() + commentArea.getLength(); int prevPartitionEnd = -1; int partitionEnd = partition.getOffset() + partition.getLength(); final int startCommentTokenLength = getCommentStart().length(); final int endCommentTokenLength = getCommentEnd().length(); while (partitionEnd <= commentAreaEnd) { if (partition.getType() == ICPartitions.C_MULTI_LINE_COMMENT || partition.getType() == ICPartitions.C_MULTI_LINE_DOC_COMMENT) { // already in a comment - remove start/end tokens edits.add( factory.createEdit(partition.getOffset(), startCommentTokenLength, "")); // $NON-NLS-1$ edits.add( factory.createEdit( partitionEnd - endCommentTokenLength, endCommentTokenLength, "")); // $NON-NLS-1$ } // advance to next partition prevPartitionEnd = partitionEnd; partition = docExtension.getPartition(ICPartitions.C_PARTITIONING, partitionEnd, false); partitionEnd = partition.getOffset() + partition.getLength(); // break the loop if we get stuck and no advance was made if (partitionEnd <= prevPartitionEnd) break; } }
/** * Handles partition boundaries within the selection. The end of the current partition and the * start of the next partition are examined for whether they contain comment tokens that interfere * with the created comment. * * <p>Comment tokens are removed from interior multi-line comments. Javadoc comments are left as * is; instead, multi-line comment tokens are inserted before and after Javadoc partitions to * ensure that the entire selected area is commented. * * <p>The next partition is returned. * * @param partition the current partition * @param edits the list of edits to add to * @param factory the edit factory * @param docExtension the document to get the partitions from * @return the next partition after the current * @throws BadLocationException if accessing the document fails - this can only happen if the * document gets modified concurrently * @throws BadPartitioningException if the document does not have a Java partitioning */ private ITypedRegion handleInteriorPartition( ITypedRegion partition, List edits, Edit.EditFactory factory, IDocumentExtension3 docExtension) throws BadPartitioningException, BadLocationException { // end of previous partition String partType = partition.getType(); int partEndOffset = partition.getOffset() + partition.getLength(); int tokenLength = getCommentStart().length(); boolean wasJavadoc = false; // true if the previous partition is javadoc if (partType == IJavaScriptPartitions.JS_DOC) { wasJavadoc = true; } else if (partType == IJavaScriptPartitions.JS_COMMENT) { // already in a comment - remove ending mark edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); // $NON-NLS-1$ } // advance to next partition partition = docExtension.getPartition(IJavaScriptPartitions.JS_PARTITIONING, partEndOffset, false); partType = partition.getType(); // start of next partition if (wasJavadoc) { // if previous was javadoc, and the current one is not a comment, // then add a block comment start if (partType == IDocument.DEFAULT_CONTENT_TYPE || isSpecialPartition(partType)) { edits.add(factory.createEdit(partition.getOffset(), 0, getCommentStart())); } } else { // !wasJavadoc if (partType == IJavaScriptPartitions.JS_DOC) { // if next is javadoc, end block comment before edits.add(factory.createEdit(partition.getOffset(), 0, getCommentEnd())); } else if (partType == IJavaScriptPartitions.JS_COMMENT) { // already in a comment - remove startToken edits.add( factory.createEdit( partition.getOffset(), getCommentStart().length(), "")); // $NON-NLS-1$ } } return partition; }
/** * Add enclosing comment tags for the whole area to be commented * * @param commentArea initial comment area which can be adjusted * @param lastPartition last partition * @param doc document * @param factory Edit factory * @param edits List of edits to update the document * @return new possibly adjusted comment area * @throws BadLocationException */ private Region handleEnclosingPartitions( Region commentArea, ITypedRegion lastPartition, IDocument doc, Edit.EditFactory factory, List<Edit> edits) throws BadLocationException { int commentAreaStart = commentArea.getOffset(); int commentAreaEnd = commentArea.getOffset() + commentArea.getLength(); String commentStartTag = getCommentStart(); // "/*" String commentEndTag = getCommentEnd(); // "*/" String startLineEOL = doc.getLineDelimiter(doc.getLineOfOffset(commentAreaStart)); if (startLineEOL == null) startLineEOL = ""; // $NON-NLS-1$ String endLineEOL = doc.getLineDelimiter(doc.getLineOfOffset(commentAreaEnd - 1)); if (endLineEOL == null) endLineEOL = ""; // $NON-NLS-1$ boolean isLeftEol = commentAreaStart < startLineEOL.length() || doc.get(commentAreaStart - startLineEOL.length(), startLineEOL.length()) .equals(startLineEOL); boolean isRightEol = doc.get(commentAreaEnd - endLineEOL.length(), endLineEOL.length()).equals(endLineEOL); if (isLeftEol && isRightEol) { // Block of full lines found int areaStartLine = doc.getLineOfOffset(commentAreaStart + startLineEOL.length()); int areaEndLine = doc.getLineOfOffset(commentAreaEnd - endLineEOL.length()); if (areaStartLine != areaEndLine) { // If multiple full lines arrange inserting comment tags on their own lines commentStartTag = getCommentStart() + startLineEOL; commentEndTag = getCommentEnd() + endLineEOL; } else { // If one full line insert end comment tag on the same line (before the EOL) commentAreaEnd = commentAreaEnd - endLineEOL.length(); } } else { if (lastPartition.getType() == ICPartitions.C_SINGLE_LINE_COMMENT || lastPartition.getType() == ICPartitions.C_SINGLE_LINE_DOC_COMMENT) { // C++ comments "//" partition ends with EOL, insert end comment tag before it // on the same line, so we get something like /*// text*/ commentAreaEnd = commentAreaEnd - endLineEOL.length(); } } edits.add(factory.createEdit(commentAreaStart, 0, commentStartTag)); edits.add(factory.createEdit(commentAreaEnd, 0, commentEndTag)); return new Region(commentAreaStart, commentAreaEnd - commentAreaStart); }
/** * Handles the partition under the end of the selection. For normal java code, the comment end * token is inserted at the selection end; if the selection ends inside a special (i.e. string, * character, line comment) partition, the entire partition is included inside the comment. * * @param partition the partition under the selection end offset * @param edits the list of edits to add to * @param factory the edit factory * @param endOffset the end offset of the selection */ private void handleLastPartition( ITypedRegion partition, List edits, Edit.EditFactory factory, int endOffset) throws BadLocationException { String partType = partition.getType(); if (partType == IDocument.DEFAULT_CONTENT_TYPE) { // normal java: end comment where selection ends edits.add(factory.createEdit(endOffset, 0, getCommentEnd())); } else if (isSpecialPartition(partType)) { // special types: consume entire partition edits.add( factory.createEdit(partition.getOffset() + partition.getLength(), 0, getCommentEnd())); } }
/** * Handle the partition under the start offset of the selection. * * @param partition the partition under the start of the selection * @param edits the list of edits to later execute * @param factory the factory for edits * @param offset the start of the selection, which must lie inside <code>partition</code> */ private void handleFirstPartition( ITypedRegion partition, List edits, Edit.EditFactory factory, int offset) throws BadLocationException { int partOffset = partition.getOffset(); String partType = partition.getType(); Assert.isTrue(partOffset <= offset, "illegal partition"); // $NON-NLS-1$ // first partition: mark start of comment if (partType == IDocument.DEFAULT_CONTENT_TYPE) { // Java code: right where selection starts edits.add(factory.createEdit(offset, 0, getCommentStart())); } else if (isSpecialPartition(partType)) { // special types: include the entire partition edits.add(factory.createEdit(partOffset, 0, getCommentStart())); } // javadoc: no mark, will only start after comment }