Example #1
0
    public PsiFile resolve() {
      final PsiFile referencedFile = getReferencedFile();
      if (referencedFile != null) {
        return referencedFile;
      }

      if (myPsiFile != null) {
        final PsiElement psiElement = myPsiFile.findElementAt(myLinkInfo.offset);
        if (psiElement != null) {
          final PsiElement parent = psiElement.getParent();
          if (parent instanceof XmlTag) {
            final XmlAttribute attribute = ((XmlTag) parent).getAttribute(HREF_ATTR);
            if (attribute != null) {
              final XmlAttributeValue value = attribute.getValueElement();
              if (value != null) {
                final PsiReference[] references = value.getReferences();
                for (PsiReference reference : references) {
                  final PsiElement element = reference.resolve();
                  if (element instanceof PsiFile) {
                    return (PsiFile) element;
                  }
                }
              }
            }
          }
        }
      }

      return null;
    }
 @NotNull
 public XPathType getExpectedType(XPathExpression expr) {
   final XmlTag tag = PsiTreeUtil.getContextOfType(expr, XmlTag.class, true);
   if (tag != null && XsltSupport.isXsltTag(tag)) {
     final XsltElement element =
         XsltElementFactory.getInstance().wrapElement(tag, XsltElement.class);
     if (element instanceof XsltVariable) {
       return ((XsltVariable) element).getType();
     } else {
       final XmlAttribute attr = PsiTreeUtil.getContextOfType(expr, XmlAttribute.class, true);
       if (attr != null) {
         if (element instanceof XsltWithParam) {
           final XmlAttribute nameAttr = tag.getAttribute("name", null);
           if (nameAttr != null) {
             final XmlAttributeValue valueElement = nameAttr.getValueElement();
             if (valueElement != null) {
               final PsiReference[] references = valueElement.getReferences();
               for (PsiReference reference : references) {
                 final PsiElement psiElement = reference.resolve();
                 if (psiElement instanceof XsltVariable) {
                   return ((XsltVariable) psiElement).getType();
                 }
               }
             }
           }
         } else {
           final String name = attr.getName();
           return getTypeForTag(tag, name);
         }
       }
     }
   }
   return XPathType.UNKNOWN;
 }
 public static boolean hasBadResolve(final PsiReference reference, boolean checkSoft) {
   if (!checkSoft && reference.isSoft()) return false;
   if (reference instanceof PsiPolyVariantReference) {
     return ((PsiPolyVariantReference) reference).multiResolve(false).length == 0;
   }
   return reference.resolve() == null;
 }
  private void doCheckRefs(final PsiElement value, final PsiReference[] references, int start) {
    for (int i = start; i < references.length; ++i) {
      PsiReference reference = references[i];
      ProgressManager.checkCanceled();
      if (reference == null) {
        continue;
      }
      if (!hasBadResolve(reference, false)) {
        continue;
      }
      String description = getErrorDescription(reference);

      final int startOffset = reference.getElement().getTextRange().getStartOffset();
      final TextRange referenceRange = reference.getRangeInElement();

      // logging for IDEADEV-29655
      if (referenceRange.getStartOffset() > referenceRange.getEndOffset()) {
        LOG.error(
            "Reference range start offset > end offset:  "
                + reference
                + ", start offset: "
                + referenceRange.getStartOffset()
                + ", end offset: "
                + referenceRange.getEndOffset());
      }

      HighlightInfoType type =
          getTagProblemInfoType(PsiTreeUtil.getParentOfType(value, XmlTag.class));
      if (value instanceof XmlAttributeValue) {
        PsiElement parent = value.getParent();
        if (parent instanceof XmlAttribute) {
          String name = ((XmlAttribute) parent).getName().toLowerCase();
          if (type.getSeverity(null).compareTo(HighlightInfoType.WARNING.getSeverity(null)) > 0
              && name.endsWith("stylename")) {
            type = HighlightInfoType.WARNING;
          } else if (name.equals("href")
              && type.getSeverity(null) == HighlightInfoType.WARNING.getSeverity(null)) {
            continue;
          }
        }
      }
      HighlightInfo info =
          HighlightInfo.createHighlightInfo(
              type,
              startOffset + referenceRange.getStartOffset(),
              startOffset + referenceRange.getEndOffset(),
              description);
      addToResults(info);
      if (reference instanceof QuickFixProvider)
        ((QuickFixProvider) reference).registerQuickfix(info, reference);
      UnresolvedReferenceQuickFixProvider.registerReferenceFixes(
          reference, new QuickFixActionRegistrarImpl(info));
    }
  }
  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;
  }
 @Override
 public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
   final PsiFile containingFile = element.getContainingFile();
   if (!JavaFxFileTypeFactory.isFxml(containingFile)) return;
   if (element instanceof XmlAttributeValue) {
     final String value = ((XmlAttributeValue) element).getValue();
     if (!JavaFxPsiUtil.isExpressionBinding(value)
         && !JavaFxPsiUtil.isIncorrectExpressionBinding(value)) {
       final PsiReference[] references = element.getReferences();
       for (PsiReference reference : references) {
         if (reference instanceof JavaFxColorReference) {
           attachColorIcon(element, holder, StringUtil.unquoteString(element.getText()));
           continue;
         }
         final PsiElement resolve = reference.resolve();
         if (resolve instanceof PsiMember) {
           if (!JavaFxPsiUtil.isVisibleInFxml((PsiMember) resolve)) {
             final String symbolPresentation =
                 "'" + SymbolPresentationUtil.getSymbolPresentableText(resolve) + "'";
             final Annotation annotation =
                 holder.createErrorAnnotation(
                     element,
                     symbolPresentation
                         + (resolve instanceof PsiClass
                             ? " should be public"
                             : " should be public or annotated with @FXML"));
             if (!(resolve instanceof PsiClass)) {
               annotation.registerUniversalFix(
                   new AddAnnotationFix(
                       JavaFxCommonNames.JAVAFX_FXML_ANNOTATION,
                       (PsiMember) resolve,
                       ArrayUtil.EMPTY_STRING_ARRAY),
                   null,
                   null);
             }
           }
         }
       }
     }
   } else if (element instanceof XmlAttribute) {
     final XmlAttribute attribute = (XmlAttribute) element;
     final String attributeName = attribute.getName();
     if (!FxmlConstants.FX_BUILT_IN_ATTRIBUTES.contains(attributeName)
         && !attribute.isNamespaceDeclaration()
         && JavaFxPsiUtil.isReadOnly(attributeName, attribute.getParent())) {
       holder.createErrorAnnotation(
           element.getNavigationElement(), "Property '" + attributeName + "' is read-only");
     }
     if (FxmlConstants.SOURCE.equals(attributeName)) {
       final XmlAttributeValue valueElement = attribute.getValueElement();
       if (valueElement != null) {
         final XmlTag xmlTag = attribute.getParent();
         if (xmlTag != null) {
           final XmlTag referencedTag = JavaFxBuiltInTagDescriptor.getReferencedTag(xmlTag);
           if (referencedTag != null) {
             if (referencedTag.getTextOffset() > xmlTag.getTextOffset()) {
               holder.createErrorAnnotation(
                   valueElement.getValueTextRange(), valueElement.getValue() + " not found");
             } else if (xmlTag.getParentTag() == referencedTag.getParentTag()) {
               final Annotation annotation =
                   holder.createErrorAnnotation(
                       valueElement.getValueTextRange(), "Duplicate child added");
               annotation.registerFix(
                   new JavaFxWrapWithDefineIntention(referencedTag, valueElement.getValue()));
             }
           }
         }
       }
     }
   } else if (element instanceof XmlTag) {
     if (FxmlConstants.FX_SCRIPT.equals(((XmlTag) element).getName())) {
       final XmlTagValue tagValue = ((XmlTag) element).getValue();
       if (!StringUtil.isEmptyOrSpaces(tagValue.getText())) {
         final List<String> langs =
             JavaFxPsiUtil.parseInjectedLanguages((XmlFile) element.getContainingFile());
         if (langs.isEmpty()) {
           final ASTNode openTag = element.getNode().findChildByType(XmlTokenType.XML_NAME);
           final Annotation annotation =
               holder.createErrorAnnotation(
                   openTag != null ? openTag.getPsi() : element, "Page language not specified.");
           annotation.registerFix(new JavaFxInjectPageLanguageIntention());
         }
       }
     }
   }
 }