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;
}
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);
}
}
}
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;
}
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;
}
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;
}
Aggregations