Search in sources :

Example 36 with XmlElement

use of com.intellij.psi.xml.XmlElement in project android by JetBrains.

the class AttributeProcessingUtil method isLayoutAttributeRequired.

/**
   * Check whether layout tag attribute with given name should be marked as required.
   * Currently, tests for layout_width and layout_height attribute and marks them as required in appropriate context.
   */
public static boolean isLayoutAttributeRequired(@NotNull XmlName attributeName, @NotNull DomElement element) {
    // Mark layout_width and layout_height required - if the context calls for it
    String localName = attributeName.getLocalName();
    if (!(ATTR_LAYOUT_WIDTH.equals(localName) || ATTR_LAYOUT_HEIGHT.equals(localName))) {
        return false;
    }
    if ((element instanceof LayoutViewElement || element instanceof Fragment) && NS_RESOURCES.equals(attributeName.getNamespaceKey())) {
        XmlElement xmlElement = element.getXmlElement();
        XmlTag tag = xmlElement instanceof XmlTag ? (XmlTag) xmlElement : null;
        String tagName = tag != null ? tag.getName() : null;
        if (!SIZE_NOT_REQUIRED_TAG_NAMES.contains(tagName) && (tag == null || tag.getAttribute(ATTR_STYLE) == null)) {
            XmlTag parentTag = tag != null ? tag.getParentTag() : null;
            String parentTagName = parentTag != null ? parentTag.getName() : null;
            if (!SIZE_NOT_REQUIRED_PARENT_TAG_NAMES.contains(parentTagName)) {
                return true;
            }
        }
    }
    return false;
}
Also used : XmlElement(com.intellij.psi.xml.XmlElement) XmlTag(com.intellij.psi.xml.XmlTag)

Example 37 with XmlElement

use of com.intellij.psi.xml.XmlElement in project android by JetBrains.

the class AndroidResourceRenameResourceProcessor method prepareValueResourceRenaming.

private static void prepareValueResourceRenaming(PsiElement element, String newName, Map<PsiElement, String> allRenames, final AndroidFacet facet) {
    ResourceManager manager = facet.getLocalResourceManager();
    XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
    assert tag != null;
    String type = manager.getValueResourceType(tag);
    assert type != null;
    Project project = tag.getProject();
    DomElement domElement = DomManager.getDomManager(project).getDomElement(tag);
    assert domElement instanceof ResourceElement;
    String name = ((ResourceElement) domElement).getName().getValue();
    assert name != null;
    List<ResourceElement> resources = manager.findValueResources(type, name);
    for (ResourceElement resource : resources) {
        XmlElement xmlElement = resource.getName().getXmlAttributeValue();
        if (!element.getManager().areElementsEquivalent(element, xmlElement)) {
            allRenames.put(xmlElement, newName);
        }
    }
    if (getResourceType(element) == ResourceType.STYLE) {
        // For styles, try also to find child styles defined by name (i.e. "ParentName.StyleName") and add them
        // to the rename list. This will allow the rename processor to also handle the references to those. For example,
        // If you rename "MyTheme" and your manifest theme is "MyTheme.NoActionBar", this will make sure that
        // the reference from the manifest is also updated by adding "MyTheme.NoActionBar" to the rename list.
        // We iterate the styles in order to cascade any changes to children down the hierarchy.
        // List of styles that will be renamed.
        HashSet<String> renamedStyles = Sets.newHashSet();
        renamedStyles.add(name);
        final String stylePrefix = name + ".";
        Collection<String> renameCandidates;
        ResourceType resourceType = ResourceType.getEnum(type);
        if (resourceType == null) {
            renameCandidates = Collections.emptyList();
        } else {
            renameCandidates = Collections2.filter(manager.getResourceNames(resourceType), new Predicate<String>() {

                @Override
                public boolean apply(String input) {
                    return input.startsWith(stylePrefix);
                }
            });
        }
        for (String resourceName : ORDER_BY_LENGTH.sortedCopy(renameCandidates)) {
            // resourceName.lastIndexOf will never return -1 because we've filtered all names that
            // do not contain stylePrefix
            String parentName = resourceName.substring(0, resourceName.lastIndexOf('.'));
            if (!renamedStyles.contains(parentName)) {
                // This resource's parent wasn't affected by the rename
                continue;
            }
            for (ResourceElement resource : manager.findValueResources(type, resourceName)) {
                if (!(resource instanceof Style) || ((Style) resource).getParentStyle().getXmlAttributeValue() != null) {
                    // This element is not a style or does have an explicit parent so we do not rename it.
                    continue;
                }
                XmlAttributeValue xmlElement = resource.getName().getXmlAttributeValue();
                if (xmlElement != null) {
                    String newStyleName = newName + StringUtil.trimStart(resourceName, name);
                    allRenames.put(new ValueResourceElementWrapper(xmlElement), newStyleName);
                    renamedStyles.add(resourceName);
                }
            }
        }
    }
    PsiField[] resFields = AndroidResourceUtil.findResourceFieldsForValueResource(tag, false);
    for (PsiField resField : resFields) {
        String escaped = AndroidResourceUtil.getFieldNameByResourceName(newName);
        allRenames.put(resField, escaped);
    }
    // Also rename the dependent fields, e.g. if you rename <declare-styleable name="Foo">,
    // we have to rename not just R.styleable.Foo but the also R.styleable.Foo_* attributes
    PsiField[] styleableFields = AndroidResourceUtil.findStyleableAttributeFields(tag, false);
    if (styleableFields.length > 0) {
        String tagName = tag.getName();
        boolean isDeclareStyleable = tagName.equals(TAG_DECLARE_STYLEABLE);
        boolean isAttr = !isDeclareStyleable && tagName.equals(TAG_ATTR) && tag.getParentTag() != null;
        assert isDeclareStyleable || isAttr;
        String style = isAttr ? tag.getParentTag().getAttributeValue(ATTR_NAME) : null;
        for (PsiField resField : styleableFields) {
            String fieldName = resField.getName();
            String newAttributeName;
            if (isDeclareStyleable && fieldName.startsWith(name)) {
                newAttributeName = newName + fieldName.substring(name.length());
            } else if (isAttr && style != null) {
                newAttributeName = style + '_' + newName;
            } else {
                newAttributeName = name;
            }
            String escaped = AndroidResourceUtil.getFieldNameByResourceName(newAttributeName);
            allRenames.put(resField, escaped);
        }
    }
}
Also used : ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) ResourceType(com.android.resources.ResourceType) ResourceManager(org.jetbrains.android.resourceManagers.ResourceManager) LocalResourceManager(org.jetbrains.android.resourceManagers.LocalResourceManager) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) Predicate(com.google.common.base.Predicate) Project(com.intellij.openapi.project.Project) DomElement(com.intellij.util.xml.DomElement) XmlElement(com.intellij.psi.xml.XmlElement) Style(org.jetbrains.android.dom.resources.Style) XmlTag(com.intellij.psi.xml.XmlTag) LazyValueResourceElementWrapper(org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper) ValueResourceElementWrapper(org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper)

