use of com.intellij.util.xml.XmlName in project android by JetBrains.
the class AttributeProcessingUtil method registerAttribute.
private static void registerAttribute(@NotNull AttributeDefinition attrDef, @Nullable String parentStyleableName, @Nullable String namespaceKey, @NotNull DomElement element, @NotNull AttributeProcessor callback) {
String name = attrDef.getName();
if (!NS_RESOURCES.equals(namespaceKey) && name.startsWith(PREFIX_ANDROID)) {
// A styleable-definition in the app namespace (user specified or from a library) can include
// a reference to a platform attribute. In such a case, register it under the android namespace
// as opposed to the app namespace. See https://code.google.com/p/android/issues/detail?id=171162
name = name.substring(PREFIX_ANDROID.length());
namespaceKey = NS_RESOURCES;
}
XmlName xmlName = new XmlName(name, namespaceKey);
final DomExtension extension = callback.processAttribute(xmlName, attrDef, parentStyleableName);
if (extension == null) {
return;
}
Converter converter = AndroidDomUtil.getSpecificConverter(xmlName, element);
if (converter == null) {
if (TOOLS_URI.equals(namespaceKey)) {
converter = ToolsAttributeUtil.getConverter(attrDef);
} else {
converter = AndroidDomUtil.getConverter(attrDef);
if (converter != null && element.getParentOfType(Manifest.class, true) != null) {
converter = new ManifestPlaceholderConverter(converter);
}
}
}
if (converter != null) {
extension.setConverter(converter, mustBeSoft(converter, attrDef.getFormats()));
}
// tag completion. If attribute is not required, no additional action is needed.
if (element instanceof LayoutElement && isLayoutAttributeRequired(xmlName, element) || element instanceof ManifestElement && AndroidManifestUtils.isRequiredAttribute(xmlName, element)) {
extension.addCustomAnnotation(new RequiredImpl());
}
}
use of com.intellij.util.xml.XmlName in project android by JetBrains.
the class AttributeProcessingUtil method processXmlAttributes.
/**
* Yield attributes for resources in xml/ folder
*/
public static void processXmlAttributes(@NotNull AndroidFacet facet, @NotNull XmlTag tag, @NotNull XmlResourceElement element, @NotNull Set<XmlName> skipAttrNames, @NotNull AttributeProcessor callback) {
final String tagName = tag.getName();
String styleableName = AndroidXmlResourcesUtil.SPECIAL_STYLEABLE_NAMES.get(tagName);
if (styleableName != null) {
final Set<XmlName> newSkipAttrNames = new HashSet<>();
if (element instanceof Intent) {
newSkipAttrNames.add(new XmlName("action", NS_RESOURCES));
}
registerAttributes(facet, element, styleableName, SYSTEM_RESOURCE_PACKAGE, callback, newSkipAttrNames);
}
// for preferences
Map<String, PsiClass> prefClassMap = getPreferencesClassMap(facet);
String prefClassName = element.getXmlTag().getName();
PsiClass c = prefClassMap.get(prefClassName);
// register attributes by preference class
registerAttributesForClassAndSuperclasses(facet, element, c, callback, skipAttrNames);
// register attributes by widget
String widgetClassName = AndroidTextUtils.trimEndOrNullize(prefClassName, PREFERENCE_TAG_NAME);
if (widgetClassName != null) {
PsiClass widgetClass = LayoutViewClassUtils.findClassByTagName(facet, widgetClassName, AndroidUtils.VIEW_CLASS_NAME);
registerAttributesForClassAndSuperclasses(facet, element, widgetClass, callback, skipAttrNames);
}
}
use of com.intellij.util.xml.XmlName in project android by JetBrains.
the class AttributeProcessingUtil method processAttributes.
/**
* Enumerate attributes that are available for the given XML tag, represented by {@link AndroidDomElement},
* and "return" them via {@link AttributeProcessor}.
*
* Primary user is {@link AndroidDomExtender}, which uses it to provide code completion facilities when
* editing XML files in text editor.
*
* Implementation of the method implements {@link Styleable} annotation handling and dispatches on tag type
* using instanceof checks for adding attributes that don't come from styleable definitions with statically
* known names.
*
* @param processAllExistingAttrsFirst whether already existing attributes should be returned first
*/
public static void processAttributes(@NotNull AndroidDomElement element, @NotNull AndroidFacet facet, boolean processAllExistingAttrsFirst, @NotNull AttributeProcessor callback) {
XmlTag tag = element.getXmlTag();
final Set<XmlName> skippedAttributes = processAllExistingAttrsFirst ? registerExistingAttributes(facet, tag, element, callback) : new HashSet<>();
if (element instanceof ManifestElement) {
processManifestAttributes(tag, element, callback);
} else if (element instanceof LayoutElement) {
processLayoutAttributes(facet, tag, (LayoutElement) element, skippedAttributes, callback);
} else if (element instanceof XmlResourceElement) {
processXmlAttributes(facet, tag, (XmlResourceElement) element, skippedAttributes, callback);
} else if (element instanceof XmlRawResourceElement) {
processRawAttributes(tag, callback);
}
// If DOM element is annotated with @Styleable annotation, load a styleable definition
// from Android framework with the name provided in annotation and register all attributes
// from it for code highlighting and completion.
final Styleable styleableAnnotation = element.getAnnotation(Styleable.class);
if (styleableAnnotation == null) {
return;
}
final SystemResourceManager manager = facet.getSystemResourceManager();
if (manager == null) {
return;
}
final AttributeDefinitions definitions = manager.getAttributeDefinitions();
if (definitions == null) {
return;
}
if (element instanceof MenuItem) {
processMenuItemAttributes(facet, element, skippedAttributes, callback);
return;
}
for (String styleableName : styleableAnnotation.value()) {
final StyleableDefinition styleable = definitions.getStyleableByName(styleableName);
if (styleable == null) {
// DOM element is annotated with @Styleable annotation, but styleable definition with
// provided name is not there in Android framework. This is a bug, so logging it as a warning.
getLog().warn(String.format("@Styleable(%s) annotation doesn't point to existing styleable", styleableName));
} else {
registerStyleableAttributes(element, styleable, ANDROID_URI, callback, skippedAttributes);
}
}
// TODO: figure it out how to make it DRY without introducing new method with lots of arguments
if (element instanceof InterpolatorElement) {
final String styleableName = InterpolatorDomFileDescription.getInterpolatorStyleableByTagName(tag.getName());
if (styleableName != null) {
final StyleableDefinition styleable = definitions.getStyleableByName(styleableName);
if (styleable == null) {
getLog().warn(String.format("%s doesn't point to existing styleable for interpolator", styleableName));
} else {
registerStyleableAttributes(element, styleable, ANDROID_URI, callback, skippedAttributes);
}
}
}
}
use of com.intellij.util.xml.XmlName in project android by JetBrains.
the class AttributeProcessingUtil method registerStyleableAttributes.
private static void registerStyleableAttributes(@NotNull DomElement element, @NotNull StyleableDefinition styleable, @Nullable String namespace, @NotNull AttributeProcessor callback, @NotNull Set<XmlName> skippedAttributes) {
for (AttributeDefinition attrDef : styleable.getAttributes()) {
String attrName = attrDef.getName();
final XmlName xmlName = new XmlName(attrName, namespace);
if (!skippedAttributes.contains(xmlName)) {
skippedAttributes.add(xmlName);
registerAttribute(attrDef, styleable.getName(), namespace, element, callback);
}
}
}
use of com.intellij.util.xml.XmlName in project android by JetBrains.
the class AttributeProcessingUtil method registerToolsAttribute.
private static void registerToolsAttribute(@NotNull String attributeName, @NotNull AttributeProcessor callback) {
final AttributeDefinition definition = ToolsAttributeUtil.getAttrDefByName(attributeName);
if (definition != null) {
final XmlName name = new XmlName(attributeName, TOOLS_URI);
final DomExtension domExtension = callback.processAttribute(name, definition, null);
final ResolvingConverter converter = ToolsAttributeUtil.getConverter(definition);
if (domExtension != null && converter != null) {
domExtension.setConverter(converter);
}
} else {
getLog().warn("No attribute definition for tools attribute " + attributeName);
}
}
Aggregations