use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class IncrementalDocumentSynchronizer method incrementalSync.
private boolean incrementalSync(final DocumentInfo info) {
final XmlElementValueProvider valueProvider = findSupportedTarget();
if (valueProvider == null) {
return false;
}
XmlTag tag = (XmlTag) valueProvider.getElement().getParent();
if (!(tag.getDescriptor() instanceof ClassBackedElementDescriptor)) {
return false;
}
int componentId = info.rangeMarkerIndexOf(tag);
if (componentId == -1) {
return false;
}
final AnnotationBackedDescriptor descriptor = (AnnotationBackedDescriptor) valueProvider.getPsiMetaData();
assert descriptor != null;
final String typeName = descriptor.getTypeName();
final String type = descriptor.getType();
if (type == null) {
return !typeName.equals(FlexAnnotationNames.EFFECT);
} else if (type.equals(JSCommonTypeNames.FUNCTION_CLASS_NAME) || typeName.equals(FlexAnnotationNames.EVENT)) {
return true;
}
final StringRegistry.StringWriter stringWriter = new StringRegistry.StringWriter();
//noinspection IOResourceOpenedButNotSafelyClosed
final PrimitiveAmfOutputStream dataOut = new PrimitiveAmfOutputStream(new ByteArrayOutputStreamEx(16));
PrimitiveWriter writer = new PrimitiveWriter(dataOut, stringWriter);
boolean needRollbackStringWriter = true;
try {
if (descriptor.isAllowsPercentage()) {
String value = valueProvider.getTrimmed();
final boolean hasPercent;
if (value.isEmpty() || ((hasPercent = value.endsWith("%")) && value.length() == 1)) {
return true;
}
final String name;
if (hasPercent) {
name = descriptor.getPercentProxy();
value = value.substring(0, value.length() - 1);
} else {
name = descriptor.getName();
}
stringWriter.write(name, dataOut);
dataOut.writeAmfDouble(value);
} else {
stringWriter.write(descriptor.getName(), dataOut);
if (!writer.writeIfApplicable(valueProvider, dataOut, descriptor)) {
needRollbackStringWriter = false;
stringWriter.rollback();
return false;
}
}
needRollbackStringWriter = false;
} catch (InvalidPropertyException ignored) {
return true;
} catch (NumberFormatException ignored) {
return true;
} finally {
if (needRollbackStringWriter) {
stringWriter.rollback();
}
}
Client.getInstance().updatePropertyOrStyle(info.getId(), componentId, stream -> {
stringWriter.writeTo(stream);
stream.write(descriptor.isStyle());
dataOut.writeTo(stream);
}).doWhenDone(() -> DesignerApplicationManager.createDocumentRenderedNotificationDoneHandler(true).consume(info));
return true;
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class ResolveExternalInlineStyleSourceAction method findTargetIfStyleDeclarationOwner.
private Navigatable findTargetIfStyleDeclarationOwner(XmlTag parent) {
int foundCount = 0;
Navigatable target = null;
for (XmlAttribute attribute : parent.getAttributes()) {
XmlAttributeDescriptor descriptor = attribute.getDescriptor();
// 8
if (descriptor instanceof AnnotationBackedDescriptor) {
String ourValue = properties.get(descriptor.getName());
if (ourValue != null) {
if (attribute.getDisplayValue().equals(ourValue)) {
foundCount++;
if (descriptor.getName().equals(targetStyleName)) {
target = (Navigatable) attribute;
}
if (foundCount == properties.size()) {
return target;
}
}
}
}
}
for (XmlTag tag : parent.getSubTags()) {
XmlElementDescriptor descriptor = tag.getDescriptor();
if (descriptor instanceof AnnotationBackedDescriptor && ((PsiPresentableMetaData) descriptor).getTypeName().equals(FlexAnnotationNames.STYLE)) {
String ourValue = properties.get(descriptor.getName());
if (ourValue != null) {
if (tag.getSubTags().length == 0 && tag.getValue().getTrimmedText().equals(ourValue)) {
foundCount++;
if (descriptor.getName().equals(targetStyleName)) {
target = (Navigatable) tag;
}
if (foundCount == properties.size()) {
return target;
}
}
}
}
}
return null;
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class FlashUmlDependencyProvider method computeUsedClasses.
public Collection<Pair<JSClass, FlashUmlRelationship>> computeUsedClasses() {
final Collection<Pair<JSClass, FlashUmlRelationship>> result = new ArrayList<>();
final JSElementVisitor visitor = new JSElementVisitor() {
JSVariable myVariable;
JSNewExpression myNewExpression;
boolean myInField;
boolean myInParameter;
@Override
public void visitJSReferenceExpression(final JSReferenceExpression node) {
if (PsiTreeUtil.getParentOfType(node, JSImportStatement.class) != null) {
return;
}
if (myVariable == null && myNewExpression == null && !myInParameter && isReturnTypeReference(node)) {
return;
}
PsiElement resolved = node.resolve();
if (myNewExpression != null && resolved instanceof JSFunction) {
if (((JSFunction) resolved).isConstructor()) {
resolved = JSResolveUtil.findParent(resolved);
}
}
if (resolved instanceof JSClass) {
FlashUmlRelationship relType;
if (node.getParent() instanceof JSReferenceExpression) {
relType = Factory.dependency(myInField ? myVariable.getName() : null, myVariable != null ? myVariable : node);
} else if (myNewExpression != null) {
if (node.getParent() instanceof JSGenericSignature) {
relType = Factory.dependency(myInField ? myVariable.getName() : null, myVariable != null ? myVariable : node);
} else {
relType = Factory.create(myNewExpression);
}
} else if (myInField && node.getParent() instanceof JSGenericSignature) {
assert myVariable != null;
String qName = ((JSClass) resolved).getQualifiedName();
if (FlashUmlVfsResolver.isVectorType(qName)) {
relType = Factory.dependency(myVariable.getName(), myVariable);
} else {
relType = Factory.oneToMany(myVariable.getName(), myVariable);
}
} else if (myInField) {
assert myVariable != null;
String qName = ((JSClass) resolved).getQualifiedName();
if (FlashUmlVfsResolver.isVectorType(qName)) {
relType = Factory.dependency(myVariable.getName(), myVariable);
} else {
relType = Factory.oneToOne(myVariable.getName(), myVariable);
}
} else {
relType = Factory.dependency(null, myVariable != null ? myVariable : node);
}
result.add(Pair.create((JSClass) resolved, relType));
}
super.visitJSReferenceExpression(node);
}
@Override
public void visitJSVariable(final JSVariable node) {
if (node instanceof JSParameter) {
myInParameter = true;
} else {
myVariable = node;
}
myInField = JSResolveUtil.findParent(node) instanceof JSClass;
try {
super.visitJSVariable(node);
} finally {
myVariable = null;
myInField = false;
myInParameter = false;
}
}
@Override
public void visitJSNewExpression(final JSNewExpression node) {
myNewExpression = node;
try {
super.visitJSNewExpression(node);
} finally {
myNewExpression = null;
}
}
@Override
public void visitElement(final PsiElement element) {
super.visitElement(element);
element.acceptChildren(this);
}
};
if (myClazz instanceof XmlBackedJSClassImpl) {
// TODO process attributes
((XmlBackedJSClassImpl) myClazz).processInjectedFiles(jsFile -> {
jsFile.accept(visitor);
return true;
});
myClazz.getParent().acceptChildren(new // don't visit parent tag
XmlElementVisitor() {
// also to prevent extra references resolve
private String myInClassAttributeName;
@Override
public void visitXmlTag(final XmlTag tag) {
XmlElementDescriptor descriptor = tag.getDescriptor();
if (descriptor != null) {
PsiElement declaration = descriptor.getDeclaration();
if (declaration instanceof XmlFile && JavaScriptSupportLoader.isFlexMxmFile((PsiFile) declaration)) {
declaration = XmlBackedJSClassFactory.getXmlBackedClass((XmlFile) declaration);
}
if (declaration instanceof JSClass) {
XmlAttribute id = tag.getAttribute("id");
FlashUmlRelationship type = id != null && StringUtil.isNotEmpty(id.getValue()) ? Factory.oneToOne(id.getValue(), id) : Factory.dependency(null, tag);
result.add(Pair.create((JSClass) declaration, type));
}
}
super.visitXmlTag(tag);
}
@Override
public void visitXmlAttribute(final XmlAttribute attribute) {
XmlAttributeDescriptor descriptor = attribute.getDescriptor();
if (descriptor instanceof AnnotationBackedDescriptor) {
if (FlexReferenceContributor.isClassReferenceType(((AnnotationBackedDescriptor) descriptor).getType())) {
myInClassAttributeName = StringUtil.notNullize(attribute.getName());
try {
super.visitXmlAttribute(attribute);
} finally {
myInClassAttributeName = null;
}
}
}
}
@Override
public void visitXmlAttributeValue(final XmlAttributeValue value) {
if (myInClassAttributeName != null) {
processReferenceSet(value.getReferences(), result, Factory.dependency(myInClassAttributeName, value.getParent()));
}
}
@Override
public void visitXmlText(final XmlText text) {
List<Pair<PsiElement, TextRange>> injectedFiles = InjectedLanguageManager.getInstance(text.getProject()).getInjectedPsiFiles(text);
if (injectedFiles != null) {
for (Pair<PsiElement, TextRange> pair : injectedFiles) {
if (CSS.is(pair.first.getLanguage())) {
pair.first.accept(new CssElementVisitor() {
// to prevent extra references resolve
private boolean myInClassReference;
@Override
public void visitElement(final PsiElement element) {
super.visitElement(element);
element.acceptChildren(this);
}
@Override
public void visitCssFunction(final CssFunction _function) {
if (FlexReferenceContributor.CLASS_REFERENCE.equals(_function.getName())) {
myInClassReference = true;
try {
super.visitCssFunction(_function);
} finally {
myInClassReference = false;
}
}
}
@Override
public void visitCssString(final CssString _string) {
if (myInClassReference) {
CssDeclaration declaration = PsiTreeUtil.getParentOfType(_string, CssDeclaration.class);
if (declaration != null) {
processReferenceSet(_string.getReferences(), result, Factory.dependency(declaration.getPropertyName(), declaration));
}
}
}
});
}
}
}
super.visitXmlText(text);
}
@Override
public void visitElement(final PsiElement element) {
super.visitElement(element);
element.acceptChildren(this);
}
});
}
myClazz.processDeclarations(new BaseScopeProcessor() {
@Override
public boolean execute(@NotNull final PsiElement element, @NotNull final ResolveState state) {
element.accept(visitor);
return true;
}
}, ResolveState.initial(), myClazz, myClazz);
return result;
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class ClassBackedElementDescriptor method ensureDescriptorsMapsInitialized.
private void ensureDescriptorsMapsInitialized(PsiElement element, @Nullable Set<JSClass> visited) {
Map<String, AnnotationBackedDescriptor> map;
Map<String, Map<String, AnnotationBackedDescriptor>> packageToInternalDescriptors;
synchronized (CodeContext.class) {
map = myDescriptors;
packageToInternalDescriptors = myPackageToInternalDescriptors;
if (map != null && packageToInternalDescriptors != null)
return;
map = new THashMap<>();
packageToInternalDescriptors = new THashMap<>();
Set<PsiElement> processedElements = null;
if (element instanceof XmlBackedJSClassImpl) {
// TODO: make this code and following loop better
element = element.getParent().getContainingFile();
}
if (element instanceof XmlFile && MxmlJSClass.isFxgFile((PsiFile) element)) {
element = XmlBackedJSClassFactory.getXmlBackedClass((XmlFile) element);
}
while (element instanceof XmlFile) {
final XmlDocument document = ((XmlFile) element).getDocument();
final XmlTag rootTag = document != null ? document.getRootTag() : null;
final XmlElementDescriptor descriptor = rootTag != null ? rootTag.getDescriptor() : null;
if (processedElements == null)
processedElements = new THashSet<>();
processedElements.add(element);
element = descriptor != null ? descriptor.getDeclaration() : null;
if (processedElements.contains(element))
break;
collectMxmlAttributes(map, packageToInternalDescriptors, rootTag);
}
if (element instanceof JSNamedElement) {
JSNamedElement jsClass = (JSNamedElement) element;
if (visited == null || !visited.contains(jsClass)) {
if (!MxmlJSClass.XML_TAG_NAME.equals(jsClass.getName()) && !MxmlJSClass.XMLLIST_TAG_NAME.equals(jsClass.getName())) {
JSReferenceList extendsList = jsClass instanceof JSClass ? ((JSClass) jsClass).getExtendsList() : null;
if (extendsList != null) {
final JSClass clazz = (JSClass) jsClass;
if (visited == null) {
visited = new THashSet<>();
}
visited.add(clazz);
for (JSClass superClazz : clazz.getSuperClasses()) {
appendSuperClassDescriptors(map, packageToInternalDescriptors, superClazz, visited);
}
} else if (!OBJECT_CLASS_NAME.equals(jsClass.getName()) && CodeContext.isStdNamespace(context.namespace)) {
appendSuperClassDescriptors(map, packageToInternalDescriptors, ActionScriptClassResolver.findClassByQNameStatic(OBJECT_CLASS_NAME, jsClass), visited);
}
}
collectMyAttributes(jsClass, map, packageToInternalDescriptors);
}
}
myDescriptors = map;
myPackageToInternalDescriptors = packageToInternalDescriptors;
}
}
use of com.intellij.lang.javascript.flex.AnnotationBackedDescriptor in project intellij-plugins by JetBrains.
the class ClassBackedElementDescriptor method getDefaultPropertyDescriptor.
@Nullable
private AnnotationBackedDescriptor getDefaultPropertyDescriptor(final JSClass jsClass) {
final Ref<JSAttribute> dpAttributeRef = Ref.create();
if (jsClass instanceof XmlBackedJSClassImpl) {
final XmlFile xmlFile = (XmlFile) jsClass.getContainingFile();
final XmlTag rootTag = xmlFile.getRootTag();
if (rootTag != null) {
for (XmlTag metadataTag : rootTag.findSubTags(FlexPredefinedTagNames.METADATA, JavaScriptSupportLoader.MXML_URI3)) {
JSResolveUtil.processInjectedFileForTag(metadataTag, new JSResolveUtil.JSInjectedFilesVisitor() {
@Override
protected void process(final JSFile file) {
for (PsiElement elt : file.getChildren()) {
if (elt instanceof JSAttributeList) {
final JSAttribute dpAttribute = ((JSAttributeList) elt).findAttributeByName("DefaultProperty");
if (dpAttributeRef.isNull() && dpAttribute != null) {
dpAttributeRef.set(dpAttribute);
return;
}
}
}
}
});
}
}
} else {
final JSAttributeList attributeList = jsClass.getAttributeList();
if (attributeList != null) {
dpAttributeRef.set(attributeList.findAttributeByName("DefaultProperty"));
}
}
final JSAttribute attribute = dpAttributeRef.get();
if (attribute != null) {
JSAttributeNameValuePair pair = attribute.getValueByName(null);
if (pair != null) {
String s = pair.getSimpleValue();
if (s != null) {
getAttributesDescriptors(null);
XmlAttributeDescriptor descriptor = getAttributeDescriptor(s, null);
if (descriptor instanceof AnnotationBackedDescriptor) {
return (AnnotationBackedDescriptor) descriptor;
} else {
return new AnnotationBackedDescriptorImpl("any", this, true, "NonExistentClass!", null, null);
}
}
}
}
return null;
}
Aggregations