Example 38 with XmlElement

use of com.intellij.psi.xml.XmlElement in project android by JetBrains.

the class ResourceReferenceConverter method getVariants.

@Override
@NotNull
public Collection<? extends ResourceValue> getVariants(ConvertContext context) {
    Set<ResourceValue> result = new HashSet<>();
    Module module = context.getModule();
    if (module == null)
        return result;
    AndroidFacet facet = AndroidFacet.getInstance(module);
    if (facet == null)
        return result;
    final Set<ResourceType> recommendedTypes = getResourceTypes(context);
    if (recommendedTypes.contains(ResourceType.BOOL) && recommendedTypes.size() < VALUE_RESOURCE_TYPES.size()) {
        // Is this resource reference expected to be a @bool reference? Specifically
        // check that it's not allowed to be *all* resource types since that's a fallback
        // for when we don't have metadata, and we don't want to show true and false
        // as possible completions for things like com.google.android.gms.version
        result.add(ResourceValue.literal(VALUE_TRUE));
        result.add(ResourceValue.literal(VALUE_FALSE));
    }
    // hack to check if it is a real id attribute
    if (recommendedTypes.contains(ResourceType.ID) && recommendedTypes.size() == 1) {
        result.add(ResourceValue.reference(NEW_ID_PREFIX));
    }
    XmlElement element = context.getXmlElement();
    if (element == null)
        return result;
    String value = getValue(element);
    assert value != null;
    boolean startsWithRefChar = StringUtil.startsWithChar(value, '@');
    if (!myQuiet || startsWithRefChar) {
        String resourcePackage = null;
        // Retrieve the system prefix depending on the prefix settings ("@android:" or "android:")
        String systemPrefix = getPackagePrefix(SYSTEM_RESOURCE_PACKAGE, myWithPrefix || startsWithRefChar);
        if (value.startsWith(systemPrefix)) {
            resourcePackage = SYSTEM_RESOURCE_PACKAGE;
        } else {
            result.add(ResourceValue.literal(systemPrefix));
        }
        final char prefix = myWithPrefix || startsWithRefChar ? '@' : 0;
        if (value.startsWith(NEW_ID_PREFIX)) {
            addVariantsForIdDeclaration(result, facet, prefix, value);
        }
        if (recommendedTypes.size() >= 1 && myExpandedCompletionSuggestion) {
            // We will add the resource type (e.g. @style/) if the current value starts like a reference using @
            final boolean explicitResourceType = startsWithRefChar || myWithExplicitResourceType;
            for (final ResourceType type : recommendedTypes) {
                addResourceReferenceValues(facet, prefix, type, resourcePackage, result, explicitResourceType);
            }
        } else {
            final Set<ResourceType> filteringSet = SYSTEM_RESOURCE_PACKAGE.equals(resourcePackage) ? null : getResourceTypesInCurrentModule(facet);
            for (ResourceType resourceType : ResourceType.values()) {
                final String type = resourceType.getName();
                String typePrefix = getTypePrefix(resourcePackage, type);
                if (value.startsWith(typePrefix)) {
                    addResourceReferenceValues(facet, prefix, resourceType, resourcePackage, result, true);
                } else if (recommendedTypes.contains(resourceType) && (filteringSet == null || filteringSet.contains(resourceType))) {
                    result.add(ResourceValue.literal(typePrefix));
                }
            }
        }
    }
    if (myAllowAttributeReferences) {
        completeAttributeReferences(value, facet, result);
    }
    final ResolvingConverter<String> additionalConverter = getAdditionalConverter(context);
    if (additionalConverter != null) {
        for (String variant : additionalConverter.getVariants(context)) {
            result.add(ResourceValue.literal(variant));
        }
    }
    return result;
}
Also used : ResourceValue(org.jetbrains.android.dom.resources.ResourceValue) XmlElement(com.intellij.psi.xml.XmlElement) ResourceType(com.android.resources.ResourceType) AndroidResourceType(org.jetbrains.android.dom.AndroidResourceType) Module(com.intellij.openapi.module.Module) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) NotNull(org.jetbrains.annotations.NotNull)

