WI-11 In files with php extentions and htmls + php inside comments dont work properly

This commit is contained in:
Maxim.Mossienko
2010-06-18 16:54:09 +04:00
parent 22cbcc5dc3
commit 6a80f62113
3 changed files with 124 additions and 30 deletions
@@ -44,9 +44,12 @@ import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.IntArrayList;
import com.intellij.util.text.CharArrayUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class CommentByLineCommentHandler implements CodeInsightActionHandler {
private Project myProject;
private PsiFile myFile;
@@ -59,6 +62,7 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
private int[] myStartOffsets;
private int[] myEndOffsets;
private Commenter[] myCommenters;
private Map<SelfManagingCommenter, SelfManagingCommenter.CommenterDataHolder> myCommenterStateMap;
private CodeStyleManager myCodeStyleManager;
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
@@ -121,8 +125,19 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
if (startingNewLineComment) {
final Commenter commenter = myCommenters[0];
if (commenter != null) {
String prefix = commenter.getLineCommentPrefix();
if (prefix == null) prefix = commenter.getBlockCommentPrefix();
String prefix;
if (commenter instanceof SelfManagingCommenter) {
prefix = ((SelfManagingCommenter)commenter).getCommentPrefix(
myStartLine,
myDocument,
myFile,
myCommenterStateMap.get((SelfManagingCommenter)commenter)
);
} else {
prefix = commenter.getLineCommentPrefix();
if (prefix == null) prefix = commenter.getBlockCommentPrefix();
}
int lineStart = myDocument.getLineStartOffset(myStartLine);
lineStart = CharArrayUtil.shiftForward(myDocument.getCharsSequence(), lineStart, " \t");
lineStart += prefix.length();
@@ -169,6 +184,7 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
myStartOffsets = new int[myEndLine - myStartLine + 1];
myEndOffsets = new int[myEndLine - myStartLine + 1];
myCommenters = new Commenter[myEndLine - myStartLine + 1];
myCommenterStateMap = new THashMap<SelfManagingCommenter, SelfManagingCommenter.CommenterDataHolder>();
CharSequence chars = myDocument.getCharsSequence();
boolean singleline = myStartLine == myEndLine;
@@ -208,14 +224,24 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
}
boolean allLineCommented = true;
for (int line = myStartLine; line <= myEndLine; line++) {
final Commenter commenter = blockSuitableCommenter != null ? blockSuitableCommenter : findCommenter(line);
Commenter commenter = blockSuitableCommenter != null ? blockSuitableCommenter : findCommenter(line);
if (commenter == null) return;
if (commenter.getLineCommentPrefix() == null &&
(commenter.getBlockCommentPrefix() == null || commenter.getBlockCommentSuffix() == null)) {
return;
}
if (commenter instanceof SelfManagingCommenter &&
myCommenterStateMap.get(commenter) == null) {
final SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter)commenter;
SelfManagingCommenter.CommenterDataHolder state =
selfManagingCommenter.createLineCommentingState(myStartLine, myEndLine, myDocument, myFile);
if (state == null) state = SelfManagingCommenter.CommenterDataHolder.EMPTY_STATE;
myCommenterStateMap.put(selfManagingCommenter, state);
}
myCommenters[line - myStartLine] = commenter;
if (!isLineCommented(line, chars, commenter) && (singleline || !isLineEmpty(line))) {
allLineCommented = false;
@@ -271,38 +297,48 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
}
private boolean isLineCommented(final int line, final CharSequence chars, final Commenter commenter) {
String prefix = commenter.getLineCommentPrefix();
boolean commented;
int lineEndForBlockCommenting = -1;
int lineStart = myDocument.getLineStartOffset(line);
lineStart = CharArrayUtil.shiftForward(chars, lineStart, " \t");
boolean commented;
if (prefix != null) {
commented = CharArrayUtil.regionMatches(chars, lineStart, prefix) ||
prefix.endsWith(" ") && CharArrayUtil.regionMatches(chars, lineStart, prefix.trim()+"\n");
if (commented) {
myStartOffsets[line - myStartLine] = lineStart;
myEndOffsets[line - myStartLine] = -1;
}
}
else {
prefix = commenter.getBlockCommentPrefix();
String suffix = commenter.getBlockCommentSuffix();
final int textLength = myDocument.getTextLength();
int lineEnd = myDocument.getLineEndOffset(line);
if (lineEnd == textLength) {
final int shifted = CharArrayUtil.shiftBackward(chars, textLength - 1, " \t");
if (shifted < textLength - 1) lineEnd = shifted;
if (commenter instanceof SelfManagingCommenter) {
final SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter)commenter;
commented = selfManagingCommenter.isCommented(line, lineStart, myDocument, myFile, myCommenterStateMap.get(selfManagingCommenter));
} else {
String prefix = commenter.getLineCommentPrefix();
if (prefix != null) {
commented = CharArrayUtil.regionMatches(chars, lineStart, prefix) ||
prefix.endsWith(" ") && CharArrayUtil.regionMatches(chars, lineStart, prefix.trim()+"\n");
if (commented) {
myStartOffsets[line - myStartLine] = lineStart;
myEndOffsets[line - myStartLine] = -1;
}
}
else {
lineEnd = CharArrayUtil.shiftBackward(chars, lineEnd, " \t");
}
commented = lineStart == lineEnd && myStartLine != myEndLine ||
CharArrayUtil.regionMatches(chars, lineStart, prefix)
&& CharArrayUtil.regionMatches(chars, lineEnd - suffix.length(), suffix);
if (commented) {
myStartOffsets[line - myStartLine] = lineStart;
myEndOffsets[line - myStartLine] = lineEnd;
prefix = commenter.getBlockCommentPrefix();
String suffix = commenter.getBlockCommentSuffix();
final int textLength = myDocument.getTextLength();
lineEndForBlockCommenting = myDocument.getLineEndOffset(line);
if (lineEndForBlockCommenting == textLength) {
final int shifted = CharArrayUtil.shiftBackward(chars, textLength - 1, " \t");
if (shifted < textLength - 1) lineEndForBlockCommenting = shifted;
}
else {
lineEndForBlockCommenting = CharArrayUtil.shiftBackward(chars, lineEndForBlockCommenting, " \t");
}
commented = lineStart == lineEndForBlockCommenting && myStartLine != myEndLine ||
CharArrayUtil.regionMatches(chars, lineStart, prefix)
&& CharArrayUtil.regionMatches(chars, lineEndForBlockCommenting - suffix.length(), suffix);
}
}
if (commented) {
myStartOffsets[line - myStartLine] = lineStart;
myEndOffsets[line - myStartLine] = lineEndForBlockCommenting;
}
return commented;
}
@@ -414,6 +450,13 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
if (commenter == null) return;
final int startOffset = myStartOffsets[line - myStartLine];
if (commenter instanceof SelfManagingCommenter) {
final SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter)commenter;
selfManagingCommenter.uncommentLine(line, startOffset, myDocument, myFile, myCommenterStateMap.get(selfManagingCommenter));
return;
}
final int endOffset = myEndOffsets[line - myStartLine];
if (startOffset == endOffset) {
return;
@@ -471,6 +514,12 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
private void commentLine(int line, int offset, @Nullable Commenter commenter) {
if (commenter == null) commenter = findCommenter(line);
if (commenter == null) return;
if (commenter instanceof SelfManagingCommenter) {
final SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter)commenter;
selfManagingCommenter.commentLine(line, offset, myDocument, myFile, myCommenterStateMap.get(selfManagingCommenter));
return;
}
String prefix = commenter.getLineCommentPrefix();
if (prefix != null) {
myDocument.insertString(offset, prefix);
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2010 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.codeInsight.generation;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author Maxim.Mossienko
*/
public interface SelfManagingCommenter<T extends SelfManagingCommenter.CommenterDataHolder> {
ExtensionPointName<SelfManagingCommenter> EP_NAME = ExtensionPointName.create("com.intellij.selfManagingCommenter");
T createLineCommentingState(int startLine, int endLine, Document document, PsiFile file);
void commentLine(int line, int offset, Document document, PsiFile file, T data);
void uncommentLine(int line, int startOffset, Document document, PsiFile file, T data);
boolean isCommented(int line, int lineStart, Document document, PsiFile file, T data);
@NotNull
String getCommentPrefix(int line, Document document, PsiFile file, T data);
interface CommenterDataHolder {
CommenterDataHolder EMPTY_STATE = new CommenterDataHolder() {};
}
}
@@ -121,6 +121,8 @@
<extensionPoint name="fileType.fileViewProviderFactory" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint"/>
<extensionPoint name="multiLangCommenter"
interface="com.intellij.psi.templateLanguages.MultipleLangCommentProvider"/>
<extensionPoint name="selfManagingCommenter"
interface="com.intellij.codeInsight.generation.SelfManagingCommenter"/>
<extensionPoint name="cacheBuilder"
beanClass="com.intellij.lang.cacheBuilder.CacheBuilderEP"/>