Search in sources :

Example 11 with AnnotationBackedDescriptor

use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.

the class MxmlTagNameReference method fixSubTagsPrefixes.

private static void fixSubTagsPrefixes(final XmlTag tag, final String oldPrefix, final String newPrefix) {
    final XmlElementDescriptor descriptor = tag.getDescriptor();
    if (!(descriptor instanceof ClassBackedElementDescriptor)) {
        return;
    }
    for (final XmlTag subTag : tag.getSubTags()) {
        if (Comparing.strEqual(subTag.getNamespacePrefix(), oldPrefix) && subTag.getDescriptor() == null) {
            final String oldSubTagName = subTag.getName();
            subTag.setName(StringUtil.isEmpty(newPrefix) ? subTag.getLocalName() : (newPrefix + ":" + subTag.getLocalName()));
            final XmlElementDescriptor subTagDescriptor = descriptor.getElementDescriptor(subTag, tag);
            if (!(subTagDescriptor instanceof AnnotationBackedDescriptor)) {
                subTag.setName(oldSubTagName);
            }
        }
    }
}
Also used : XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) AnnotationBackedDescriptor(com.intellij.lang.javascript.flex.AnnotationBackedDescriptor) XmlTag(com.intellij.psi.xml.XmlTag)

Example 12 with AnnotationBackedDescriptor

use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.

the class XmlTagValueProvider method getSubstituted.

@Override
public CharSequence getSubstituted() {
    CharSequence v = getDisplay(tag.getValue().getChildren());
    if (v == EMPTY) {
        return EMPTY;
    }
    XmlElementDescriptor descriptor = tag.getDescriptor();
    // may be ClassBackedElementDescriptor for fx:String: <TextArea><text><fx:String>sfsdsd</fx:String></text></TextArea>
    if (descriptor instanceof AnnotationBackedDescriptor && ((AnnotationBackedDescriptor) descriptor).isCollapseWhiteSpace()) {
        return CharMatcher.WHITESPACE.trimAndCollapseFrom(v, ' ');
    } else {
        return v;
    }
}
Also used : XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) AnnotationBackedDescriptor(com.intellij.lang.javascript.flex.AnnotationBackedDescriptor)

Example 13 with AnnotationBackedDescriptor

use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor 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;
}
Also used : ClassBackedElementDescriptor(com.intellij.javascript.flex.mxml.schema.ClassBackedElementDescriptor) AnnotationBackedDescriptor(com.intellij.lang.javascript.flex.AnnotationBackedDescriptor) PropertyKind(com.intellij.flex.uiDesigner.mxml.PropertyProcessor.PropertyKind) InvalidPropertyException(com.intellij.flex.uiDesigner.InvalidPropertyException) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor)

Example 14 with AnnotationBackedDescriptor

use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.

the class MxmlWriter method processDefaultProperty.

// descriptor will be null if child is XmlText
@Nullable
private PropertyKind processDefaultProperty(XmlTag parentTag, XmlElementValueProvider valueProvider, @Nullable ClassBackedElementDescriptor descriptor, int childrenLength, @NotNull Context context) {
    final ClassBackedElementDescriptor parentDescriptor = (ClassBackedElementDescriptor) parentTag.getDescriptor();
    assert parentDescriptor != null;
    final AnnotationBackedDescriptor defaultDescriptor = parentDescriptor.getDefaultPropertyDescriptor();
    final boolean isXmlText = descriptor == null;
    if (defaultDescriptor == null) {
        final String className = parentDescriptor.getQualifiedName();
        final JSClass jsClass;
        if (parentDescriptor instanceof MxmlBackedElementDescriptor) {
            jsClass = (JSClass) ActionScriptClassResolver.findClassByQNameStatic(className, parentTag);
        } else {
            jsClass = (JSClass) parentDescriptor.getDeclaration();
        }
        final boolean isDirectContainerImpl = className.equals(FlexCommonTypeNames.ICONTAINER);
        if (isDirectContainerImpl || ActionScriptClassResolver.isParentClass(jsClass, FlexCommonTypeNames.ICONTAINER)) {
            if (isXmlText) {
                addProblem(parentTag, "initializer.cannot.be.represented.in.text", parentTag.getLocalName());
                return null;
            }
            if (!isDirectContainerImpl && isHaloNavigator(className, jsClass) && !ActionScriptClassResolver.isParentClass((JSClass) descriptor.getDeclaration(), FlexCommonTypeNames.INAVIGATOR_CONTENT)) {
                addProblem(parentTag, "children.must.be", parentTag.getLocalName(), FlexCommonTypeNames.INAVIGATOR_CONTENT);
                return null;
            }
            writer.classOrPropertyName("0");
            out.write(AmfExtendedTypes.MX_CONTAINER_CHILDREN);
            return PropertyKind.ARRAY;
        } else {
            // http://youtrack.jetbrains.net/issue/IDEA-66565
            addProblem(parentTag, "default.property.not.found", parentTag.getLocalName());
        }
    } else {
        // xmlText as default property with injection, see BindingToDeferredInstanceFromBytesBase
        if (isXmlText && writeXmlTextAsDefaultPropertyInjectedValue(parentTag, valueProvider, defaultDescriptor, context)) {
            return null;
        }
        if (defaultDescriptor.getType().equals(JSCommonTypeNames.ARRAY_CLASS_NAME) && defaultDescriptor.getArrayType() != null) {
            final String elementType = defaultDescriptor.getArrayType();
            context.setChildrenType(elementType);
            final boolean isString = elementType.equals(JSCommonTypeNames.STRING_CLASS_NAME);
            if (isString) {
                if (descriptor != null && !descriptor.getQualifiedName().equals(JSCommonTypeNames.STRING_CLASS_NAME)) {
                    addProblem(parentTag, "children.must.be", parentTag.getLocalName(), elementType);
                    return null;
                }
            } else {
                if (isXmlText) {
                    addProblem(parentTag, "initializer.cannot.be.represented.in.text", parentTag.getLocalName());
                    return PropertyKind.IGNORE;
                }
            }
        }
        writer.classOrPropertyName(defaultDescriptor.getName());
        if (defaultDescriptor.isDeferredInstance()) {
            writer.newInstance("com.intellij.flex.uiDesigner.flex.DeferredInstanceFromArray", 1, false).typeMarker(Amf3Types.ARRAY);
            return PropertyKind.ARRAY;
        } else {
            final String type = defaultDescriptor.getType();
            if (type.equals(JSCommonTypeNames.STRING_CLASS_NAME) || (isXmlText && childrenLength == 1 && (type.equals(JSCommonTypeNames.OBJECT_CLASS_NAME) || type.equals(JSCommonTypeNames.ANY_TYPE)))) {
                writeSubstitutedString(valueProvider.getSubstituted());
            } else if (defaultDescriptor.contentIsArrayable()) {
                out.write(type.equals(JSCommonTypeNames.ARRAY_CLASS_NAME) ? Amf3Types.ARRAY : AmfExtendedTypes.ARRAY_IF_LENGTH_GREATER_THAN_1);
                return PropertyKind.ARRAY;
            } else if (defaultDescriptor.getArrayType() != null) /* Vector */
            {
                if (isXmlText) {
                    LOG.warn("skip " + valueProvider.getElement() + " due to IDEA-73478");
                    return null;
                }
                writer.vectorHeader(defaultDescriptor.getArrayType());
                return PropertyKind.VECTOR;
            } else if (type.equals(JSCommonTypeNames.NUMBER_CLASS_NAME)) {
                out.writeAmfDouble(valueProvider.getTrimmed());
            } else if (type.equals(JSCommonTypeNames.BOOLEAN_CLASS_NAME)) {
                out.writeAmfBoolean(valueProvider.getTrimmed());
            } else {
                out.write(Amf3Types.OBJECT);
                return PropertyKind.COMPLEX;
            }
        }
    }
    return PropertyKind.PRIMITIVE;
}
Also used : ClassBackedElementDescriptor(com.intellij.javascript.flex.mxml.schema.ClassBackedElementDescriptor) MxmlBackedElementDescriptor(com.intellij.javascript.flex.mxml.schema.MxmlBackedElementDescriptor) AnnotationBackedDescriptor(com.intellij.lang.javascript.flex.AnnotationBackedDescriptor) MxmlJSClass(com.intellij.javascript.flex.mxml.MxmlJSClass) JSClass(com.intellij.lang.javascript.psi.ecmal4.JSClass) Nullable(org.jetbrains.annotations.Nullable)