Example 39 with XmlElement

use of com.intellij.psi.xml.XmlElement in project intellij-plugins by JetBrains.

the class ActionScriptImportHandler method _resolveTypeName.

// TODO _str should be JSReferenceExpression for caching!
@Nullable
private JSImportedElementResolveResult _resolveTypeName(@Nullable final String _name, @NotNull PsiElement context) {
    String name = _name;
    if (name == null)
        return null;
    JSResolveUtil.GenericSignature genericSignature = JSResolveUtil.extractGenericSignature(name);
    if (genericSignature != null) {
        name = genericSignature.elementType;
    }
    final Ref<JSImportedElementResolveResult> resultRef = new Ref<>();
    final String name1 = name;
    JSResolveUtil.walkOverStructure(context, context1 -> {
        JSImportedElementResolveResult resolved = null;
        if (context1 instanceof XmlBackedJSClassImpl) {
            XmlTag rootTag = ((XmlBackedJSClassImpl) context1).getParent();
            if (rootTag != null && name1.equals(rootTag.getLocalName())) {
                final XmlElementDescriptor descriptor = rootTag.getDescriptor();
                PsiElement element = descriptor != null ? descriptor.getDeclaration() : null;
                if (element instanceof XmlFile) {
                    element = XmlBackedJSClassFactory.getXmlBackedClass((XmlFile) element);
                }
                final String s = element instanceof JSClass ? ((JSClass) element).getQualifiedName() : rootTag.getLocalName();
                resolved = new JSImportedElementResolveResult(s);
            } else {
                resolved = resolveTypeNameUsingImports(name1, context1);
            }
        } else if (context1 instanceof JSQualifiedNamedElement) {
            if (context1 instanceof JSClass && name1.equals(context1.getName())) {
                resolved = new JSImportedElementResolveResult(((JSQualifiedNamedElement) context1).getQualifiedName());
            } else {
                resolved = resolveTypeNameUsingImports(name1, context1);
                if (resolved == null && context1.getParent() instanceof JSFile) {
                    final String qName = ((JSQualifiedNamedElement) context1).getQualifiedName();
                    final String packageName = qName == null ? "" : context1 instanceof JSPackageStatement ? qName + "." : qName.substring(0, qName.lastIndexOf('.') + 1);
                    if (packageName.length() != 0) {
                        final PsiElement byQName = JSClassResolver.findClassFromNamespace(packageName + name1, context1);
                        if (byQName instanceof JSQualifiedNamedElement) {
                            resolved = new JSImportedElementResolveResult(((JSQualifiedNamedElement) byQName).getQualifiedName());
                        }
                    }
                }
            }
        } else {
            resolved = resolveTypeNameUsingImports(name1, context1);
            PsiElement contextOfContext;
            if (resolved == null && context1 instanceof JSFile && (contextOfContext = context1.getContext()) != null) {
                XmlBackedJSClassImpl clazz = contextOfContext instanceof XmlElement ? (XmlBackedJSClassImpl) XmlBackedJSClassImpl.getContainingComponent((XmlElement) contextOfContext) : null;
                if (clazz != null) {
                    SinkResolveProcessor r = new SinkResolveProcessor(name1, new ResolveResultSink(null, name1));
                    r.setForceImportsForPlace(true);
                    boolean b = clazz.doImportFromScripts(r, clazz);
                    if (!b) {
                        PsiElement resultFromProcessor = r.getResult();
                        JSQualifiedNamedElement clazzFromComponent = resultFromProcessor instanceof JSQualifiedNamedElement ? (JSQualifiedNamedElement) resultFromProcessor : null;
                        if (clazzFromComponent != null) {
                            resolved = new JSImportedElementResolveResult(clazzFromComponent.getQualifiedName(), clazz, null);
                        }
                    }
                }
            }
        }
        if (resolved != null) {
            resultRef.set(resolved);
            return false;
        }
        if (context1 instanceof JSPackageStatement)
            return false;
        return true;
    });
    JSImportedElementResolveResult result = resultRef.get();
    if (genericSignature != null && result != null) {
        // TODO: more than one type parameter
        StringBuilder genericSignatureBuffer = new StringBuilder();
        genericSignatureBuffer.append(".<");
        genericSignatureBuffer.append(resolveTypeName(genericSignature.genericType, context).getQualifiedName());
        genericSignatureBuffer.append(">");
        result = result.appendSignature(genericSignatureBuffer.toString());
    }
    return result;
}
Also used : XmlBackedJSClassImpl(com.intellij.lang.javascript.flex.XmlBackedJSClassImpl) XmlFile(com.intellij.psi.xml.XmlFile) JSPackageStatement(com.intellij.lang.javascript.psi.ecmal4.JSPackageStatement) JSQualifiedNamedElement(com.intellij.lang.javascript.psi.ecmal4.JSQualifiedNamedElement) Ref(com.intellij.openapi.util.Ref) XmlElement(com.intellij.psi.xml.XmlElement) JSFile(com.intellij.lang.javascript.psi.JSFile) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) JSClass(com.intellij.lang.javascript.psi.ecmal4.JSClass) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag) Nullable(org.jetbrains.annotations.Nullable)

