package com.intellij.javascript.flex;
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
import com.intellij.lang.javascript.psi.impl.JSPropertyReference;
import com.intellij.lang.javascript.psi.resolve.JSResolveUtil;
import com.intellij.lang.properties.BundleNameEvaluator;
import com.intellij.lang.properties.PropertiesReferenceManager;
import com.intellij.lang.properties.ResourceBundleReference;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.references.PropertyReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class FlexPropertiesSupport {
private static final BundleNameEvaluator MY_BUNDLE_NAME_EVALUATOR = new BundleNameEvaluator() {
public String evaluateBundleName(PsiFile psiFile) {
final VirtualFile virtualFile = psiFile == null ? null : psiFile.getOriginalFile().getVirtualFile();
if (virtualFile != null && psiFile instanceof PropertiesFile) {
String className = virtualFile.getNameWithoutExtension();
String packageName = JSResolveUtil.getExpectedPackageNameFromFile(virtualFile, psiFile.getProject());
if (!StringUtil.isEmpty(packageName)) {
className = packageName + "." + className;
}
return className;
}
return null;
}
};
public static <T extends PsiElement> PsiReference[] getPropertyReferences(T element, PropertyReferenceInfoProvider<T> infoProvider) {
TextRange range = infoProvider.getReferenceRange(element);
if (range == null) return PsiReference.EMPTY_ARRAY;
return new PsiReference[]{
new MyPropertyReference(range, element, infoProvider)
};
}
public static <T extends PsiElement> PsiReference[] getResourceBundleReference(T element, BundleReferenceInfoProvider<T> infoProvider) {
final TextRange textRange = infoProvider.getReferenceRange(element);
if (textRange == null) return PsiReference.EMPTY_ARRAY;
return new PsiReference[] { new MyResourceBundleReference(element, infoProvider.isSoft(element)) {
@Override
protected TextRange calculateDefaultRangeInElement() {
return textRange;
}
}
};
}
public interface PropertyReferenceInfoProvider<T> {
@Nullable TextRange getReferenceRange(T element);
@Nullable String getBundleName(T element);
boolean isSoft(T element);
}
public interface BundleReferenceInfoProvider<T> {
@Nullable TextRange getReferenceRange(T element);
boolean isSoft(T element);
}
private static class MyPropertyReference<T extends PsiElement> extends PropertyReference implements JSPropertyReference {
public MyPropertyReference(TextRange range, T element, PropertyReferenceInfoProvider<T> infoProvider) {
super(range.substring(element.getText()), element, infoProvider.getBundleName(element), infoProvider.isSoft(element), range);
}
@Override
protected List<PropertiesFile> retrievePropertyFilesByBundleName(String bundleName, PsiElement element) {
return PropertiesReferenceManager.getInstance(element.getProject()).findPropertiesFiles(
element.getResolveScope(),
bundleName,
MY_BUNDLE_NAME_EVALUATOR
);
}
}
private static class MyResourceBundleReference extends ResourceBundleReference implements EmptyResolveMessageProvider {
public MyResourceBundleReference(PsiElement element, boolean soft) {
super(element, soft);
}
@NotNull
public String getUnresolvedMessagePattern() {
return "Cannot resolve property bundle";
}
@Nullable
public String evaluateBundleName(final PsiFile psiFile) {
return MY_BUNDLE_NAME_EVALUATOR.evaluateBundleName(psiFile);
}
}
}