コード例 #1
0
  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);
    }
  }
コード例 #2
0
  private void checkDuplicateAttribute(XmlTag tag, final XmlAttribute attribute) {
    if (skipValidation(tag)) {
      return;
    }

    final XmlAttribute[] attributes = tag.getAttributes();
    final PsiFile containingFile = tag.getContainingFile();
    final XmlExtension extension =
        containingFile instanceof XmlFile
            ? XmlExtension.getExtension(containingFile)
            : XmlExtension.DEFAULT_EXTENSION;
    for (XmlAttribute tagAttribute : attributes) {
      ProgressManager.checkCanceled();
      if (attribute != tagAttribute
          && Comparing.strEqual(attribute.getName(), tagAttribute.getName())) {
        final String localName = attribute.getLocalName();

        if (extension.canBeDuplicated(tagAttribute))
          continue; // multiple import attributes are allowed in jsp directive

        HighlightInfo highlightInfo =
            HighlightInfo.createHighlightInfo(
                getTagProblemInfoType(tag),
                XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(
                    SourceTreeToPsiMap.psiElementToTree(attribute)),
                XmlErrorMessages.message("duplicate.attribute", localName));
        addToResults(highlightInfo);

        IntentionAction intentionAction = new RemoveAttributeIntentionFix(localName, attribute);

        QuickFixAction.registerQuickFixAction(highlightInfo, intentionAction);
      }
    }
  }
コード例 #3
0
  @Override
  public void visitXmlProcessingInstruction(XmlProcessingInstruction processingInstruction) {
    super.visitXmlProcessingInstruction(processingInstruction);
    PsiElement parent = processingInstruction.getParent();

    if (parent instanceof XmlProlog && processingInstruction.getText().startsWith("<?xml")) {
      for (PsiElement e = PsiTreeUtil.prevLeaf(processingInstruction);
          e != null;
          e = PsiTreeUtil.prevLeaf(e)) {
        if (e instanceof PsiWhiteSpace && PsiTreeUtil.prevLeaf(e) != null
            || e instanceof OuterLanguageElement) {
          continue;
        }
        PsiElement eParent = e.getParent();
        if (eParent instanceof PsiComment) e = eParent;
        if (eParent instanceof XmlProcessingInstruction) break;

        addToResults(
            HighlightInfo.createHighlightInfo(
                HighlightInfoType.ERROR,
                e,
                XmlErrorMessages.message("xml.declaration.should.precede.all.document.content")));
      }
    }
  }
コード例 #4
0
  @Override
  public void visitXmlToken(XmlToken token) {
    IElementType tokenType = token.getTokenType();
    if (tokenType == XmlTokenType.XML_NAME || tokenType == XmlTokenType.XML_TAG_NAME) {
      PsiElement element = token.getPrevSibling();
      while (element instanceof PsiWhiteSpace) element = element.getPrevSibling();

      if (element instanceof XmlToken) {
        if (((XmlToken) element).getTokenType() == XmlTokenType.XML_START_TAG_START) {
          PsiElement parent = element.getParent();

          if (parent instanceof XmlTag
              && !(token.getNextSibling() instanceof OuterLanguageElement)) {
            checkTag((XmlTag) parent);
          }
        }
      } else {
        PsiElement parent = token.getParent();

        if (parent instanceof XmlAttribute
            && !(token.getNextSibling() instanceof OuterLanguageElement)) {
          checkAttribute((XmlAttribute) parent);
        }
      }
    } else if (tokenType == XmlTokenType.XML_DATA_CHARACTERS
        && token.getParent() instanceof XmlText) {
      if (token.textContains(']') && token.textContains('>')) {
        String s = token.getText();
        String marker = "]]>";
        int i = s.indexOf(marker);

        if (i != -1) { // TODO: fix
          TextRange textRange = token.getTextRange();
          int start = textRange.getStartOffset() + i;
          HighlightInfoType type =
              PsiTreeUtil.getParentOfType(token, XmlTag.class) instanceof HtmlTag
                  ? HighlightInfoType.WARNING
                  : HighlightInfoType.ERROR;
          HighlightInfo info =
              HighlightInfo.createHighlightInfo(
                  type,
                  start,
                  start + marker.length(),
                  XmlErrorMessages.message(
                      "cdata.end.should.not.appear.in.content.unless.to.mark.end.of.cdata.section"));
          addToResults(info);
        }
      }
    }
  }
コード例 #5
0
  private void checkRequiredAttributes(
      XmlTag tag, String name, XmlElementDescriptor elementDescriptor) {
    XmlAttributeDescriptor[] attributeDescriptors = elementDescriptor.getAttributesDescriptors(tag);
    Set<String> requiredAttributes = null;

    for (XmlAttributeDescriptor attribute : attributeDescriptors) {
      if (attribute != null && attribute.isRequired()) {
        if (requiredAttributes == null) {
          requiredAttributes = new HashSet<String>();
        }
        requiredAttributes.add(attribute.getName(tag));
      }
    }

    if (requiredAttributes != null) {
      for (final String attrName : requiredAttributes) {
        if (tag.getAttribute(attrName, "") == null
            && !XmlExtension.getExtension(tag.getContainingFile())
                .isRequiredAttributeImplicitlyPresent(tag, attrName)) {

          final InsertRequiredAttributeFix insertRequiredAttributeIntention =
              new InsertRequiredAttributeFix(tag, attrName, null);
          final String localizedMessage =
              XmlErrorMessages.message("element.doesnt.have.required.attribute", name, attrName);
          final InspectionProfile profile =
              InspectionProjectProfileManager.getInstance(tag.getProject()).getInspectionProfile();
          final LocalInspectionToolWrapper toolWrapper =
              (LocalInspectionToolWrapper)
                  profile.getInspectionTool(RequiredAttributesInspection.SHORT_NAME, tag);
          if (toolWrapper != null) {
            RequiredAttributesInspection inspection =
                (RequiredAttributesInspection) toolWrapper.getTool();
            reportOneTagProblem(
                tag,
                attrName,
                localizedMessage,
                insertRequiredAttributeIntention,
                HighlightDisplayKey.find(RequiredAttributesInspection.SHORT_NAME),
                inspection,
                XmlEntitiesInspection.NOT_REQUIRED_ATTRIBUTE);
          }
        }
      }
    }
  }
コード例 #6
0
  public static String getErrorDescription(final PsiReference reference) {
    String message;
    if (reference instanceof EmptyResolveMessageProvider) {
      message = ((EmptyResolveMessageProvider) reference).getUnresolvedMessagePattern();
    } else {
      //noinspection UnresolvedPropertyKey
      message = PsiBundle.message("cannot.resolve.symbol");
    }

    String description;
    try {
      description = MessageFormat.format(message, reference.getCanonicalText());
    } catch (IllegalArgumentException ex) {
      // unresolvedMessage provided by third-party reference contains wrong format string (e.g. {}),
      // tolerate it
      description = message;
      LOG.warn(
          XmlErrorMessages.message(
              "plugin.reference.message.problem", reference.getClass().getName(), message));
    }
    return description;
  }
コード例 #7
0
  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);
    }
  }