Example 40 with XmlElement

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

the class AntDomPropertyDefiningElement method getNavigationElement.

public final PsiElement getNavigationElement(String propertyName) {
    for (GenericAttributeValue<String> value : getPropertyDefiningAttributes()) {
        if (!propertyName.equals(value.getStringValue())) {
            continue;
        }
        final DomTarget domTarget = DomTarget.getTarget(this, value);
        return domTarget != null ? PomService.convertToPsi(domTarget) : null;
    }
    for (String propName : getImplicitPropertyNames()) {
        if (propertyName.equals(propName)) {
            final DomTarget domTarget = DomTarget.getTarget(this);
            if (domTarget != null) {
                return PomService.convertToPsi(domTarget);
            }
            final XmlElement xmlElement = getXmlElement();
            return xmlElement != null ? xmlElement.getNavigationElement() : null;
        }
    }
    return null;
}
Also used : DomTarget(com.intellij.util.xml.DomTarget) XmlElement(com.intellij.psi.xml.XmlElement)

Aggregations

XmlElement (com.intellij.psi.xml.XmlElement)69 PsiElement (com.intellij.psi.PsiElement)16 NotNull (org.jetbrains.annotations.NotNull)16 Nullable (org.jetbrains.annotations.Nullable)11 XmlTag (com.intellij.psi.xml.XmlTag)10 PsiFile (com.intellij.psi.PsiFile)7 PsiReference (com.intellij.psi.PsiReference)6 XmlAttribute (com.intellij.psi.xml.XmlAttribute)6 XmlFile (com.intellij.psi.xml.XmlFile)6 Manifest (org.jetbrains.android.dom.manifest.Manifest)5 Module (com.intellij.openapi.module.Module)4 Project (com.intellij.openapi.project.Project)4 DomElement (com.intellij.util.xml.DomElement)4 ArrayList (java.util.ArrayList)4 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)3 CompositePsiElement (com.intellij.psi.impl.source.tree.CompositePsiElement)3 SmartList (com.intellij.util.SmartList)3 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)3 ResourceType (com.android.resources.ResourceType)2 Result (com.intellij.openapi.application.Result)2