package fr.adrienbrault.idea.symfony2plugin.twig.variable.collector; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; 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 fr.adrienbrault.idea.symfony2plugin.config.utils.ConfigUtil; import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver; import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil; import fr.adrienbrault.idea.symfony2plugin.templating.variable.TwigFileVariableCollector; import fr.adrienbrault.idea.symfony2plugin.templating.variable.TwigFileVariableCollectorParameter; import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable; import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.psi.YAMLFile; import java.util.HashMap; import java.util.HashSet; import java.util.Map; /** * config.yml: * twig: * globals: * foobar: "@foobar" * * @author Daniel Espendiller <[email protected]> */ public class GlobalTwigConfigVariableCollector implements TwigFileVariableCollector { private static final Key<CachedValue<Map<String, PsiVariable>>> CACHE = new Key<>("TWIG_CONFIGURATION_GLOBALS"); @Override public void collectPsiVariables(@NotNull TwigFileVariableCollectorParameter parameter, @NotNull Map<String, PsiVariable> variables) { variables.putAll(getGlobals(parameter.getProject())); } @NotNull private Map<String, PsiVariable> getGlobals(@NotNull Project project) { return CachedValuesManager.getManager(project).getCachedValue( project, CACHE, () -> CachedValueProvider.Result.create(getGlobalsInner(project), PsiModificationTracker.MODIFICATION_COUNT), false ); } @NotNull private static Map<String, PsiVariable> getGlobalsInner(@NotNull Project project) { Map<String, PsiVariable> variableMap = new HashMap<>(); for (VirtualFile virtualFile : ConfigUtil.getConfigurations(project, "twig")) { PsiFile file = PsiManager.getInstance(project).findFile(virtualFile); if(!(file instanceof YAMLFile)) { continue; } for (Map.Entry<String, String> entry : TwigUtil.getTwigGlobalsFromYamlConfig((YAMLFile) file).entrySet()) { String value = entry.getValue(); String serviceClass = ContainerCollectionResolver.resolveService( project, YamlHelper.trimSpecialSyntaxServiceName(value) ); if(serviceClass != null) { variableMap.put(entry.getKey(), new PsiVariable("\\" + serviceClass)); } else { variableMap.put(entry.getKey(), new PsiVariable(new HashSet<>())); } } } return variableMap; } }