package com.intellij.lang.javascript.uml;
import com.intellij.diagram.DiagramVfsResolver;
import com.intellij.javascript.flex.resolve.ActionScriptClassResolver;
import com.intellij.lang.javascript.JavaScriptSupportLoader;
import com.intellij.lang.javascript.psi.JSCommonTypeNames;
import com.intellij.lang.javascript.psi.JSFile;
import com.intellij.lang.javascript.psi.ecmal4.JSClass;
import com.intellij.lang.javascript.psi.ecmal4.JSQualifiedNamedElement;
import com.intellij.lang.javascript.psi.ecmal4.XmlBackedJSClassFactory;
import com.intellij.lang.javascript.psi.impl.JSPsiImplUtils;
import com.intellij.lang.javascript.psi.resolve.JSResolveUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class FlashUmlVfsResolver implements DiagramVfsResolver<Object> {
private static final Logger LOG = Logger.getInstance(FlashUmlVfsResolver.class.getName());
public static final String SEPARATOR = ":";
public String getQualifiedName(Object element) {
return getQualifiedNameStatic(element);
}
@Nullable
public static String getQualifiedNameStatic(Object element) {
if (element == null) {
return null;
}
if (element instanceof PsiElement) {
if (((PsiElement)element).getProject().isDisposed()) {
return null;
}
if (element instanceof JSQualifiedNamedElement) {
JSQualifiedNamedElement qualifiedNamedElement = (JSQualifiedNamedElement)element;
String qName = qualifiedNamedElement.getQualifiedName();
if (qName == null) return null;
return combineWithModuleName(qualifiedNamedElement, fixVectorTypeName(qName));
}
else if (element instanceof JSFile) {
return getQualifiedNameStatic(JSPsiImplUtils.findQualifiedElement((JSFile)element));
}
else if (element instanceof XmlFile && JavaScriptSupportLoader.isFlexMxmFile((PsiFile)element)) {
//noinspection ConstantConditions
return getQualifiedNameStatic(XmlBackedJSClassFactory.getXmlBackedClass((XmlFile)element));
}
else if (element instanceof PsiDirectory) {
PsiDirectory directory = (PsiDirectory)element;
return JSResolveUtil.getExpectedPackageNameFromFile(directory.getVirtualFile(), directory.getProject());
}
}
else if (element instanceof String) {
return (String)element;
}
LOG.error("can't get qualified name of " + element);
return null;
}
@Nullable
private static String combineWithModuleName(@NotNull final PsiElement element, @Nullable final String qName) {
if (qName == null) return null;
if (ApplicationManager.getApplication().isUnitTestMode()) return qName;
Module module = ModuleUtil.findModuleForPsiElement(element);
if (module != null) {
return module.getName() + SEPARATOR + qName;
}
return qName;
}
public Object resolveElementByFQN(String fqn, Project project) {
return resolveElementByFqnStatic(fqn, project);
}
@Nullable
public static Object resolveElementByFqnStatic(String fqn, Project project) {
final GlobalSearchScope searchScope;
int separatorIndex = fqn.indexOf(SEPARATOR);
if (separatorIndex != -1) {
String moduleName = fqn.substring(0, separatorIndex);
Module module = ModuleManager.getInstance(project).findModuleByName(moduleName);
if (module == null) {
return null;
}
fqn = fqn.substring(separatorIndex + 1);
searchScope = module.getModuleScope(true);
}
else {
searchScope = GlobalSearchScope.allScope(project);
}
final PsiElement clazz = ActionScriptClassResolver.findClassByQNameStatic(fqn, searchScope);
if (clazz instanceof JSClass) return clazz;
if (FlashUmlElementManager.packageExists(project, fqn, searchScope)) return fqn;
return null;
}
static String fixVectorTypeName(String name) {
if (isVectorType(name)) {
return JSCommonTypeNames.VECTOR_CLASS_NAME;
}
return name;
}
static boolean isVectorType(final String name) {
return name.startsWith("Vector$");
}
}