use of com.intellij.util.CharTable in project intellij-community by JetBrains.
the class XmlWhiteSpaceFormattingStrategy method addWhitespaceToTagBody.
private static void addWhitespaceToTagBody(final ASTNode treePrev, final LeafElement whiteSpaceElement) {
final CharTable charTable = SharedImplUtil.findCharTableByTree(treePrev);
final ASTNode treeParent = treePrev.getTreeParent();
final boolean before;
final XmlText xmlText;
if (treePrev.getElementType() == XmlElementType.XML_TEXT) {
xmlText = (XmlText) treePrev.getPsi();
before = true;
} else if (treePrev.getTreePrev().getElementType() == XmlElementType.XML_TEXT) {
xmlText = (XmlText) treePrev.getTreePrev().getPsi();
before = false;
} else {
xmlText = (XmlText) Factory.createCompositeElement(XmlElementType.XML_TEXT, charTable, treeParent.getPsi().getManager());
CodeEditUtil.setNodeGenerated(xmlText.getNode(), true);
treeParent.addChild(xmlText.getNode(), treePrev);
before = true;
}
final ASTNode node = xmlText.getNode();
assert node != null;
final TreeElement anchorInText = (TreeElement) (before ? node.getFirstChildNode() : node.getLastChildNode());
if (anchorInText == null)
node.addChild(whiteSpaceElement);
else if (anchorInText.getElementType() != XmlTokenType.XML_WHITE_SPACE)
node.addChild(whiteSpaceElement, before ? anchorInText : null);
else {
final String text = before ? whiteSpaceElement.getText() + anchorInText.getText() : anchorInText.getText() + whiteSpaceElement.getText();
node.replaceChild(anchorInText, ASTFactory.whitespace(text));
}
}
use of com.intellij.util.CharTable in project intellij-community by JetBrains.
the class XmlAspectImpl method update.
@Override
public void update(PomModelEvent event) {
if (!event.getChangedAspects().contains(myTreeAspect))
return;
final TreeChangeEvent changeSet = (TreeChangeEvent) event.getChangeSet(myTreeAspect);
if (changeSet == null)
return;
final ASTNode rootElement = changeSet.getRootElement();
final PsiFile file = (PsiFile) rootElement.getPsi();
if (!(file instanceof XmlFile))
return;
final XmlAspectChangeSetImpl xmlChangeSet = event.registerChangeSetIfAbsent(this, new XmlAspectChangeSetImpl(myModel));
xmlChangeSet.addChangedFile((XmlFile) file);
final ASTNode[] changedElements = changeSet.getChangedElements();
final CharTable table = ((FileElement) changeSet.getRootElement()).getCharTable();
for (ASTNode changedElement : changedElements) {
TreeChange changesByElement = changeSet.getChangesByElement(changedElement);
PsiElement psiElement = null;
while (changedElement != null && (psiElement = changedElement.getPsi()) == null) {
final ASTNode parent = changedElement.getTreeParent();
final ChangeInfoImpl changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, changedElement);
changeInfo.compactChange(changesByElement);
changesByElement = new TreeChangeImpl(parent);
changesByElement.addChange(changedElement, changeInfo);
changedElement = parent;
}
if (changedElement == null)
continue;
final TreeChange finalChangedElement = changesByElement;
psiElement.accept(new XmlElementVisitor() {
TreeChange myChange = finalChangedElement;
@Override
public void visitElement(PsiElement element) {
final ASTNode child = element.getNode();
final ASTNode treeParent = child.getTreeParent();
if (treeParent == null)
return;
final PsiElement parent = treeParent.getPsi();
final ChangeInfoImpl changeInfo = ChangeInfoImpl.create(ChangeInfo.CONTENTS_CHANGED, child);
changeInfo.compactChange(myChange);
myChange = new TreeChangeImpl(treeParent);
myChange.addChange(child, changeInfo);
parent.accept(this);
}
@Override
public void visitXmlAttribute(XmlAttribute attribute) {
final ASTNode[] affectedChildren = myChange.getAffectedChildren();
String oldName = null;
String oldValue = null;
for (final ASTNode treeElement : affectedChildren) {
final ChangeInfo changeByChild = myChange.getChangeByChild(treeElement);
final int changeType = changeByChild.getChangeType();
if (treeElement.getElementType() == XmlTokenType.XML_NAME) {
if (changeType == ChangeInfo.REMOVED) {
oldName = treeElement.getText();
} else if (changeType == ChangeInfo.REPLACE) {
oldName = ((ReplaceChangeInfo) changeByChild).getReplaced().getText();
}
}
if (treeElement.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE) {
if (changeType == ChangeInfo.REMOVED) {
oldValue = treeElement.getText();
} else if (changeType == ChangeInfo.REPLACE) {
oldValue = ((ReplaceChangeInfo) changeByChild).getReplaced().getText();
}
}
}
if (oldName != null && !oldName.equals(attribute.getName())) {
xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), oldName, null));
xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), attribute.getName(), attribute.getValue()));
} else if (oldValue != null) {
xmlChangeSet.add(new XmlAttributeSetImpl(attribute.getParent(), attribute.getName(), attribute.getValue()));
} else {
xmlChangeSet.add(new XmlElementChangedImpl(attribute));
}
}
@Override
public void visitXmlTag(XmlTag tag) {
ASTNode[] affectedChildren = shortenChange(myChange.getAffectedChildren(), changeSet);
for (final ASTNode treeElement : affectedChildren) {
if (!(treeElement.getPsi() instanceof XmlTagChild)) {
visitElement(tag);
return;
}
}
for (final ASTNode treeElement : affectedChildren) {
final ChangeInfo changeByChild = myChange.getChangeByChild(treeElement);
final int changeType = changeByChild.getChangeType();
final IElementType type = treeElement.getElementType();
if (type == TokenType.WHITE_SPACE)
continue;
/*
if (type == ElementType.XML_NAME) {
final XmlToken xmlToken = (XmlToken)((ReplaceChangeInfo)changeByChild).getReplaced();
xmlChangeSet.add(new XmlTagNameChangedImpl(tag, xmlToken.getText()));
continue;
}
*/
final PsiElement element = treeElement.getPsi();
switch(changeType) {
case ChangeInfo.ADD:
xmlChangeSet.add(new XmlTagChildAddImpl(tag, (XmlTagChild) element));
break;
case ChangeInfo.REMOVED:
treeElement.putUserData(CharTable.CHAR_TABLE_KEY, table);
xmlChangeSet.add(new XmlTagChildRemovedImpl(tag, (XmlTagChild) element));
break;
case ChangeInfo.CONTENTS_CHANGED:
xmlChangeSet.add(new XmlTagChildChangedImpl(tag, (XmlTagChild) element));
break;
case ChangeInfo.REPLACE:
final PsiElement psi = ((ReplaceChangeInfo) changeByChild).getReplaced().getPsi();
if (psi instanceof XmlTagChild) {
final XmlTagChild replaced = (XmlTagChild) psi;
replaced.putUserData(CharTable.CHAR_TABLE_KEY, table);
xmlChangeSet.add(new XmlTagChildRemovedImpl(tag, replaced));
xmlChangeSet.add(new XmlTagChildAddImpl(tag, (XmlTagChild) element));
}
break;
}
}
}
@Override
public void visitXmlDocument(XmlDocument document) {
xmlChangeSet.clear();
xmlChangeSet.add(new XmlDocumentChangedImpl(document));
}
@Override
public void visitFile(PsiFile file) {
final XmlDocument document = ((XmlFile) file).getDocument();
if (document != null) {
xmlChangeSet.clear();
xmlChangeSet.add(new XmlDocumentChangedImpl(document));
}
}
});
}
}
use of com.intellij.util.CharTable in project intellij-community by JetBrains.
the class XmlProcessingInstructionManipulator method handleContentChange.
@Override
public XmlProcessingInstruction handleContentChange(@NotNull XmlProcessingInstruction element, @NotNull TextRange range, String newContent) throws IncorrectOperationException {
CheckUtil.checkWritable(element);
final CompositeElement attrNode = (CompositeElement) element.getNode();
final ASTNode valueNode = attrNode.findLeafElementAt(range.getStartOffset());
LOG.assertTrue(valueNode != null, "Leaf not found in " + attrNode + " at offset " + range.getStartOffset() + " in element " + element);
final PsiElement elementToReplace = valueNode.getPsi();
String text;
try {
text = elementToReplace.getText();
final int offsetInParent = elementToReplace.getStartOffsetInParent();
String textBeforeRange = text.substring(0, range.getStartOffset() - offsetInParent);
String textAfterRange = text.substring(range.getEndOffset() - offsetInParent, text.length());
newContent = element.getText().startsWith("'") || element.getText().endsWith("'") ? newContent.replace("'", "'") : newContent.replace("\"", """);
text = textBeforeRange + newContent + textAfterRange;
} catch (StringIndexOutOfBoundsException e) {
LOG.error("Range: " + range + " in text: '" + element.getText() + "'", e);
throw e;
}
final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(attrNode);
final LeafElement newValueElement = Factory.createSingleLeafElement(XmlTokenType.XML_TAG_CHARACTERS, text, charTableByTree, element.getManager());
attrNode.replaceChildInternal(valueNode, newValueElement);
return element;
}
use of com.intellij.util.CharTable in project intellij-community by JetBrains.
the class FormatterUtil method replaceInnerWhiteSpace.
/**
* There is a possible case that we want to adjust white space which is not represented at the AST/PSI tree, e.g.
* we might have a multiline comment which uses tabs for inner lines indents and want to replace them by spaces.
* There is no white space element then, the only leaf is the comment itself.
* <p/>
* This method allows such 'inner element modifications', i.e. it receives information on what new text should be used
* at the target inner element range and performs corresponding replacement by generating new leaf with adjusted text
* and replacing the old one by it.
*
* @param newWhiteSpaceText new text to use at the target inner element range
* @param holder target range holder
* @param whiteSpaceRange target range which text should be replaced by the given one
*/
public static void replaceInnerWhiteSpace(@NotNull final String newWhiteSpaceText, @NotNull final ASTNode holder, @NotNull final TextRange whiteSpaceRange) {
final CharTable charTable = SharedImplUtil.findCharTableByTree(holder);
StringBuilder newText = createNewLeafChars(holder, whiteSpaceRange, newWhiteSpaceText);
LeafElement newElement = Factory.createSingleLeafElement(holder.getElementType(), newText, charTable, holder.getPsi().getManager());
holder.getTreeParent().replaceChild(holder, newElement);
}
use of com.intellij.util.CharTable in project intellij-community by JetBrains.
the class MethodElement method deleteChildInternal.
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
if (child.getElementType() == CODE_BLOCK) {
final ASTNode prevWS = TreeUtil.prevLeaf(child);
if (prevWS != null && prevWS.getElementType() == TokenType.WHITE_SPACE) {
removeChild(prevWS);
}
super.deleteChildInternal(child);
final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
LeafElement semicolon = Factory.createSingleLeafElement(SEMICOLON, ";", 0, 1, treeCharTab, getManager());
addInternal(semicolon, semicolon, null, Boolean.TRUE);
} else {
super.deleteChildInternal(child);
}
}
Aggregations