IDEA-58423 xml: commenting double dashes produces invalid xml

This commit is contained in:
Dmitry Avdeev
2014-10-16 18:49:29 +04:00
parent a4cdee5220
commit 24b1f59950
3 changed files with 108 additions and 32 deletions
@@ -387,7 +387,7 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
}
public void commentRange(int startOffset, int endOffset, String commentPrefix, String commentSuffix, Commenter commenter) {
CharSequence chars = myDocument.getCharsSequence();
final CharSequence chars = myDocument.getCharsSequence();
LogicalPosition caretPosition = myCaret.getLogicalPosition();
if (startOffset == 0 || chars.charAt(startOffset - 1) == '\n') {
@@ -416,7 +416,7 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
nestingSuffix.append(commentSuffix.startsWith("\n") ? commentSuffix.substring(1) : commentSuffix);
nestingSuffix.append("\n");
TextRange range =
insertNestedComments(chars, startOffset, endOffset, nestingPrefix.toString(), nestingSuffix.toString(), commenter);
insertNestedComments(startOffset, endOffset, nestingPrefix.toString(), nestingSuffix.toString(), commenter);
myCaret.setSelection(range.getStartOffset(), range.getEndOffset());
LogicalPosition pos = new LogicalPosition(caretPosition.line + 1, caretPosition.column);
myCaret.moveToLogicalPosition(pos);
@@ -424,7 +424,7 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
}
}
TextRange range = insertNestedComments(chars, startOffset, endOffset, commentPrefix, commentSuffix, commenter);
TextRange range = insertNestedComments(startOffset, endOffset, commentPrefix, commentSuffix, commenter);
myCaret.setSelection(range.getStartOffset(), range.getEndOffset());
LogicalPosition pos = new LogicalPosition(caretPosition.line, caretPosition.column + commentPrefix.length());
myCaret.moveToLogicalPosition(pos);
@@ -449,8 +449,7 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
}
}
private TextRange insertNestedComments(CharSequence chars,
int startOffset,
private TextRange insertNestedComments(int startOffset,
int endOffset,
String commentPrefix,
String commentSuffix,
@@ -471,6 +470,7 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
IntArrayList nestedCommentSuffixes = new IntArrayList();
String commentedPrefix = commenter.getCommentedBlockCommentPrefix();
String commentedSuffix = commenter.getCommentedBlockCommentSuffix();
CharSequence chars = myDocument.getCharsSequence();
for (int i = startOffset; i < endOffset; ++i) {
if (CharArrayUtil.regionMatches(chars, i, normalizedPrefix)) {
nestedCommentPrefixes.add(i);
@@ -523,7 +523,20 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
shift += commentPrefix.length();
}
return new TextRange(startOffset, endOffset + shift);
TextRange range = new TextRange(startOffset, endOffset + shift);
return processDocument(range, commenter, true);
}
private TextRange processDocument(TextRange range, Commenter commenter, boolean escape) {
if (!(commenter instanceof EscapingCommenter)) return range;
RangeMarker marker = myDocument.createRangeMarker(range);
if (escape) {
((EscapingCommenter)commenter).escape(myDocument, range);
}
else {
((EscapingCommenter)commenter).unescape(myDocument, range);
}
return TextRange.create(marker.getStartOffset(), marker.getEndOffset());
}
private static int getNearest(String text, String pattern, int position) {
@@ -641,6 +654,7 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
return;
}
RangeMarker marker = myDocument.createRangeMarker(range);
String text = myDocument.getCharsSequence().subSequence(range.getStartOffset(), range.getEndOffset()).toString();
int startOffset = range.getStartOffset();
//boolean endsProperly = CharArrayUtil.regionMatches(chars, range.getEndOffset() - commentSuffix.length(), commentSuffix);
@@ -670,5 +684,7 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
commenter);
}
}
processDocument(TextRange.create(marker.getStartOffset(), marker.getEndOffset()), commenter, false);
}
}
@@ -13,37 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.xml;
package com.intellij.codeInsight.generation;
import com.intellij.lang.Commenter;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
/**
* @author max
* @author Dmitry Avdeev
*/
public class XmlCommenter implements Commenter {
public interface EscapingCommenter extends Commenter {
@Override
public String getLineCommentPrefix() {
return null;
}
void escape(Document document, TextRange range);
@Override
public String getBlockCommentPrefix() {
return "<!--";
}
@Override
public String getBlockCommentSuffix() {
return "-->";
}
@Override
public String getCommentedBlockCommentPrefix() {
return "&lt;!&ndash;";
}
@Override
public String getCommentedBlockCommentSuffix() {
return "&ndash;&gt;";
}
void unescape(Document document, TextRange range);
}
@@ -0,0 +1,79 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.xml;
import com.intellij.codeInsight.generation.EscapingCommenter;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author max
*/
public class XmlCommenter implements EscapingCommenter {
private static final String DOUBLE_DASH = "--";
private static final String ESCAPED = "&#45;&#45;";
@Override
public String getLineCommentPrefix() {
return null;
}
@NotNull
@Override
public String getBlockCommentPrefix() {
return "<!--";
}
@NotNull
@Override
public String getBlockCommentSuffix() {
return "-->";
}
@Override
public String getCommentedBlockCommentPrefix() {
return "&lt;!&ndash;";
}
@Override
public String getCommentedBlockCommentSuffix() {
return "&ndash;&gt;";
}
@Override
public void escape(Document document, TextRange range) {
for (int i = range.getEndOffset() - getBlockCommentSuffix().length() - DOUBLE_DASH.length();
i >= range.getStartOffset() + getBlockCommentPrefix().length();
i--) {
if (CharArrayUtil.regionMatches(document.getCharsSequence(), i, DOUBLE_DASH) &&
!CharArrayUtil.regionMatches(document.getCharsSequence(), i, getBlockCommentSuffix())) {
document.replaceString(i, i + DOUBLE_DASH.length(), ESCAPED);
}
}
}
@Override
public void unescape(Document document, TextRange range) {
for (int i = range.getEndOffset(); i >= range.getStartOffset(); i--) {
if (CharArrayUtil.regionMatches(document.getCharsSequence(), i, ESCAPED)) {
document.replaceString(i, i + ESCAPED.length(), DOUBLE_DASH);
}
}
}
}