Search in sources :

Example 16 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class DefaultXmlExtension method getPrefixDeclaration.

@Override
public SchemaPrefix getPrefixDeclaration(final XmlTag context, String namespacePrefix) {
    @NonNls String nsDeclarationAttrName = null;
    for (XmlTag t = context; t != null; t = t.getParentTag()) {
        if (t.hasNamespaceDeclarations()) {
            if (nsDeclarationAttrName == null)
                nsDeclarationAttrName = namespacePrefix.length() > 0 ? "xmlns:" + namespacePrefix : "xmlns";
            XmlAttribute attribute = t.getAttribute(nsDeclarationAttrName);
            if (attribute != null) {
                final String attrPrefix = attribute.getNamespacePrefix();
                final TextRange textRange = TextRange.from(attrPrefix.length() + 1, namespacePrefix.length());
                return new SchemaPrefix(attribute, textRange, namespacePrefix);
            }
        }
    }
    return null;
}
Also used : NonNls(org.jetbrains.annotations.NonNls) XmlAttribute(com.intellij.psi.xml.XmlAttribute) SchemaPrefix(com.intellij.psi.impl.source.xml.SchemaPrefix) TextRange(com.intellij.openapi.util.TextRange) XmlTag(com.intellij.psi.xml.XmlTag)

Example 17 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class JavaFxEventHandlerInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) {
    if (!JavaFxFileTypeFactory.isFxml(session.getFile()))
        return PsiElementVisitor.EMPTY_VISITOR;
    return new XmlElementVisitor() {

        @Override
        public void visitXmlAttributeValue(XmlAttributeValue xmlAttributeValue) {
            super.visitXmlAttributeValue(xmlAttributeValue);
            final PsiElement valueParent = xmlAttributeValue.getParent();
            if (!(valueParent instanceof XmlAttribute))
                return;
            final XmlAttribute attribute = (XmlAttribute) valueParent;
            final List<PsiMethod> eventHandlerMethods = getEventHandlerMethods(attribute);
            if (eventHandlerMethods.size() == 0)
                return;
            if (eventHandlerMethods.size() != 1) {
                holder.registerProblem(xmlAttributeValue, "Ambiguous event handler name: more than one matching method found");
            }
            if (myDetectNonVoidReturnType) {
                eventHandlerMethods.stream().map(PsiMethod::getReturnType).filter(returnType -> !PsiType.VOID.equals(returnType)).findAny().ifPresent(ignored -> holder.registerProblem(xmlAttributeValue, "Return type of event handler should be void"));
            }
            final PsiClassType declaredType = JavaFxPsiUtil.getDeclaredEventType(attribute);
            if (declaredType == null)
                return;
            for (PsiMethod method : eventHandlerMethods) {
                final PsiParameter[] parameters = method.getParameterList().getParameters();
                if (parameters.length == 1) {
                    final PsiType actualType = parameters[0].getType();
                    if (actualType instanceof PsiClassType) {
                        if (!actualType.isAssignableFrom(declaredType)) {
                            final LocalQuickFix parameterTypeFix = new ChangeParameterTypeQuickFix(attribute, method, declaredType);
                            final PsiClassType actualRawType = ((PsiClassType) actualType).rawType();
                            final PsiClassType expectedRawType = declaredType.rawType();
                            if (actualRawType.isAssignableFrom(expectedRawType)) {
                                final List<LocalQuickFix> quickFixes = new ArrayList<>();
                                quickFixes.add(parameterTypeFix);
                                collectFieldTypeFixes(attribute, (PsiClassType) actualType, quickFixes);
                                holder.registerProblem(xmlAttributeValue, "Incompatible generic parameter of event handler argument: " + actualType.getCanonicalText() + " is not assignable from " + declaredType.getCanonicalText(), quickFixes.toArray(LocalQuickFix.EMPTY_ARRAY));
                            } else {
                                holder.registerProblem(xmlAttributeValue, "Incompatible event handler argument: " + actualRawType.getCanonicalText() + " is not assignable from " + expectedRawType.getCanonicalText(), parameterTypeFix);
                            }
                        }
                    }
                }
            }
        }
    };
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) ArrayList(java.util.ArrayList) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) NotNull(org.jetbrains.annotations.NotNull)

Example 18 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class JavaFxEventHandlerInspection method collectFieldTypeFixes.

private static void collectFieldTypeFixes(@NotNull XmlAttribute attribute, @NotNull PsiClassType eventType, @NotNull List<LocalQuickFix> quickFixes) {
    final XmlTag xmlTag = attribute.getParent();
    if (xmlTag == null)
        return;
    final XmlAttribute idAttribute = xmlTag.getAttribute(FxmlConstants.FX_ID);
    if (idAttribute == null)
        return;
    final XmlAttributeValue idValue = idAttribute.getValueElement();
    if (idValue == null)
        return;
    final PsiReference reference = idValue.getReference();
    if (reference == null)
        return;
    final PsiElement element = reference.resolve();
    if (!(element instanceof PsiField))
        return;
    final PsiField tagField = (PsiField) element;
    if (tagField.hasModifierProperty(PsiModifier.STATIC) || !JavaFxPsiUtil.isVisibleInFxml(tagField))
        return;
    final PsiType tagFieldType = tagField.getType();
    if (!(tagFieldType instanceof PsiClassType))
        return;
    final PsiClassType rawFieldType = ((PsiClassType) tagFieldType).rawType();
    final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(eventType);
    final PsiClass eventClass = resolveResult.getElement();
    if (eventClass == null)
        return;
    final PsiSubstitutor eventSubstitutor = resolveResult.getSubstitutor();
    for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(eventClass)) {
        final PsiType eventTypeArgument = eventSubstitutor.substitute(typeParameter);
        final PsiClassType rawEventArgument = eventTypeArgument instanceof PsiClassType ? ((PsiClassType) eventTypeArgument).rawType() : null;
        if (rawFieldType.equals(rawEventArgument)) {
            final List<IntentionAction> fixes = HighlightUtil.getChangeVariableTypeFixes(tagField, eventTypeArgument);
            for (IntentionAction action : fixes) {
                if (action instanceof LocalQuickFix) {
                    quickFixes.add((LocalQuickFix) action);
                }
            }
            break;
        }
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) IntentionAction(com.intellij.codeInsight.intention.IntentionAction) XmlTag(com.intellij.psi.xml.XmlTag)

