use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class MxmlReferenceContributor method createReferenceProviderForTagOrAttributeExpectingJSClass.
private static PsiReferenceProvider createReferenceProviderForTagOrAttributeExpectingJSClass(final Function<PsiReference, LocalQuickFix[]> quickFixProvider) {
return new PsiReferenceProvider() {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
final PsiMetaData descriptor;
final String name;
if (element instanceof XmlTag) {
descriptor = ((XmlTag) element).getDescriptor();
name = ((XmlTag) element).getLocalName();
} else if (element instanceof XmlAttributeValue) {
final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(element, XmlAttribute.class);
descriptor = xmlAttribute == null ? null : xmlAttribute.getDescriptor();
name = xmlAttribute == null ? "" : xmlAttribute.getName();
} else {
assert false : element;
return PsiReference.EMPTY_ARRAY;
}
if (!(descriptor instanceof AnnotationBackedDescriptor))
return PsiReference.EMPTY_ARRAY;
final String type = ((AnnotationBackedDescriptor) descriptor).getType();
if (!FlexReferenceContributor.isClassReferenceType(type))
return PsiReference.EMPTY_ARRAY;
final Pair<String, TextRange> trimmedValueAndRange = getTrimmedValueAndRange((XmlElement) element);
if (trimmedValueAndRange.second.getStartOffset() == 0)
return PsiReference.EMPTY_ARRAY;
if (trimmedValueAndRange.first.indexOf('{') != -1 || trimmedValueAndRange.first.indexOf('@') != -1)
return PsiReference.EMPTY_ARRAY;
final JSReferenceSet jsReferenceSet = new JSReferenceSet(element, trimmedValueAndRange.first, trimmedValueAndRange.second.getStartOffset(), false, true) {
@Override
protected JSTextReference createTextReference(String s, int offset, boolean methodRef) {
return new MyJSTextReference(this, s, offset, methodRef, quickFixProvider);
}
};
if (SKIN_CLASS_ATTR_NAME.equals(name)) {
jsReferenceSet.setBaseClassFqns(Collections.singletonList(UI_COMPONENT_FQN));
}
return jsReferenceSet.getReferences();
}
};
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class ActionScriptGenerateEventHandler method getEventType.
@Nullable
public static String getEventType(final XmlAttribute xmlAttribute) {
final XmlAttributeDescriptor descriptor = xmlAttribute == null ? null : xmlAttribute.getDescriptor();
final PsiElement declaration = descriptor instanceof AnnotationBackedDescriptor ? descriptor.getDeclaration() : null;
final PsiElement declarationParent = declaration == null ? null : declaration.getParent();
if (declaration instanceof JSAttributeNameValuePair && (((JSAttributeNameValuePair) declaration).getName() == null || "name".equals(((JSAttributeNameValuePair) declaration).getName())) && declarationParent instanceof JSAttribute && "Event".equals(((JSAttribute) declarationParent).getName())) {
return ((AnnotationBackedDescriptor) descriptor).getType();
}
return null;
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class PropertyProcessor method writeClassFactory.
private void writeClassFactory(XmlElementValueProvider valueProvider) throws InvalidPropertyException {
if (valueProvider instanceof XmlTagValueProvider) {
XmlTag tag = ((XmlTagValueProvider) valueProvider).getTag();
XmlTag[] subTags = tag.getSubTags();
if (subTags.length > 0) {
processFxComponent(subTags[0], true);
return;
}
}
String className = valueProvider.getTrimmed();
if (writeFxComponentReferenceIfProcessed(className) || writeReferenceIfReferenced(className)) {
return;
}
final JSClass jsClass = valueProvider.getJsClass();
if (jsClass == null) {
throw new InvalidPropertyException(valueProvider.getElement(), "unresolved.class", valueProvider.getTrimmed());
}
final Trinity<Integer, String, Condition<AnnotationBackedDescriptor>> effectiveClassInfo;
final PsiElement parent = jsClass.getNavigationElement().getParent();
if (parent instanceof XmlTag && MxmlUtil.isComponentLanguageTag((XmlTag) parent)) {
// if referenced by inner class name, but inner fx component is not yet processed
if (parent.getContainingFile().equals(valueProvider.getElement().getContainingFile())) {
processFxComponent((XmlTag) parent, false);
return;
} else {
effectiveClassInfo = new Trinity<>(-1, "mx.core.UIComponent", null);
}
} else {
effectiveClassInfo = MxmlUtil.computeEffectiveClass(valueProvider.getElement(), jsClass, mxmlWriter.projectComponentReferenceCounter, false);
}
if (effectiveClassInfo.first == -1) {
if (effectiveClassInfo.second != null) {
if (effectiveClassInfo.second.equals("mx.core.UIComponent")) {
PsiMetaData psiMetaData = valueProvider.getPsiMetaData();
if (psiMetaData != null && psiMetaData.getName().equals("itemRenderer") && MxmlUtil.isPropertyOfSparkDataGroup((AnnotationBackedDescriptor) psiMetaData)) {
className = MxmlUtil.UNKNOWN_ITEM_RENDERER_CLASS_NAME;
} else {
className = MxmlUtil.UNKNOWN_COMPONENT_CLASS_NAME;
}
} else {
className = effectiveClassInfo.second;
}
}
writeNonProjectUnreferencedClassFactory(className);
} else {
writer.documentFactoryReference(effectiveClassInfo.first);
}
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class MxmlWriter method processElements.
@SuppressWarnings("StatementWithEmptyBody")
private boolean processElements(final XmlTag tag, @Nullable final Context parentContext, final boolean allowIncludeInExcludeFrom, final int dataPosition, final int referencePosition, final boolean writeLocation, @Nullable final Condition<AnnotationBackedDescriptor> propertyFilter) {
boolean staticChild = true;
ByteRange dataRange = null;
// if state specific property before includeIn, state override data range wil be added before object data range, so,
// we keep current index and insert at the specified position
final Marker dataRangeAfterAnchor = writer.getBlockOut().getLastMarker();
if (writeLocation) {
out.writeUInt29(writer.P_FUD_RANGE_ID);
out.writeUInt29(rangeMarkers.size());
rangeMarkers.add(document.createRangeMarker(tag.getTextOffset(), tag.getTextOffset() + tag.getTextLength()));
}
assert !tagAttributeProcessContext.isCssRulesetDefined();
Context context = tagAttributeProcessContext;
if (parentContext != null && parentContext.getScope().staticObjectPointToScope) {
tagAttributeProcessContext.setTempParentScope(parentContext.getScope());
}
for (final XmlAttribute attribute : tag.getAttributes()) {
if (attribute.getValueElement() == null) {
// skip invalid - "<Button label/>"
continue;
}
final XmlAttributeDescriptor attributeDescriptor = attribute.getDescriptor();
final AnnotationBackedDescriptor descriptor;
if (attributeDescriptor instanceof AnnotationBackedDescriptor) {
descriptor = (AnnotationBackedDescriptor) attributeDescriptor;
// id and includeIn/excludeFrom only as attribute, not as tag
if (descriptor.isPredefined()) {
if (descriptor.hasIdType()) {
processObjectWithExplicitId(attribute.getValue(), context);
} else if (allowIncludeInExcludeFrom) {
String name = descriptor.getName();
boolean excludeFrom = false;
if (name.equals(FlexStateElementNames.INCLUDE_IN) || (excludeFrom = name.equals(FlexStateElementNames.EXCLUDE_FROM))) {
if (context == tagAttributeProcessContext) {
context = new DynamicObjectContext(tagAttributeProcessContext);
}
// must be before stateWriter.includeIn - start object data range before state data range
dataRange = writer.getBlockOut().startRange(dataPosition, dataRangeAfterAnchor);
((DynamicObjectContext) context).setDataRange(dataRange);
stateWriter.includeInOrExcludeFrom(attribute.getValueElement(), parentContext, (DynamicObjectContext) context, excludeFrom);
staticChild = false;
} else if (name.equals(FlexStateElementNames.ITEM_CREATION_POLICY)) {
if (attribute.getValue().charAt(0) == 'i') {
if (context == tagAttributeProcessContext) {
context = new DynamicObjectContext(tagAttributeProcessContext);
}
((DynamicObjectContext) context).setImmediateCreation(true);
}
} else if (name.equals(FlexStateElementNames.ITEM_DESTRUCTION_POLICY)) {
if (attribute.getValue().charAt(0) == 'a') {
stateWriter.applyItemAutoDestruction(context, parentContext);
}
}
}
} else if (propertyFilter != null && !propertyFilter.value(descriptor)) {
// skip
} else if (MxmlUtil.isIdLanguageAttribute(attribute, descriptor)) {
String explicitId = attribute.getValue();
writer.idMxmlProperty(explicitId);
processObjectWithExplicitId(explicitId, context);
} else if (descriptor.getTypeName() == null) {
//IDEA-73453
// skip
LOG.warn("Skip " + descriptor.getName() + " in " + tag.getText() + " due to IDEA-73453");
} else if (hasStates && stateWriter.checkStateSpecificPropertyValue(this, propertyProcessor, valueProviderFactory.create(attribute), descriptor, context)) {
// skip
} else {
writeAttributeBackedProperty(attribute, descriptor, context, context);
}
} else if (attributeDescriptor instanceof AnyXmlAttributeDescriptor) {
writeAttributeBackedProperty(attribute, new AnyXmlAttributeDescriptorWrapper(attributeDescriptor), context, context);
} else if (!attribute.isNamespaceDeclaration()) {
LOG.warn("unknown attribute (" + attribute.getText() + ") descriptor: " + (attributeDescriptor == null ? "null" : attributeDescriptor.toString()) + " of tag " + tag.getText());
}
}
if (!hasStates) {
assert context == tagAttributeProcessContext;
context = writer.createStaticContext(parentContext, referencePosition);
if (tagAttributeProcessContext.isCssRulesetDefined()) {
context.markCssRulesetDefined();
}
} else if (context == tagAttributeProcessContext) {
context = stateWriter.createContextForStaticBackSibling(allowIncludeInExcludeFrom, referencePosition, parentContext);
stateWriter.finalizeStateSpecificAttributesForStaticContext((StaticObjectContext) context, parentContext, this);
if (tagAttributeProcessContext.isCssRulesetDefined()) {
context.markCssRulesetDefined();
}
}
tagAttributeProcessContext.reset();
processTagChildren(tag, context, parentContext, true, null);
// width="150"><group>{cardtype} !!id (for binding target, RadioButton id="visa") allocation here!!</group></RadioButton>
if (dataPosition != -1) {
writer.endObject();
if (dataRange != null) {
writer.getBlockOut().endRange(dataRange);
}
}
return staticChild;
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class IncrementalDocumentSynchronizer method findSupportedTarget.
@Nullable
private XmlElementValueProvider findSupportedTarget() {
PsiElement element = event.getParent();
// if we change attribute value via line marker, so, event.getParent() will be XmlAttribute instead of XmlAttributeValue
while (!(element instanceof XmlAttribute)) {
element = element.getParent();
if (element instanceof XmlTag) {
XmlTag tag = (XmlTag) element;
XmlElementDescriptor descriptor = tag.getDescriptor();
if (descriptor instanceof ClassBackedElementDescriptor) {
ClassBackedElementDescriptor classBackedElementDescriptor = (ClassBackedElementDescriptor) descriptor;
if (classBackedElementDescriptor.isPredefined()) {
isStyleDataChanged = descriptor.getQualifiedName().equals(FlexPredefinedTagNames.STYLE);
isSkippedXml = isStyleDataChanged || (!MxmlUtil.isObjectLanguageTag(tag) && !descriptor.getQualifiedName().equals(FlexPredefinedTagNames.DECLARATIONS));
}
}
return null;
} else if (element instanceof PsiFile || element == null) {
return null;
}
}
XmlAttribute attribute = (XmlAttribute) element;
if (JavaScriptSupportLoader.MXML_URI3.equals(attribute.getNamespace()) || attribute.getValueElement() == null) {
return null;
}
XmlAttributeDescriptor xmlDescriptor = attribute.getDescriptor();
if (!(xmlDescriptor instanceof AnnotationBackedDescriptor)) {
return null;
}
AnnotationBackedDescriptor descriptor = (AnnotationBackedDescriptor) xmlDescriptor;
if (descriptor.isPredefined() || MxmlUtil.isIdLanguageAttribute(attribute, descriptor)) {
return null;
}
// todo incremental sync for state-specific attributes
PsiReference[] references = attribute.getReferences();
if (references.length > 1) {
for (int i = references.length - 1; i > -1; i--) {
PsiReference psiReference = references[i];
if (psiReference instanceof FlexReferenceContributor.StateReference) {
return null;
}
}
} else {
String prefix = attribute.getName() + '.';
for (XmlAttribute anotherAttribute : attribute.getParent().getAttributes()) {
if (anotherAttribute != attribute && anotherAttribute.getName().startsWith(prefix)) {
return null;
}
}
}
XmlAttributeValueProvider valueProvider = new XmlAttributeValueProvider(attribute);
// skip binding
PsiLanguageInjectionHost injectedHost = valueProvider.getInjectedHost();
if (injectedHost != null && InjectedLanguageUtil.hasInjections(injectedHost)) {
return null;
}
return valueProvider;
}
Aggregations