use of com.intellij.xml.XmlExtension in project intellij-community by JetBrains.
the class RelaxedHtmlFromSchemaElementDescriptor method getRelaxedDescriptor.
public static XmlElementDescriptor getRelaxedDescriptor(XmlElementDescriptor base, final XmlTag childTag) {
final String namespace = childTag.getNamespace();
final XmlExtension extension = XmlExtension.getExtensionByElement(childTag);
if (!XmlUtil.XHTML_URI.equals(namespace) && (base.getContentType() != XmlElementDescriptor.CONTENT_TYPE_EMPTY || // allow custom tag
(extension != null && extension.isCustomTagAllowed(childTag)))) {
return new AnyXmlElementDescriptor(base, childTag.getNSDescriptor(namespace, true));
}
return null;
}
use of com.intellij.xml.XmlExtension in project intellij-community by JetBrains.
the class DefaultXmlTagNameProvider method addTagNameVariants.
@Override
public void addTagNameVariants(List<LookupElement> elements, @NotNull XmlTag tag, String prefix) {
final List<String> namespaces;
if (prefix.isEmpty()) {
namespaces = new ArrayList<>(Arrays.asList(tag.knownNamespaces()));
// empty namespace
namespaces.add(XmlUtil.EMPTY_URI);
} else {
namespaces = new ArrayList<>(Collections.singletonList(tag.getNamespace()));
}
PsiFile psiFile = tag.getContainingFile();
XmlExtension xmlExtension = XmlExtension.getExtension(psiFile);
List<String> nsInfo = new ArrayList<>();
List<XmlElementDescriptor> variants = TagNameVariantCollector.getTagDescriptors(tag, namespaces, nsInfo);
if (variants.isEmpty() && psiFile instanceof XmlFile && ((XmlFile) psiFile).getRootTag() == tag) {
getRootTagsVariants(tag, elements);
return;
}
final Set<String> visited = new HashSet<>();
for (int i = 0; i < variants.size(); i++) {
XmlElementDescriptor descriptor = variants.get(i);
String qname = descriptor.getName(tag);
if (!visited.add(qname))
continue;
if (!prefix.isEmpty() && qname.startsWith(prefix + ":")) {
qname = qname.substring(prefix.length() + 1);
}
PsiElement declaration = descriptor.getDeclaration();
if (declaration != null && !declaration.isValid()) {
LOG.error(descriptor + " contains invalid declaration: " + declaration);
}
LookupElementBuilder lookupElement = declaration == null ? LookupElementBuilder.create(qname) : LookupElementBuilder.create(declaration, qname);
final int separator = qname.indexOf(':');
if (separator > 0) {
lookupElement = lookupElement.withLookupString(qname.substring(separator + 1));
}
String ns = nsInfo.get(i);
if (StringUtil.isNotEmpty(ns)) {
lookupElement = lookupElement.withTypeText(ns, true);
}
if (descriptor instanceof PsiPresentableMetaData) {
lookupElement = lookupElement.withIcon(((PsiPresentableMetaData) descriptor).getIcon());
}
if (xmlExtension.useXmlTagInsertHandler()) {
lookupElement = lookupElement.withInsertHandler(XmlTagInsertHandler.INSTANCE);
}
lookupElement = lookupElement.withCaseSensitivity(!(descriptor instanceof HtmlElementDescriptorImpl));
elements.add(PrioritizedLookupElement.withPriority(lookupElement, separator > 0 ? 0 : 1));
}
}
use of com.intellij.xml.XmlExtension in project intellij-community by JetBrains.
the class XmlTagImpl method computeNamespaceMap.
@Nullable
private BidirectionalMap<String, String> computeNamespaceMap(PsiElement parent) {
BidirectionalMap<String, String> map = null;
boolean hasNamespaceDeclarations = hasNamespaceDeclarations();
if (hasNamespaceDeclarations) {
map = new BidirectionalMap<>();
final XmlAttribute[] attributes = getAttributes();
for (final XmlAttribute attribute : attributes) {
if (attribute.isNamespaceDeclaration()) {
final String name = attribute.getName();
int splitIndex = name.indexOf(':');
final String value = getRealNs(attribute.getValue());
if (value != null) {
if (splitIndex < 0) {
map.put("", value);
} else {
map.put(XmlUtil.findLocalNameByQualifiedName(name), value);
}
}
}
}
}
if (parent instanceof XmlDocument) {
final XmlExtension extension = XmlExtension.getExtensionByElement(parent);
if (extension != null) {
final String[][] namespacesFromDocument = extension.getNamespacesFromDocument((XmlDocument) parent, hasNamespaceDeclarations);
if (namespacesFromDocument != null) {
if (map == null) {
map = new BidirectionalMap<>();
}
for (final String[] prefix2ns : namespacesFromDocument) {
map.put(prefix2ns[0], getRealNs(prefix2ns[1]));
}
}
}
}
return map;
}
use of com.intellij.xml.XmlExtension in project intellij-community by JetBrains.
the class XmlAttributeReferenceCompletionProvider method addVariants.
private static void addVariants(final CompletionResultSet result, final XmlAttribute[] attributes, final XmlAttributeDescriptor[] descriptors, XmlAttribute attribute, @Nullable InsertHandler<LookupElement> replacementInsertHandler) {
final XmlTag tag = attribute.getParent();
final PsiFile file = tag.getContainingFile();
final XmlExtension extension = XmlExtension.getExtension(file);
final String prefix = attribute.getName().contains(":") && ((XmlAttributeImpl) attribute).getRealLocalName().length() > 0 ? attribute.getNamespacePrefix() + ":" : null;
for (XmlAttributeDescriptor descriptor : descriptors) {
if (isValidVariant(attribute, descriptor, attributes, extension)) {
String name = descriptor.getName(tag);
InsertHandler<LookupElement> insertHandler = XmlAttributeInsertHandler.INSTANCE;
if (tag instanceof HtmlTag && HtmlUtil.isShortNotationOfBooleanAttributePreferred() && HtmlUtil.isBooleanAttribute(descriptor, tag)) {
insertHandler = null;
}
if (replacementInsertHandler != null) {
insertHandler = replacementInsertHandler;
} else if (descriptor instanceof NamespaceAwareXmlAttributeDescriptor) {
final String namespace = ((NamespaceAwareXmlAttributeDescriptor) descriptor).getNamespace(tag);
if (file instanceof XmlFile && namespace != null && namespace.length() > 0 && !name.contains(":") && tag.getPrefixByNamespace(namespace) == null) {
insertHandler = new XmlAttributeInsertHandler(namespace);
}
}
if (prefix == null || name.startsWith(prefix)) {
if (prefix != null && name.length() > prefix.length()) {
name = descriptor.getName(tag).substring(prefix.length());
}
LookupElementBuilder element = LookupElementBuilder.create(name);
if (descriptor instanceof PsiPresentableMetaData) {
element = element.withIcon(((PsiPresentableMetaData) descriptor).getIcon());
}
final int separator = name.indexOf(':');
if (separator > 0) {
element = element.withLookupString(name.substring(separator + 1));
}
element = element.withCaseSensitivity(!(descriptor instanceof HtmlAttributeDescriptorImpl)).withInsertHandler(insertHandler);
result.addElement(descriptor.isRequired() ? PrioritizedLookupElement.withPriority(element.appendTailText("(required)", true), 100) : HtmlUtil.isOwnHtmlAttribute(descriptor) ? PrioritizedLookupElement.withPriority(element, 50) : element);
}
}
}
}
use of com.intellij.xml.XmlExtension in project android by JetBrains.
the class AndroidLayoutXmlTagNameProvider method addTagNameVariants.
@Override
public void addTagNameVariants(List<LookupElement> elements, @NotNull XmlTag tag, String prefix) {
final PsiFile file = tag.getContainingFile();
if (!(file instanceof XmlFile && LayoutDomFileDescription.isLayoutFile((XmlFile) file))) {
// Only use this provider for Android layout files
return;
}
XmlExtension xmlExtension = XmlExtension.getExtension(file);
List<XmlElementDescriptor> variants = TagNameVariantCollector.getTagDescriptors(tag, NAMESPACES, null);
// Find the framework widgets that have a support library alternative
Set<String> supportAlternatives = Sets.newHashSet();
for (XmlElementDescriptor descriptor : variants) {
String qualifiedName = descriptor.getName(tag);
if (qualifiedName.startsWith(ANDROID_SUPPORT_PKG_PREFIX)) {
supportAlternatives.add(AndroidUtils.getUnqualifiedName(qualifiedName));
}
}
final Set<String> addedNames = Sets.newHashSet();
for (XmlElementDescriptor descriptor : variants) {
String qualifiedName = descriptor.getName(tag);
if (!addedNames.add(qualifiedName)) {
continue;
}
final String simpleName = AndroidUtils.getUnqualifiedName(qualifiedName);
// Creating LookupElementBuilder with PsiElement gives an ability to show documentation during completion time
PsiElement declaration = descriptor.getDeclaration();
LookupElementBuilder lookupElement = declaration == null ? LookupElementBuilder.create(qualifiedName) : LookupElementBuilder.create(declaration, qualifiedName);
final boolean isDeprecated = isDeclarationDeprecated(declaration);
if (isDeprecated) {
lookupElement = lookupElement.withStrikeoutness(true);
}
if (simpleName != null) {
lookupElement = lookupElement.withLookupString(simpleName);
}
// This statement preserves them in autocompletion.
if (descriptor instanceof PsiPresentableMetaData) {
lookupElement = lookupElement.withIcon(((PsiPresentableMetaData) descriptor).getIcon());
}
// Using insert handler is required for, e.g. automatic insertion of required fields in Android layout XMLs
if (xmlExtension.useXmlTagInsertHandler()) {
lookupElement = lookupElement.withInsertHandler(XmlTagInsertHandler.INSTANCE);
}
// Deprecated tag names are supposed to be shown below non-deprecated tags
int priority = isDeprecated ? 10 : 100;
if (simpleName == null) {
if (supportAlternatives.contains(qualifiedName)) {
// This component has a support library alternative so lower the priority so the support component is shown at the top.
priority -= 1;
} else {
// The component doesn't have an alternative in the support library so push it to the top.
priority += 10;
}
}
elements.add(PrioritizedLookupElement.withPriority(lookupElement, priority));
}
}
Aggregations