Example 19 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class JavaFxClassTagDescriptorBase method validate.

@Override
public void validate(@NotNull XmlTag context, @NotNull ValidationHost host) {
    final XmlTag parentTag = context.getParentTag();
    if (parentTag != null) {
        final XmlAttribute attribute = context.getAttribute(FxmlConstants.FX_CONTROLLER);
        if (attribute != null) {
            //todo add delete/move to upper tag fix
            host.addMessage(attribute.getNameElement(), "fx:controller can only be applied to root element", ValidationHost.ErrorType.ERROR);
        }
    }
    final Pair<PsiClass, Boolean> tagValueClassInfo = JavaFxPsiUtil.getTagValueClass(context, getPsiClass());
    final PsiClass aClass = tagValueClassInfo.getFirst();
    JavaFxPsiUtil.isClassAcceptable(parentTag, aClass, (errorMessage, errorType) -> host.addMessage(context.getNavigationElement(), errorMessage, errorType));
    boolean needInstantiate = !tagValueClassInfo.getSecond();
    if (needInstantiate && aClass != null && aClass.isValid()) {
        JavaFxPsiUtil.isAbleToInstantiate(aClass, errorMessage -> host.addMessage(context, errorMessage, ValidationHost.ErrorType.ERROR));
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlTag(com.intellij.psi.xml.XmlTag)

Example 20 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project intellij-community by JetBrains.

the class JavaFxControllerFieldSearcher method execute.

@Override
public boolean execute(@NotNull final ReferencesSearch.SearchParameters queryParameters, @NotNull final Processor<PsiReference> consumer) {
    final PsiElement elementToSearch = queryParameters.getElementToSearch();
    if (elementToSearch instanceof PsiField) {
        final PsiField field = (PsiField) elementToSearch;
        final PsiClass containingClass = ReadAction.compute(() -> field.getContainingClass());
        if (containingClass != null) {
            final String qualifiedName = ReadAction.compute(() -> containingClass.getQualifiedName());
            if (qualifiedName != null) {
                Project project = PsiUtilCore.getProjectInReadAction(containingClass);
                final List<PsiFile> fxmlWithController = JavaFxControllerClassIndex.findFxmlWithController(project, qualifiedName);
                for (final PsiFile file : fxmlWithController) {
                    ApplicationManager.getApplication().runReadAction(() -> {
                        final String fieldName = field.getName();
                        if (fieldName == null)
                            return;
                        final VirtualFile virtualFile = file.getViewProvider().getVirtualFile();
                        final SearchScope searchScope = queryParameters.getEffectiveSearchScope();
                        if (searchScope.contains(virtualFile)) {
                            file.accept(new XmlRecursiveElementVisitor() {

                                @Override
                                public void visitXmlAttributeValue(final XmlAttributeValue value) {
                                    final PsiReference reference = value.getReference();
                                    if (reference != null) {
                                        final PsiElement resolve = reference.resolve();
                                        if (resolve instanceof XmlAttributeValue) {
                                            final PsiElement parent = resolve.getParent();
                                            if (parent instanceof XmlAttribute) {
                                                final XmlAttribute attribute = (XmlAttribute) parent;
                                                if (FxmlConstants.FX_ID.equals(attribute.getName()) && fieldName.equals(attribute.getValue())) {
                                                    consumer.process(reference);
                                                }
                                            }
                                        }
                                    }
                                }
                            });
                        }
                    });
                }
            }
        }
    }
    return true;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) Project(com.intellij.openapi.project.Project) SearchScope(com.intellij.psi.search.SearchScope)

Aggregations

XmlAttribute (com.intellij.psi.xml.XmlAttribute)220 XmlTag (com.intellij.psi.xml.XmlTag)116 PsiElement (com.intellij.psi.PsiElement)60 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)57 NotNull (org.jetbrains.annotations.NotNull)44 XmlFile (com.intellij.psi.xml.XmlFile)37 Nullable (org.jetbrains.annotations.Nullable)27 Project (com.intellij.openapi.project.Project)25 VirtualFile (com.intellij.openapi.vfs.VirtualFile)20 TextRange (com.intellij.openapi.util.TextRange)18 XmlAttributeDescriptor (com.intellij.xml.XmlAttributeDescriptor)18 ArrayList (java.util.ArrayList)18 PsiFile (com.intellij.psi.PsiFile)17 PsiReference (com.intellij.psi.PsiReference)17 IncorrectOperationException (com.intellij.util.IncorrectOperationException)10 DomElement (com.intellij.util.xml.DomElement)10 Result (com.intellij.openapi.application.Result)9 XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)9 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)8 XmlElement (com.intellij.psi.xml.XmlElement)6