package org.angularjs.editor;
import com.intellij.lang.Language;
import com.intellij.lang.javascript.JavascriptLanguage;
import com.intellij.lang.javascript.psi.stubs.JSImplicitElement;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import org.angularjs.index.AngularIndexUtil;
import org.angularjs.index.AngularInjectionDelimiterIndex;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author Dennis.Ushakov
*/
public class AngularJSBracesUtil {
public static final String DEFAULT_START = "{{";
public static final String DEFAULT_END = "}}";
public static final Key<CachedValue<String>> START_KEY = Key.create("angularjs.startSymbol");
public static final Key<CachedValue<String>> END_KEY = Key.create("angularjs.endSymbol");
private static final Set<String> DEFAULT_CONFLICTS = new HashSet<>(Arrays.asList("DjangoTemplate", "Jinja2", "Web2Py",
"Handlebars", "Twig", "Blade"));
public static String getInjectionStart(Project project) {
return getInjectionDelimiter(project, START_KEY, DEFAULT_START);
}
public static String getInjectionEnd(Project project) {
return getInjectionDelimiter(project, END_KEY, DEFAULT_END);
}
private static String getInjectionDelimiter(Project project, final Key<CachedValue<String>> key, final String defaultDelimiter) {
return CachedValuesManager.getManager(project).getCachedValue(project, key, () -> {
String id = key.toString();
final JSImplicitElement delimiter = AngularIndexUtil.resolve(project, AngularInjectionDelimiterIndex.KEY,
id.substring(id.lastIndexOf(".") + 1));
if (delimiter != null) {
return CachedValueProvider.Result.create(delimiter.getTypeString(), delimiter);
}
return CachedValueProvider.Result.create(defaultDelimiter, PsiModificationTracker.MODIFICATION_COUNT);
}, false);
}
public static boolean hasConflicts(String start, String end, PsiElement element) {
final Language elementLanguage = element.getLanguage();
// JSP contains two roots that contain XmlText, don't inject anything in JSP root to prevent double injections
if ("JSP".equals(elementLanguage.getDisplayName())) {
return true;
}
PsiFile file = element.getContainingFile();
if (DEFAULT_START.equals(start) || DEFAULT_END.equals(end)) {
// JSX attributes don't contain AngularJS injections, {{}} is JSX injection with object inside
if (elementLanguage.isKindOf(JavascriptLanguage.INSTANCE)) return true;
for (Language language : file.getViewProvider().getLanguages()) {
if (DEFAULT_CONFLICTS.contains(language.getDisplayName())) {
return true;
}
}
}
return false;
}
}