protected void parseComment() { final PsiBuilder.Marker comment = mark(); advance(); while (true) { final IElementType tt = token(); if (tt == XML_COMMENT_CHARACTERS|| tt == XML_CONDITIONAL_COMMENT_START || tt == XML_CONDITIONAL_COMMENT_START_END || tt == XML_CONDITIONAL_COMMENT_END_START || tt == XML_CONDITIONAL_COMMENT_END) { advance(); continue; } else if (tt == XML_BAD_CHARACTER) { final PsiBuilder.Marker error = mark(); advance(); error.error(XmlErrorMessages.message("xml.parsing.bad.character")); continue; } if (tt == XML_COMMENT_END) { advance(); } break; } comment.done(XmlElementType.XML_COMMENT); }
@Nullable protected static String getNameFromEntityRef(final CompositeElement compositeElement, final IElementType xmlEntityDeclStart) { final ASTNode node = compositeElement.findChildByType(xmlEntityDeclStart); if (node == null) return null; ASTNode name = node.getTreeNext(); if (name != null && name.getElementType() == TokenType.WHITE_SPACE) { name = name.getTreeNext(); } if (name != null && name.getElementType() == XmlElementType.XML_ENTITY_REF) { final StringBuilder builder = new StringBuilder(); ((XmlElement)name.getPsi()).processElements(new PsiElementProcessor() { @Override public boolean execute(@NotNull final PsiElement element) { builder.append(element.getText()); return true; } }, name.getPsi()); if (builder.length() > 0) return builder.toString(); } return null; }
@Override public ThreeState fun(ASTNode oldNode, LighterASTNode newNode, FlyweightCapableTreeStructure<LighterASTNode> structure) { if (oldNode instanceof XmlTag && newNode.getTokenType() == XmlElementType.XML_TAG) { String oldName = ((XmlTag)oldNode).getName(); Ref<LighterASTNode[]> childrenRef = Ref.create(null); int count = structure.getChildren(newNode, childrenRef); if (count < 3) return ThreeState.UNSURE; LighterASTNode[] children = childrenRef.get(); if (children[0].getTokenType() != XmlTokenType.XML_START_TAG_START) return ThreeState.UNSURE; if (children[1].getTokenType() != XmlTokenType.XML_NAME) return ThreeState.UNSURE; if (children[2].getTokenType() != XmlTokenType.XML_TAG_END) return ThreeState.UNSURE; LighterASTTokenNode name = (LighterASTTokenNode)children[1]; CharSequence newName = name.getText(); if (!Comparing.equal(oldName, newName)) return ThreeState.NO; } return ThreeState.UNSURE; }
public void build(XmlBuilder builder) { PsiBuilder b = createBuilderAndParse(); FlyweightCapableTreeStructure<LighterASTNode> structure = b.getLightTree(); LighterASTNode root = structure.getRoot(); root = structure.prepareForGetChildren(root); final Ref<LighterASTNode[]> childrenRef = Ref.create(null); final int count = structure.getChildren(root, childrenRef); LighterASTNode[] children = childrenRef.get(); for (int i = 0; i < count; i++) { LighterASTNode child = children[i]; final IElementType tt = child.getTokenType(); if (tt == XmlElementType.XML_TAG || tt == XmlElementType.HTML_TAG) { processTagNode(b, structure, child, builder); } else if (tt == XmlElementType.XML_PROLOG) { processPrologNode(b, builder, structure, child); } } structure.disposeChildren(children, count); }
private void processPrologNode(PsiBuilder psiBuilder, XmlBuilder builder, FlyweightCapableTreeStructure<LighterASTNode> structure, LighterASTNode prolog) { final Ref<LighterASTNode[]> prologChildren = new Ref<LighterASTNode[]>(null); final int prologChildrenCount = structure.getChildren(structure.prepareForGetChildren(prolog), prologChildren); for (int i = 0; i < prologChildrenCount; i++) { LighterASTNode node = prologChildren.get()[i]; IElementType type = node.getTokenType(); if (type == XmlElementType.XML_DOCTYPE) { processDoctypeNode(builder, structure, node); break; } if (type == TokenType.ERROR_ELEMENT) { processErrorNode(psiBuilder, node, builder); } } }
@Override @Nullable protected ASTNode processChild(List<Block> result, final ASTNode child, final Wrap wrap, final Alignment alignment, final Indent indent) { IElementType type = child.getElementType(); if (type == XmlElementType.XML_TEXT) { final PsiElement parent = child.getPsi().getParent(); if (parent instanceof XmlTag && ((XmlTag)parent).getSubTags().length == 0) { if (buildInjectedPsiBlocks(result, child, wrap, alignment, indent)) return child; } return createXmlTextBlocks(result, child, wrap, alignment); } else if (type == XmlElementType.XML_COMMENT) { if (buildInjectedPsiBlocks(result, child, wrap, alignment, indent)) return child; return super.processChild(result, child, wrap, alignment, indent); } else { return super.processChild(result, child, wrap, alignment, indent); } }
private boolean shouldKeepWhitespaces() { if (myNode.getElementType() == XmlElementType.XML_TEXT) { if (myXmlFormattingPolicy.getShouldKeepWhiteSpaces()) { return true; } else { final ASTNode treeParent = myNode.getTreeParent(); final XmlTag tag = getTag(treeParent); if (tag != null) { if (myXmlFormattingPolicy.keepWhiteSpacesInsideTag(tag)) { return true; } } } } return false; }
protected List<Block> splitComment() { if (myNode.getElementType() != XmlElementType.XML_COMMENT) return EMPTY; final ArrayList<Block> result = new ArrayList<Block>(3); ASTNode child = myNode.getFirstChildNode(); boolean hasOuterLangElements = false; while (child != null) { if (child instanceof OuterLanguageElement) { hasOuterLangElements = true; } result.add(new XmlBlock(child, null, null, myXmlFormattingPolicy, getChildIndent(), null, isPreserveSpace())); child = child.getTreeNext(); } if (hasOuterLangElements) { return result; } else { return EMPTY; } }
@Override public PsiElement getChangeHighlightingDirtyScopeFor(@NotNull PsiElement changedElement) { try { if (changedElement instanceof XmlToken && changedElement.getNode().getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE_TOKEN) { final PsiElement grandParent = changedElement.getParent().getParent(); if (grandParent instanceof XmlAttribute) { if (XsltSupport.isXPathAttribute((XmlAttribute)grandParent)) { return grandParent; } } } else if (changedElement instanceof XmlTag && XsltSupport.isTemplate((XmlTag)changedElement, false)) { return changedElement; } } catch (NullPointerException e) { // sth was null } return null; }
protected void parseComment() { final PsiBuilder.Marker comment = mark(); advance(); while (true) { final IElementType tt = token(); if (tt == XmlTokenType.XML_COMMENT_CHARACTERS || tt == XmlTokenType.XML_CHAR_ENTITY_REF || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_START || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_START_END || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_END_START || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_END) { advance(); continue; } if (tt == XmlTokenType.XML_BAD_CHARACTER) { final PsiBuilder.Marker error = mark(); advance(); error.error(XmlErrorMessages.message("xml.parsing.bad.character")); continue; } if (tt == XmlTokenType.XML_COMMENT_END) { advance(); } break; } comment.done(XmlElementType.XML_COMMENT); }
@Nullable protected static String getNameFromEntityRef(final CompositeElement compositeElement, final IElementType xmlEntityDeclStart) { final ASTNode node = compositeElement.findChildByType(xmlEntityDeclStart); if (node == null) return null; ASTNode name = node.getTreeNext(); if (name != null && name.getElementType() == TokenType.WHITE_SPACE) { name = name.getTreeNext(); } if (name != null && name.getElementType() == XmlElementType.XML_ENTITY_REF) { final StringBuilder builder = new StringBuilder(); ((XmlElement)name.getPsi()).processElements(new PsiElementProcessor() { public boolean execute(@NotNull final PsiElement element) { builder.append(element.getText()); return true; } }, name.getPsi()); if (builder.length() > 0) return builder.toString(); } return null; }
@Override public ThreeState fun(ASTNode oldNode, LighterASTNode newNode, FlyweightCapableTreeStructure<LighterASTNode> structure) { if (oldNode instanceof XmlTag && newNode.getTokenType() == XmlElementType.XML_TAG) { String oldName = ((XmlTag)oldNode).getName(); Ref<LighterASTNode[]> childrenRef = Ref.create(null); int count = structure.getChildren(newNode, childrenRef); if (count < 3) return ThreeState.UNSURE; LighterASTNode[] children = childrenRef.get(); if (children[0].getTokenType() != XmlTokenType.XML_START_TAG_START) return ThreeState.UNSURE; if (children[1].getTokenType() != XmlTokenType.XML_NAME) return ThreeState.UNSURE; if (children[2].getTokenType() != XmlTokenType.XML_TAG_END) return ThreeState.UNSURE; LighterASTTokenNode name = (LighterASTTokenNode)children[1]; CharSequence newName = name.getText(); if (!oldName.equals(newName)) return ThreeState.NO; } return ThreeState.UNSURE; }
@Nullable static XmlToken findEndTagName(@Nullable final PsiErrorElement element) { if (element == null) return null; final ASTNode astNode = element.getNode(); if (astNode == null) return null; ASTNode current = astNode.getLastChildNode(); ASTNode prev = current; while (current != null) { final IElementType elementType = prev.getElementType(); if ((elementType == XmlElementType.XML_NAME || elementType == XmlElementType.XML_TAG_NAME) && current.getElementType() == XmlElementType.XML_END_TAG_START) { return (XmlToken)prev.getPsi(); } prev = current; current = current.getTreePrev(); } return null; }
protected @Nullable ASTNode processChild(List<Block> result, final ASTNode child, final Wrap wrap, final Alignment alignment, final Indent indent) { IElementType type = child.getElementType(); if (type == XmlElementType.XML_TEXT) { final PsiElement parent = child.getPsi().getParent(); if (parent instanceof XmlTag && ((XmlTag)parent).getSubTags().length == 0) { if (buildInjectedPsiBlocks(result, child, wrap, alignment, indent)) return child; } return createXmlTextBlocks(result, child, wrap, alignment); } else if (type == XmlElementType.XML_COMMENT) { if (buildInjectedPsiBlocks(result, child, wrap, alignment, indent)) return child; return super.processChild(result, child, wrap, alignment, indent); } else { return super.processChild(result, child, wrap, alignment, indent); } }
public boolean indentChildrenOf(final XmlTag parentTag) { if (parentTag == null) { return true; } final PsiElement firstChild = findFirstNonEmptyChild(parentTag); if (firstChild == null) { return false; } if (firstChild.getNode().getElementType() != XmlElementType.XML_START_TAG_START) { return false; } if (mySettings.HTML_DO_NOT_ALIGN_CHILDREN_OF_MIN_LINES > 0 && getLines(parentTag) > mySettings.HTML_DO_NOT_ALIGN_CHILDREN_OF_MIN_LINES) { return false; } else { return !checkName(parentTag, mySettings.HTML_DO_NOT_INDENT_CHILDREN_OF); } }
private List<Block> splitAttribute(ASTNode node, XmlFormattingPolicy formattingPolicy) { final ArrayList<Block> result = new ArrayList<Block>(3); ASTNode child = node.getFirstChildNode(); while (child != null) { if (child.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE_START_DELIMITER || child.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE_END_DELIMITER) { result.add(new XmlBlock(child, null, null, formattingPolicy, null, null, isPreserveSpace())); } else if (!child.getPsi().getLanguage().isKindOf(XMLLanguage.INSTANCE) && containsOuterLanguageElement(child)) { // Fix for EA-20311: // In case of another embedded language create a splittable XML block which can be // merged with other language's code blocks. createLeafBlocks(child, result); } else if (child.getElementType() != TokenType.ERROR_ELEMENT || child.getFirstChildNode() != null) { result.add(new ReadOnlyBlock(child)); } child = child.getTreeNext(); } return result; }
private List<Block> splitComment() { if (myNode.getElementType() != XmlElementType.XML_COMMENT) return EMPTY; final ArrayList<Block> result = new ArrayList<Block>(3); ASTNode child = myNode.getFirstChildNode(); boolean hasOuterLangElements = false; while (child != null) { if (child instanceof OuterLanguageElement) { hasOuterLangElements = true; } result.add(new XmlBlock(child, null, null, myXmlFormattingPolicy, getChildIndent(), null, isPreserveSpace())); child = child.getTreeNext(); } if (hasOuterLangElements) { return result; } else { return EMPTY; } }
@Override public XmlAttributeValue getValueElement() { if(isInternalReference()) { for(ASTNode e = getFirstChildNode(); e != null; e = e.getTreeNext()) { if(e.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE) { return (XmlAttributeValue) SourceTreeToPsiMap.treeElementToPsi(e); } } } else { for(ASTNode e = getLastChildNode(); e != null; e = e.getTreePrev()) { if(e.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE) { return (XmlAttributeValue) SourceTreeToPsiMap.treeElementToPsi(e); } } } return null; }
@Override public boolean hasCDATA() { for(XmlText xmlText : myTextElements) { PsiElement[] children = xmlText.getChildren(); for(PsiElement child : children) { if(child.getNode().getElementType() == XmlElementType.XML_CDATA) { return true; } } } return false; }
@Override public int getChildRole(ASTNode child) { LOG.assertTrue(child.getTreeParent() == this); IElementType i = child.getElementType(); if(i == XmlElementType.XML_PROLOG) { return XmlChildRole.XML_PROLOG; } else if(i == XmlElementType.XML_TAG) { return XmlChildRole.XML_TAG; } else { return ChildRoleBase.NONE; } }
@Override public XmlTag getRootTag() { XmlTag rootTag = myRootTag; if(rootTag == null) { rootTag = (XmlTag) findElementByTokenType(XmlElementType.XML_TAG); if(!MY_ROOT_TAG_UPDATER.compareAndSet(this, null, rootTag)) { rootTag = MY_ROOT_TAG_UPDATER.get(this); } } return rootTag; }
protected Wrap chooseWrap(final ASTNode child, final Wrap tagBeginWrap, final Wrap attrWrap, final Wrap textWrap) { if (myNode.getElementType() == XmlElementType.XML_TEXT) return textWrap; final IElementType elementType = child.getElementType(); if (elementType == XmlElementType.XML_ATTRIBUTE) return attrWrap; if (elementType == XmlTokenType.XML_START_TAG_START) return tagBeginWrap; if (elementType == XmlTokenType.XML_END_TAG_START) { final PsiElement parent = SourceTreeToPsiMap.treeElementToPsi(child.getTreeParent()); if (parent instanceof XmlTag) { final XmlTag tag = (XmlTag)parent; if (canWrapTagEnd(tag)) { return getTagEndWrapping(tag); } } return null; } if (elementType == XmlElementType.XML_TEXT || elementType == XmlTokenType.XML_DATA_CHARACTERS) return textWrap; return null; }
protected void processSimpleChild(final ASTNode child, final Indent indent, final List<Block> result, final Wrap wrap, final Alignment alignment) { if (isXmlTag(child)) { result.add(createTagBlock(child, indent != null ? indent : Indent.getNoneIndent(), wrap, alignment)); } else if (child.getElementType() == XmlElementType.XML_DOCTYPE) { result.add( new XmlBlock(child, wrap, alignment, myXmlFormattingPolicy, indent, null, isPreserveSpace()) { protected Wrap getDefaultWrap(final ASTNode node) { final IElementType type = node.getElementType(); return type == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN ? Wrap.createWrap(getWrapType(myXmlFormattingPolicy.getAttributesWrap()), false) : null; } } ); } else { result.add(createSimpleChild(child, indent, wrap, alignment)); } }
@Nullable private static PsiBuilder.Marker terminateText(@Nullable PsiBuilder.Marker xmlText) { if (xmlText != null) { xmlText.done(XmlElementType.XML_TEXT); xmlText = null; } return xmlText; }