private void checkTagByDescriptor(final XmlTag tag) { String name = tag.getName(); XmlElementDescriptor elementDescriptor; final PsiElement parent = tag.getParent(); if (parent instanceof XmlTag) { XmlTag parentTag = (XmlTag) parent; elementDescriptor = XmlUtil.getDescriptorFromContext(tag); final XmlElementDescriptor parentDescriptor = parentTag.getDescriptor(); if (parentDescriptor != null && elementDescriptor == null && shouldBeValidated(tag)) { if (tag instanceof HtmlTag) { // XmlEntitiesInspection inspection = getInspectionProfile(tag, // HtmlStyleLocalInspection.SHORT_NAME); // if (inspection != null /*&& // isAdditionallyDeclared(inspection.getAdditionalEntries(XmlEntitiesInspection.UNKNOWN_TAG), name)*/) { return; // } } addElementsForTag( tag, XmlErrorMessages.message("element.is.not.allowed.here", name), getTagProblemInfoType(tag), null); return; } if (elementDescriptor instanceof AnyXmlElementDescriptor || elementDescriptor == null) { elementDescriptor = tag.getDescriptor(); } if (elementDescriptor == null) return; } else { // root tag elementDescriptor = tag.getDescriptor(); if (elementDescriptor == null) { addElementsForTag( tag, XmlErrorMessages.message("element.must.be.declared", name), HighlightInfoType.WRONG_REF, null); return; } } checkRequiredAttributes(tag, name, elementDescriptor); if (elementDescriptor instanceof Validator) { //noinspection unchecked ((Validator<XmlTag>) elementDescriptor).validate(tag, this); } }
@Override public void visitXmlAttributeValue(XmlAttributeValue value) { final PsiElement parent = value.getParent(); if (!(parent instanceof XmlAttribute)) { checkReferences(value); return; } XmlAttribute attribute = (XmlAttribute) parent; XmlTag tag = attribute.getParent(); XmlElementDescriptor elementDescriptor = tag.getDescriptor(); XmlAttributeDescriptor attributeDescriptor = elementDescriptor != null ? elementDescriptor.getAttributeDescriptor(attribute) : null; if (attributeDescriptor != null && !skipValidation(value)) { String error = attributeDescriptor.validateValue(value, attribute.getValue()); if (error != null) { addToResults(HighlightInfo.createHighlightInfo(getTagProblemInfoType(tag), value, error)); return; } } checkReferences(value); }
@Override protected boolean isValidForFile( @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { if (!(file instanceof XmlFile)) return false; XmlTag contextTag = getContextTag(editor, file); return contextTag != null && isInsideTagBody(contextTag, editor) && contextTag.getDescriptor() != null; }
private Map<String, XmlElementDescriptor> configure(String... files) { myFixture.configureByFiles(files); XmlTag tag = ((XmlFile) getFile()).getRootTag(); assertNotNull(tag); XmlElementDescriptor descriptor = tag.getDescriptor(); assertNotNull(descriptor); XmlElementDescriptor[] descriptors = descriptor.getElementsDescriptors(tag); Map<String, XmlElementDescriptor> map = ContainerUtil.assignKeys( Arrays.asList(descriptors).iterator(), new Convertor<XmlElementDescriptor, String>() { @Override public String convert(XmlElementDescriptor o) { return o.getName(); } }); map.put(tag.getName(), tag.getDescriptor()); return map; }
public static XmlFile findDescriptorFile(final XmlTag tag, final XmlFile containingFile) { final XmlElementDescriptor descriptor = tag.getDescriptor(); final XmlNSDescriptor nsDescriptor = descriptor != null ? descriptor.getNSDescriptor() : null; XmlFile descriptorFile = nsDescriptor != null ? nsDescriptor.getDescriptorFile() : containingFile.getDocument().getProlog().getDoctype() != null ? containingFile : null; if (nsDescriptor != null && (descriptorFile == null || descriptorFile.getName().equals(containingFile.getName() + ".dtd"))) { descriptorFile = containingFile; } return descriptorFile; }
@Override public void visitXmlTag(XmlTag tag) { super.visitXmlTag(tag); final XmlElementDescriptor descriptor = tag.getDescriptor(); if (descriptor instanceof JavaFxClassTagDescriptorBase) { appendClassName(descriptor.getDeclaration()); } else if (descriptor instanceof JavaFxPropertyTagDescriptor && ((JavaFxPropertyTagDescriptor) descriptor).isStatic()) { final PsiElement declaration = descriptor.getDeclaration(); if (declaration instanceof PsiMember) { appendClassName(((PsiMember) declaration).getContainingClass()); } } }
public String getName(PsiElement context) { if (context == null) { return getName(); } final String form = myTag.getAttributeValue("form"); boolean isQualifiedAttr = QUALIFIED_ATTR_VALUE.equals(form); final XmlTag rootTag = (((XmlFile) myTag.getContainingFile())).getRootTag(); assert rootTag != null; String targetNs = rootTag.getAttributeValue("targetNamespace"); XmlTag contextTag = (XmlTag) context; String name = getName(); boolean attributeShouldBeQualified = false; String contextNs = contextTag.getNamespace(); if (targetNs != null && !contextNs.equals(targetNs)) { final XmlElementDescriptor xmlElementDescriptor = contextTag.getDescriptor(); if (xmlElementDescriptor instanceof XmlElementDescriptorImpl) { final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl) xmlElementDescriptor; final TypeDescriptor type = elementDescriptor.getType(); if (type instanceof ComplexTypeDescriptor) { final ComplexTypeDescriptor typeDescriptor = (ComplexTypeDescriptor) type; attributeShouldBeQualified = typeDescriptor.canContainAttribute(targetNs, null) != ComplexTypeDescriptor.CanContainAttributeType.CanNotContain; } if (!attributeShouldBeQualified && contextNs.length() == 0 && targetNs.length() > 0) { attributeShouldBeQualified = !targetNs.equals(elementDescriptor.getNamespace()); } } } if (targetNs != null && (isQualifiedAttr || QUALIFIED_ATTR_VALUE.equals(rootTag.getAttributeValue("attributeFormDefault")) || attributeShouldBeQualified)) { final String prefixByNamespace = contextTag.getPrefixByNamespace(targetNs); if (prefixByNamespace != null && prefixByNamespace.length() > 0) { name = prefixByNamespace + ":" + name; } } return name; }
protected void checkAttribute( @NotNull final XmlAttribute attribute, @NotNull final ProblemsHolder holder, final boolean isOnTheFly) { final XmlTag tag = attribute.getParent(); if (tag instanceof HtmlTag) { XmlElementDescriptor elementDescriptor = tag.getDescriptor(); if (elementDescriptor == null || elementDescriptor instanceof AnyXmlElementDescriptor) { return; } XmlAttributeDescriptor attributeDescriptor = elementDescriptor.getAttributeDescriptor(attribute); final String name = attribute.getName(); if (attributeDescriptor == null && !attribute.isNamespaceDeclaration()) { if (!XmlUtil.attributeFromTemplateFramework(name, tag) && (!isCustomValuesEnabled() || !isCustomValue(name))) { final ASTNode node = attribute.getNode(); assert node != null; final PsiElement nameElement = XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(node).getPsi(); boolean maySwitchToHtml5 = HtmlUtil.isCustomHtml5Attribute(name) && !HtmlUtil.hasNonHtml5Doctype(tag); LocalQuickFix[] quickfixes = new LocalQuickFix[maySwitchToHtml5 ? 3 : 2]; quickfixes[0] = new AddCustomTagOrAttributeIntentionAction( getShortName(), name, XmlEntitiesInspection.UNKNOWN_ATTRIBUTE); quickfixes[1] = new RemoveAttributeIntentionAction(name); if (maySwitchToHtml5) { quickfixes[2] = new SwitchToHtml5WithHighPriorityAction(); } holder.registerProblem( nameElement, XmlErrorMessages.message("attribute.is.not.allowed.here", name), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, quickfixes); } } } }
@Nullable protected XmlElementDescriptor computeElementDescriptor() { for (XmlElementDescriptorProvider provider : Extensions.getExtensions(XmlElementDescriptorProvider.EP_NAME)) { XmlElementDescriptor elementDescriptor = provider.getDescriptor(this); if (elementDescriptor != null) { return elementDescriptor; } } final String namespace = getNamespace(); if (XmlUtil.EMPTY_URI.equals(namespace)) { // nonqualified items final XmlTag parent = getParentTag(); if (parent != null) { final XmlElementDescriptor descriptor = parent.getDescriptor(); if (descriptor != null) { XmlElementDescriptor fromParent = descriptor.getElementDescriptor(this, parent); if (fromParent != null && !(fromParent instanceof AnyXmlElementDescriptor)) { return fromParent; } } } } XmlElementDescriptor elementDescriptor = null; final XmlNSDescriptor nsDescriptor = getNSDescriptor(namespace, false); LOG.debug( "Descriptor for namespace " + namespace + " is " + (nsDescriptor != null ? nsDescriptor.getClass().getCanonicalName() : "NULL")); if (nsDescriptor != null) { if (!DumbService.getInstance(getProject()).isDumb() || DumbService.isDumbAware(nsDescriptor)) { elementDescriptor = nsDescriptor.getElementDescriptor(this); } } if (elementDescriptor == null) { return XmlUtil.findXmlDescriptorByType(this); } return elementDescriptor; }
private void checkTag(XmlTag tag) { if (ourDoJaxpTesting) return; if (!myHolder.hasErrorResults()) { checkTagByDescriptor(tag); } if (!myHolder.hasErrorResults()) { if (!skipValidation(tag)) { final XmlElementDescriptor descriptor = tag.getDescriptor(); if (tag instanceof HtmlTag && (descriptor instanceof AnyXmlElementDescriptor || descriptor == null)) { return; } checkReferences(tag); } } }
private static void generateRaw(final @NotNull XmlTag newTag) { XmlElementDescriptor selected = newTag.getDescriptor(); if (selected == null) return; switch (selected.getContentType()) { case XmlElementDescriptor.CONTENT_TYPE_EMPTY: newTag.collapseIfEmpty(); ASTNode node = newTag.getNode(); assert node != null; ASTNode elementEnd = node.findChildByType(XmlTokenType.XML_EMPTY_ELEMENT_END); if (elementEnd == null) { LeafElement emptyTagEnd = Factory.createSingleLeafElement( XmlTokenType.XML_EMPTY_ELEMENT_END, "/>", 0, 2, null, newTag.getManager()); node.addChild(emptyTagEnd); } break; case XmlElementDescriptor.CONTENT_TYPE_MIXED: newTag.getValue().setText(""); } for (XmlAttributeDescriptor descriptor : selected.getAttributesDescriptors(newTag)) { if (descriptor.isRequired()) { newTag.setAttribute(descriptor.getName(), ""); } } List<XmlElementDescriptor> tags = getRequiredSubTags(selected); for (XmlElementDescriptor descriptor : tags) { if (descriptor == null) { XmlTag tag = XmlElementFactory.getInstance(newTag.getProject()) .createTagFromText("<", newTag.getLanguage()); newTag.addSubTag(tag, false); } else { XmlTag subTag = newTag.addSubTag(createTag(newTag, descriptor), false); generateRaw(subTag); } } }
public XmlElementDescriptor getElementDescriptor(@NotNull XmlTag tag) { PsiElement parent = tag.getParent(); final String namespace = tag.getNamespace(); while (parent instanceof XmlTag && !namespace.equals(((XmlTag) parent).getNamespace())) parent = parent.getContext(); if (parent instanceof XmlTag) { final XmlTag parentTag = (XmlTag) parent; final XmlElementDescriptor parentDescriptor = parentTag.getDescriptor(); if (parentDescriptor != null) { XmlElementDescriptor elementDescriptorFromParent = parentDescriptor.getElementDescriptor(tag, parentTag); if (elementDescriptorFromParent == null) { elementDescriptorFromParent = getDescriptorFromParent(tag, elementDescriptorFromParent); } if (elementDescriptorFromParent instanceof AnyXmlElementDescriptor) { final XmlElementDescriptor elementDescriptor = getElementDescriptor(tag.getLocalName(), namespace); if (elementDescriptor != null) return elementDescriptor; } return elementDescriptorFromParent; } else { return null; } } else { XmlElementDescriptor elementDescriptor = getElementDescriptor(tag.getLocalName(), tag.getNamespace()); if (elementDescriptor == null) { elementDescriptor = getDescriptorFromParent(tag, elementDescriptor); } return elementDescriptor; } }
@Override protected void checkTag( @NotNull final XmlTag tag, @NotNull final ProblemsHolder holder, final boolean isOnTheFly) { if (!(tag instanceof HtmlTag) || !XmlHighlightVisitor.shouldBeValidated(tag) || isInSpecialHtml5Namespace(tag)) { return; } XmlElementDescriptor descriptorFromContext = XmlUtil.getDescriptorFromContext(tag); PsiElement parent = tag.getParent(); XmlElementDescriptor parentDescriptor = parent instanceof XmlTag ? ((XmlTag) parent).getDescriptor() : null; XmlElementDescriptor ownDescriptor = isAbstractDescriptor(descriptorFromContext) ? tag.getDescriptor() : descriptorFromContext; if (isAbstractDescriptor(ownDescriptor) || (parentDescriptor instanceof HtmlElementDescriptorImpl && ownDescriptor instanceof HtmlElementDescriptorImpl && isAbstractDescriptor(descriptorFromContext))) { final String name = tag.getName(); if (!isCustomValuesEnabled() || !isCustomValue(name)) { final AddCustomTagOrAttributeIntentionAction action = new AddCustomTagOrAttributeIntentionAction( TAG_KEY, name, XmlEntitiesInspection.UNKNOWN_TAG); // todo: support "element is not allowed" message for html5 // some tags in html5 cannot be found in xhtml5.xsd if they are located in incorrect // context, so they get any-element descriptor (ex. "canvas: tag) final String message = isAbstractDescriptor(ownDescriptor) ? XmlErrorMessages.message("unknown.html.tag", name) : XmlErrorMessages.message("element.is.not.allowed.here", name); final PsiElement startTagName = XmlTagUtil.getStartTagNameElement(tag); assert startTagName != null; final PsiElement endTagName = XmlTagUtil.getEndTagNameElement(tag); List<LocalQuickFix> quickfixes = new ArrayList<LocalQuickFix>(); quickfixes.add(action); if (isOnTheFly) { ContainerUtil.addIfNotNull( CreateNSDeclarationIntentionFix.createFix(startTagName, ""), quickfixes); } if (HtmlUtil.isHtml5Tag(name) && !HtmlUtil.hasNonHtml5Doctype(tag)) { quickfixes.add(new SwitchToHtml5WithHighPriorityAction()); } ProblemHighlightType highlightType = tag.getContainingFile().getContext() == null ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING : ProblemHighlightType.INFORMATION; if (startTagName.getTextLength() > 0) { holder.registerProblem( startTagName, message, highlightType, quickfixes.toArray(new LocalQuickFix[quickfixes.size()])); } if (endTagName != null) { holder.registerProblem( endTagName, message, highlightType, quickfixes.toArray(new LocalQuickFix[quickfixes.size()])); } } } }
public Result beforeCharTyped( final char c, final Project project, final Editor editor, final PsiFile editedFile, final FileType fileType) { final XmlEditorOptions xmlEditorOptions = XmlEditorOptions.getInstance(); if (c == '>' && xmlEditorOptions != null && xmlEditorOptions.isAutomaticallyInsertClosingTag() && (editedFile.getLanguage() instanceof XMLLanguage || editedFile.getViewProvider().getBaseLanguage() instanceof XMLLanguage)) { PsiDocumentManager.getInstance(project).commitAllDocuments(); PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); FileViewProvider provider = editedFile.getViewProvider(); int offset = editor.getCaretModel().getOffset(); PsiElement element, elementAtCaret = null; if (offset < editor.getDocument().getTextLength()) { elementAtCaret = element = provider.findElementAt(offset, XMLLanguage.class); if (!(element instanceof PsiWhiteSpace)) { boolean nonAcceptableDelimiter = true; if (element instanceof XmlToken) { IElementType tokenType = ((XmlToken) element).getTokenType(); if (tokenType == XmlTokenType.XML_START_TAG_START || tokenType == XmlTokenType.XML_END_TAG_START) { if (offset > 0) { PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class); if (previousElement instanceof XmlToken) { tokenType = ((XmlToken) previousElement).getTokenType(); element = previousElement; nonAcceptableDelimiter = false; } } } else if (tokenType == XmlTokenType.XML_NAME) { if (element.getNextSibling() instanceof PsiErrorElement) { nonAcceptableDelimiter = false; } } if (tokenType == XmlTokenType.XML_TAG_END || tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END && element.getTextOffset() == offset - 1) { editor.getCaretModel().moveToOffset(offset + 1); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); return Result.STOP; } } if (nonAcceptableDelimiter) return Result.CONTINUE; } else { // check if right after empty end PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class); if (previousElement instanceof XmlToken) { final IElementType tokenType = ((XmlToken) previousElement).getTokenType(); if (tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END) { return Result.STOP; } } } PsiElement parent = element.getParent(); if (parent instanceof XmlText) { final String text = parent.getText(); // check / final int index = offset - parent.getTextOffset() - 1; if (index >= 0 && text.charAt(index) == '/') { return Result.CONTINUE; // already seen / } element = parent.getPrevSibling(); } else if (parent instanceof XmlTag && !(element.getPrevSibling() instanceof XmlTag)) { element = parent; } else if (parent instanceof XmlAttributeValue) { element = parent; } } else { element = provider.findElementAt(editor.getDocument().getTextLength() - 1, XMLLanguage.class); if (element == null) return Result.CONTINUE; element = element.getParent(); } if (offset > 0 && offset <= editor.getDocument().getTextLength()) { if (editor.getDocument().getCharsSequence().charAt(offset - 1) == '/') { // Some languages (e.g. GSP) allow character '/' in tag name. return Result.CONTINUE; } } if (element instanceof XmlAttributeValue) { element = element.getParent().getParent(); } while (element instanceof PsiWhiteSpace) element = element.getPrevSibling(); if (element instanceof XmlDocument) { // hack for closing tags in RHTML element = element.getLastChild(); } if (element == null) return Result.CONTINUE; if (!(element instanceof XmlTag)) { if (element instanceof XmlTokenImpl && element.getPrevSibling() != null && element.getPrevSibling().getText().equals("<")) { // tag is started and there is another text in the end editor.getDocument().insertString(offset, "</" + element.getText() + ">"); } return Result.CONTINUE; } XmlTag tag = (XmlTag) element; if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_TAG_END) != null) return Result.CONTINUE; if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_EMPTY_ELEMENT_END) != null) return Result.CONTINUE; final XmlToken startToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_START_TAG_START); if (startToken == null || !startToken.getText().equals("<")) return Result.CONTINUE; String name = tag.getName(); if (elementAtCaret instanceof XmlToken && ((XmlToken) elementAtCaret).getTokenType() == XmlTokenType.XML_NAME) { name = name.substring(0, offset - elementAtCaret.getTextOffset()); } if (tag instanceof HtmlTag && HtmlUtil.isSingleHtmlTag(name)) return Result.CONTINUE; if ("".equals(name)) return Result.CONTINUE; int tagOffset = tag.getTextRange().getStartOffset(); final XmlToken nameToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_NAME); if (nameToken != null && nameToken.getTextRange().getStartOffset() > offset) return Result.CONTINUE; HighlighterIterator iterator = ((EditorEx) editor).getHighlighter().createIterator(tagOffset); if (BraceMatchingUtil.matchBrace( editor.getDocument().getCharsSequence(), editedFile.getFileType(), iterator, true, true)) { PsiElement parent = tag.getParent(); boolean hasBalance = true; while (parent instanceof XmlTag && name.equals(((XmlTag) parent).getName())) { ASTNode astNode = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(parent.getNode()); if (astNode == null) { hasBalance = false; break; } parent = parent.getParent(); } if (hasBalance) { hasBalance = false; for (ASTNode node = parent.getNode().getLastChildNode(); node != null; node = node.getTreePrev()) { ASTNode leaf = node; if (leaf.getElementType() == TokenType.ERROR_ELEMENT) { ASTNode firstChild = leaf.getFirstChildNode(); if (firstChild != null) leaf = firstChild; else { PsiElement psiElement = PsiTreeUtil.nextLeaf(leaf.getPsi()); leaf = psiElement != null ? psiElement.getNode() : null; } if (leaf != null && leaf.getElementType() == TokenType.WHITE_SPACE) { PsiElement psiElement = PsiTreeUtil.nextLeaf(leaf.getPsi()); if (psiElement != null) leaf = psiElement.getNode(); } } if (leaf != null && leaf.getElementType() == XmlTokenType.XML_END_TAG_START) { ASTNode treeNext = leaf.getTreeNext(); IElementType treeNextType; if (treeNext != null && ((treeNextType = treeNext.getElementType()) == XmlTokenType.XML_NAME || treeNextType == XmlTokenType.XML_TAG_NAME)) { if (name.equals(treeNext.getText())) { ASTNode parentEndName = parent instanceof XmlTag ? XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(parent.getNode()) : null; hasBalance = !(parent instanceof XmlTag) || parentEndName != null && !parentEndName.getText().equals(name); break; } } } } } if (hasBalance) return Result.CONTINUE; } TextRange cdataReformatRange = null; final XmlElementDescriptor descriptor = tag.getDescriptor(); if (descriptor instanceof XmlElementDescriptorWithCDataContent) { final XmlElementDescriptorWithCDataContent cDataContainer = (XmlElementDescriptorWithCDataContent) descriptor; if (cDataContainer.requiresCdataBracesInContext(tag)) { int rangeStart = offset; @NonNls final String cDataStart = "><![CDATA["; final String inserted = cDataStart + "\n]]>"; editor.getDocument().insertString(offset, inserted); final int newoffset = offset + cDataStart.length(); editor.getCaretModel().moveToOffset(newoffset); offset += inserted.length(); cdataReformatRange = new TextRange(rangeStart, offset + 1); } } editor.getDocument().insertString(offset, "</" + name + ">"); if (cdataReformatRange != null) { PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); try { CodeStyleManager.getInstance(project) .reformatText( file, cdataReformatRange.getStartOffset(), cdataReformatRange.getEndOffset()); } catch (IncorrectOperationException e) { LOG.error(e); } } return cdataReformatRange != null ? Result.STOP : Result.CONTINUE; } return Result.CONTINUE; }
@Override public void invoke( @NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) { if (!CodeInsightUtilBase.prepareEditorForWrite(editor)) return; try { final XmlTag contextTag = getContextTag(editor, file); if (contextTag == null) { throw new CommonRefactoringUtil.RefactoringErrorHintException( "Caret should be positioned inside a tag"); } XmlElementDescriptor currentTagDescriptor = contextTag.getDescriptor(); assert currentTagDescriptor != null; final XmlElementDescriptor[] descriptors = currentTagDescriptor.getElementsDescriptors(contextTag); Arrays.sort( descriptors, new Comparator<XmlElementDescriptor>() { @Override public int compare(XmlElementDescriptor o1, XmlElementDescriptor o2) { return o1.getName().compareTo(o2.getName()); } }); final JBList list = new JBList(descriptors); list.setCellRenderer(new MyListCellRenderer()); Runnable runnable = new Runnable() { @Override public void run() { final XmlElementDescriptor selected = (XmlElementDescriptor) list.getSelectedValue(); new WriteCommandAction.Simple(project, "Generate XML Tag", file) { @Override protected void run() { if (selected == null) return; XmlTag newTag = createTag(contextTag, selected); PsiElement anchor = getAnchor(contextTag, editor, selected); if (anchor == null) { // insert it in the cursor position int offset = editor.getCaretModel().getOffset(); Document document = editor.getDocument(); document.insertString(offset, newTag.getText()); PsiDocumentManager.getInstance(project).commitDocument(document); newTag = PsiTreeUtil.getParentOfType( file.findElementAt(offset + 1), XmlTag.class, false); } else { newTag = (XmlTag) contextTag.addAfter(newTag, anchor); } if (newTag != null) { generateTag(newTag, editor); } } }.execute(); } }; if (ApplicationManager.getApplication().isUnitTestMode()) { XmlElementDescriptor descriptor = ContainerUtil.find( descriptors, new Condition<XmlElementDescriptor>() { @Override public boolean value(XmlElementDescriptor xmlElementDescriptor) { return xmlElementDescriptor.getName().equals(TEST_THREAD_LOCAL.get()); } }); list.setSelectedValue(descriptor, false); runnable.run(); } else { JBPopupFactory.getInstance() .createListPopupBuilder(list) .setTitle("Choose Tag Name") .setItemChoosenCallback(runnable) .setFilteringEnabled( new Function<Object, String>() { @Override public String fun(Object o) { return ((XmlElementDescriptor) o).getName(); } }) .createPopup() .showInBestPositionFor(editor); } } catch (CommonRefactoringUtil.RefactoringErrorHintException e) { HintManager.getInstance().showErrorHint(editor, e.getMessage()); } }
private void checkAttribute(XmlAttribute attribute) { XmlTag tag = attribute.getParent(); final String name = attribute.getName(); PsiElement prevLeaf = PsiTreeUtil.prevLeaf(attribute); if (!(prevLeaf instanceof PsiWhiteSpace)) { TextRange textRange = attribute.getTextRange(); addToResults( HighlightInfo.createHighlightInfo( tag instanceof HtmlTag ? HighlightInfoType.WARNING : HighlightInfoType.ERROR, textRange.getStartOffset(), textRange.getStartOffset(), XmlErrorMessages.message("attribute.should.be.preceded.with.space"))); } if (attribute.isNamespaceDeclaration()) { checkReferences(attribute.getValueElement()); return; } final String namespace = attribute.getNamespace(); if (XmlUtil.XML_SCHEMA_INSTANCE_URI.equals(namespace)) { checkReferences(attribute.getValueElement()); return; } XmlElementDescriptor elementDescriptor = tag.getDescriptor(); if (elementDescriptor == null || elementDescriptor instanceof AnyXmlElementDescriptor || ourDoJaxpTesting) { return; } XmlAttributeDescriptor attributeDescriptor = elementDescriptor.getAttributeDescriptor(attribute); if (attributeDescriptor == null) { if (!XmlUtil.attributeFromTemplateFramework(name, tag)) { final String localizedMessage = XmlErrorMessages.message("attribute.is.not.allowed.here", name); final HighlightInfo highlightInfo = reportAttributeProblem(tag, name, attribute, localizedMessage); if (highlightInfo != null) { final XmlFile xmlFile = (XmlFile) tag.getContainingFile(); if (xmlFile != null) { XmlExtension.getExtension(xmlFile).createAddAttributeFix(attribute, highlightInfo); } } } } else { checkDuplicateAttribute(tag, attribute); if (tag instanceof HtmlTag && attribute.getValueElement() == null && !HtmlUtil.isSingleHtmlAttribute(name)) { final String localizedMessage = XmlErrorMessages.message("empty.attribute.is.not.allowed", name); reportAttributeProblem(tag, name, attribute, localizedMessage); } // we skip resolve of attribute references since there is separate check when taking attribute // descriptors PsiReference[] attrRefs = attribute.getReferences(); doCheckRefs(attribute, attrRefs, attribute.getNamespacePrefix().length() > 0 ? 2 : 1); } }