use of com.intellij.xml.XmlElementDescriptor in project intellij-plugins by JetBrains.
the class MxmlWriter method processTagChildren.
boolean processTagChildren(final XmlTag tag, @NotNull final Context context, @Nullable final Context parentContext, final boolean propertiesExpected, @Nullable PropertyKind propertyKind) {
int lengthPosition = propertyKind != null && propertyKind.isList() ? out.allocateShort() : 0;
int explicitContentOccurred = -1;
int validAndStaticChildrenCount = 0;
final XmlTagChild[] children = tag.getValue().getChildren();
// if we process property tag value - if we cannot set value due to invalid content, so, we don't write property,
// otherwise if there is no content, we write explicit null
boolean invalidValue = false;
for (XmlTagChild child : children) {
if (child instanceof XmlTag) {
XmlTag childTag = (XmlTag) child;
XmlElementDescriptor descriptor = childTag.getDescriptor();
if (descriptor == null) {
LOG.warn("Descriptor is null, skip " + child);
invalidValue = true;
continue;
}
assert descriptor != null;
if (descriptor instanceof ClassBackedElementDescriptor) {
final ClassBackedElementDescriptor classBackedDescriptor = (ClassBackedElementDescriptor) descriptor;
if (classBackedDescriptor.isPredefined()) {
if (MxmlUtil.isObjectLanguageTag(tag)) {
// IDEA-73482
processPropertyTag(childTag, new AnyXmlAttributeDescriptorWrapper(descriptor), context);
} else if (descriptor.getQualifiedName().equals(FlexPredefinedTagNames.DECLARATIONS)) {
injectedASWriter.readDeclarations(this, childTag);
}
continue;
} else if (MxmlUtil.isAbstract(classBackedDescriptor)) {
addProblem(child, "abstract.class", classBackedDescriptor.getQualifiedName());
continue;
}
if (explicitContentOccurred == 1) {
LOG.warn("Default content already processed, skip " + child);
continue;
}
if (propertiesExpected && explicitContentOccurred == -1) {
explicitContentOccurred = 0;
final PropertyKind defaultPropertyKind = processDefaultProperty(tag, valueProviderFactory.create(childTag), classBackedDescriptor, children.length, context);
if (defaultPropertyKind == null) {
continue;
} else if (defaultPropertyKind.isList()) {
lengthPosition = out.allocateShort();
propertyKind = defaultPropertyKind;
} else if (defaultPropertyKind == PropertyKind.PRIMITIVE) {
validAndStaticChildrenCount++;
continue;
}
}
if (processClassBackedSubTag(childTag, classBackedDescriptor, context, propertyKind != null && propertyKind.isList())) {
validAndStaticChildrenCount++;
}
} else if (propertiesExpected && descriptor instanceof AnnotationBackedDescriptor) {
AnnotationBackedDescriptor annotationBackedDescriptor = (AnnotationBackedDescriptor) descriptor;
// skip invalid, contiguous child elements already processed and explicit content (i.e. AnnotationBackedDescriptor, property childTag) was occurred
if (explicitContentOccurred == 0) {
explicitContentOccurred = 1;
if (propertyKind != null && propertyKind.isList()) {
endList(validAndStaticChildrenCount, lengthPosition);
}
}
if (childTag.getNamespace().equals(MxmlJSClass.MXML_URI4) && childTag.getLocalName().equals(FlexStateElementNames.STATES)) {
if (childTag.getSubTags().length != 0) {
hasStates = true;
assert parentContext == null;
if (stateWriter == null) {
stateWriter = new StateWriter(writer);
}
stateWriter.readDeclaration(childTag);
}
} else {
processPropertyTag(childTag, annotationBackedDescriptor, context);
}
}
} else if (child instanceof XmlText && !MxmlUtil.containsOnlyWhitespace(child)) {
if (explicitContentOccurred == 1) {
LOG.warn("Default content already processed, skip '" + child.getText().trim() + "'");
continue;
}
if (context.getChildrenType() != null && !context.getChildrenType().equals(JSCommonTypeNames.STRING_CLASS_NAME)) {
LOG.warn("Illegal child type, skip '" + child.getText().trim() + "'");
continue;
}
if (propertiesExpected && explicitContentOccurred == -1) {
explicitContentOccurred = 0;
final XmlElementValueProvider valueProvider = valueProviderFactory.create((XmlText) child);
final PropertyKind defaultPropertyKind = processDefaultProperty(tag, valueProvider, null, children.length, context);
if (defaultPropertyKind == PropertyKind.IGNORE) {
explicitContentOccurred = -1;
continue;
} else if (defaultPropertyKind == null) {
continue;
} else if (defaultPropertyKind.isList()) {
lengthPosition = out.allocateShort();
propertyKind = defaultPropertyKind;
} else if (defaultPropertyKind == PropertyKind.PRIMITIVE) {
validAndStaticChildrenCount++;
continue;
} else {
final ValueWriter valueWriter;
try {
valueWriter = propertyProcessor.processXmlTextAsDefaultPropertyWithComplexType(valueProvider, tag, context);
} catch (InvalidPropertyException e) {
// we don't need any out rollback - nothing is written yet
problemsHolder.add(e);
continue;
}
if (valueWriter == null) {
throw new IllegalArgumentException("unexpected default property kind " + defaultPropertyKind);
} else if (valueWriter == InjectedASWriter.IGNORE) {
continue;
}
}
} else if (propertyKind == PropertyKind.VECTOR) {
LOG.warn("skip " + child + " due to IDEA-73478");
// IDEA-73478, XmlText allowed only for fx:Array, but not for fx:Vector (even with type String)
break;
}
if (propertyKind != null && propertyKind == PropertyKind.COMPLEX) {
invalidValue = true;
LOG.warn("Text is not expected" + child);
} else {
writer.string(((XmlText) child).getValue());
validAndStaticChildrenCount++;
}
}
}
if (propertyKind != null && propertyKind.isList()) {
endList(validAndStaticChildrenCount, lengthPosition);
} else if (!propertiesExpected && validAndStaticChildrenCount == 0) {
if (invalidValue) {
return false;
}
// PropertyAsTagWithCommentedValueAsTag, replace Amf3Types.OBJECT to Amf3Types.NULL
out.putByte(Amf3Types.NULL, out.size() - 1);
}
return true;
}
use of com.intellij.xml.XmlElementDescriptor in project intellij-plugins by JetBrains.
the class PropertyProcessor method write.
@SuppressWarnings("StatementWithEmptyBody")
@Override
public PropertyKind write(AnnotationBackedDescriptor descriptor, XmlElementValueProvider valueProvider, PrimitiveAmfOutputStream out, BaseWriter writer, boolean isStyle, @Nullable Context parentContext) throws InvalidPropertyException {
final String type = descriptor.getType();
if (isStyle) {
int flags = 0;
if (isEffect()) {
flags |= StyleFlags.EFFECT;
out.write(flags);
out.write(Amf3Types.OBJECT);
return COMPLEX_STYLE;
} else {
out.write(flags);
}
} else if (isEffect()) {
out.write(Amf3Types.OBJECT);
return COMPLEX;
}
if (writeIfPrimitive(valueProvider, type, out, descriptor, isStyle, false)) {
} else if (type.equals(JSCommonTypeNames.ARRAY_CLASS_NAME)) {
if (!descriptor.isRichTextContent() && valueProvider instanceof XmlAttributeValueProvider && isInlineArray(valueProvider.getTrimmed())) {
writeInlineArray(valueProvider);
} else {
out.write(Amf3Types.ARRAY);
return ARRAY;
}
} else if (descriptor.getArrayType() != null) {
if (valueProvider.getElement() instanceof XmlTag) {
final XmlTag propertyTag = (XmlTag) valueProvider.getElement();
final XmlTag[] subTags = propertyTag.getSubTags();
if (subTags.length == 1) {
final XmlTag contentTag = subTags[0];
final XmlElementDescriptor contentTagDescriptor = contentTag.getDescriptor();
if (contentTagDescriptor instanceof ClassBackedElementDescriptor && CodeContext.AS3_VEC_VECTOR_QUALIFIED_NAME.equals(contentTagDescriptor.getQualifiedName())) {
if (!mxmlWriter.processMxmlVector(contentTag, parentContext, false)) {
throw new InvalidPropertyException(contentTag, "invalid.vector.value");
}
return isStyle ? PRIMITIVE_STYLE : PRIMITIVE;
}
}
}
writer.vectorHeader(descriptor.getArrayType());
return VECTOR;
} else if (type.equals(JSCommonTypeNames.OBJECT_CLASS_NAME) || type.equals(JSCommonTypeNames.ANY_TYPE)) {
final PropertyKind propertyKind = writeUntypedPropertyValue(out, valueProvider, descriptor, isStyle, parentContext);
if (propertyKind != null) {
return propertyKind;
}
} else if (type.equals(FlexCommonTypeNames.IFACTORY)) {
writeClassFactory(valueProvider);
} else {
out.write(Amf3Types.OBJECT);
return isStyle ? COMPLEX_STYLE : COMPLEX;
}
return isStyle ? PRIMITIVE_STYLE : PRIMITIVE;
}
use of com.intellij.xml.XmlElementDescriptor in project intellij-community by JetBrains.
the class JavaFxNamespaceDescriptor method getElementDescriptor.
@Nullable
@Override
public XmlElementDescriptor getElementDescriptor(@NotNull XmlTag tag) {
final XmlTag parentTag = tag.getParentTag();
if (parentTag != null) {
final XmlElementDescriptor descriptor = parentTag.getDescriptor();
return descriptor != null ? descriptor.getElementDescriptor(tag, parentTag) : null;
}
final String name = tag.getName();
if (FxmlConstants.FX_ROOT.equals(name)) {
return new JavaFxRootTagDescriptor(tag);
}
return new JavaFxClassTagDescriptor(name, tag);
}
use of com.intellij.xml.XmlElementDescriptor in project intellij-community by JetBrains.
the class JavaFxNamespaceDescriptor method getRootElementsDescriptors.
@NotNull
@Override
public XmlElementDescriptor[] getRootElementsDescriptors(@Nullable XmlDocument document) {
if (document != null) {
final Project project = document.getProject();
final PsiClass paneClass = JavaPsiFacade.getInstance(project).findClass(JavaFxCommonNames.JAVAFX_SCENE_LAYOUT_PANE, GlobalSearchScope.allScope(project));
if (paneClass != null) {
final ArrayList<XmlElementDescriptor> result = new ArrayList<>();
ClassInheritorsSearch.search(paneClass, paneClass.getUseScope(), true, true, false).forEach(psiClass -> {
result.add(new JavaFxClassTagDescriptor(psiClass.getName(), psiClass));
return true;
});
return result.toArray(new XmlElementDescriptor[result.size()]);
}
}
return XmlElementDescriptor.EMPTY_ARRAY;
}
use of com.intellij.xml.XmlElementDescriptor in project intellij-community by JetBrains.
the class XsltContextProviderBase method fillFromSchema.
private static void fillFromSchema(PsiFile file, ElementNames names) {
if (!(file instanceof XmlFile))
return;
final XmlFile f = (XmlFile) file;
final XmlDocument d = f.getDocument();
if (d == null)
return;
final XmlTag rootTag = d.getRootTag();
if (rootTag == null)
return;
//noinspection unchecked
names.dependencies.add(new NSDeclTracker(rootTag));
try {
final Map<String, String> namespaceDeclarations = rootTag.getLocalNamespaceDeclarations();
final Collection<String> prefixes = namespaceDeclarations.keySet();
final XmlElementFactory ef = XmlElementFactory.getInstance(file.getProject());
int noSchemaNamespaces = 0;
for (String prefix : prefixes) {
final String namespace = namespaceDeclarations.get(prefix);
if (isIgnoredNamespace(prefix, namespace))
continue;
final XmlTag tag = ef.createTagFromText("<dummy-tag xmlns='" + namespace + "' />", XMLLanguage.INSTANCE);
final XmlDocument document = PsiTreeUtil.getParentOfType(tag, XmlDocument.class);
final XmlNSDescriptor rootDescriptor = tag.getNSDescriptor(tag.getNamespace(), true);
if (rootDescriptor == null || (rootDescriptor instanceof XmlNSDescriptorImpl && ((XmlNSDescriptorImpl) rootDescriptor).getTag() == null) || !rootDescriptor.getDeclaration().isPhysical()) {
final QName any = QNameUtil.createAnyLocalName(namespace);
names.elementNames.add(any);
names.attributeNames.add(any);
noSchemaNamespaces++;
continue;
}
//noinspection unchecked
names.dependencies.add(rootDescriptor.getDescriptorFile());
//noinspection unchecked
final Set<XmlElementDescriptor> history = new THashSet<>(150);
final XmlElementDescriptor[] e = rootDescriptor.getRootElementsDescriptors(document);
try {
for (XmlElementDescriptor descriptor : e) {
processElementDescriptors(descriptor, tag, names, history, 0);
}
} catch (StopProcessingException e1) {
Logger.getInstance(XsltContextProviderBase.class).error("Maximum recursion depth reached. Missing equals()/hashCode() implementation?", StringUtil.join(history, descriptor -> descriptor.getClass().getName() + "[" + descriptor.getQualifiedName() + "]", ", "));
}
}
names.validateNames = names.elementNames.size() > noSchemaNamespaces;
// final QName any = QNameUtil.createAnyLocalName("");
// names.elementNames.add(any);
// names.attributeNames.add(any);
} catch (IncorrectOperationException e) {
Logger.getInstance(XsltContextProvider.class.getName()).error(e);
}
}
Aggregations