Example 15 with AnnotationBackedDescriptor

use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.

the class PropertyProcessor method processXmlTextAsDefaultPropertyWithComplexType.

public ValueWriter processXmlTextAsDefaultPropertyWithComplexType(XmlElementValueProvider valueProvider, XmlTag parent, Context context) throws InvalidPropertyException {
    ClassBackedElementDescriptor classBackedElementDescriptor = (ClassBackedElementDescriptor) parent.getDescriptor();
    LOG.assertTrue(classBackedElementDescriptor != null);
    AnnotationBackedDescriptor defaultPropertyDescriptor = classBackedElementDescriptor.getDefaultPropertyDescriptor();
    LOG.assertTrue(defaultPropertyDescriptor != null);
    return processInjected(valueProvider, defaultPropertyDescriptor, defaultPropertyDescriptor.isStyle(), context);
}
Also used : ClassBackedElementDescriptor(com.intellij.javascript.flex.mxml.schema.ClassBackedElementDescriptor) AnnotationBackedDescriptor(com.intellij.lang.javascript.flex.AnnotationBackedDescriptor)

Aggregations

AnnotationBackedDescriptor (com.intellij.lang.javascript.flex.AnnotationBackedDescriptor)21 XmlAttributeDescriptor (com.intellij.xml.XmlAttributeDescriptor)7 PsiElement (com.intellij.psi.PsiElement)6 XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)6 Nullable (org.jetbrains.annotations.Nullable)6 MxmlJSClass (com.intellij.javascript.flex.mxml.MxmlJSClass)5 ClassBackedElementDescriptor (com.intellij.javascript.flex.mxml.schema.ClassBackedElementDescriptor)5 TextRange (com.intellij.openapi.util.TextRange)4 XmlBackedJSClassImpl (com.intellij.lang.javascript.flex.XmlBackedJSClassImpl)3 JSClass (com.intellij.lang.javascript.psi.ecmal4.JSClass)3 PsiMetaData (com.intellij.psi.meta.PsiMetaData)3 XmlTag (com.intellij.psi.xml.XmlTag)3 AnyXmlAttributeDescriptor (com.intellij.xml.impl.schema.AnyXmlAttributeDescriptor)3 InvalidPropertyException (com.intellij.flex.uiDesigner.InvalidPropertyException)2 XmlAttributeValueProvider (com.intellij.flex.uiDesigner.mxml.XmlAttributeValueProvider)2 JavaScriptSupportLoader (com.intellij.lang.javascript.JavaScriptSupportLoader)2 JSCommonTypeNames (com.intellij.lang.javascript.psi.JSCommonTypeNames)2 JSAttribute (com.intellij.lang.javascript.psi.ecmal4.JSAttribute)2 JSAttributeNameValuePair (com.intellij.lang.javascript.psi.ecmal4.JSAttributeNameValuePair)2 JSReferenceSet (com.intellij.lang.javascript.psi.impl.JSReferenceSet)2