diff --git a/src/fr/adrienbrault/idea/symfony2plugin/action/SymfonySymbolSearchAction.java b/src/fr/adrienbrault/idea/symfony2plugin/action/SymfonySymbolSearchAction.java index 9c19cd070..beffc3a1f 100644 --- a/src/fr/adrienbrault/idea/symfony2plugin/action/SymfonySymbolSearchAction.java +++ b/src/fr/adrienbrault/idea/symfony2plugin/action/SymfonySymbolSearchAction.java @@ -94,7 +94,7 @@ private ContainerCollectionResolver.ServiceCollector getServiceCollector() { private Map> getTemplateMap() { if(this.templateMap == null) { - this.templateMap = TwigUtil.getTwigAndPhpTemplateFiles(this.project); + this.templateMap = TwigUtil.getTemplateMap(this.project, true); } return this.templateMap; diff --git a/src/fr/adrienbrault/idea/symfony2plugin/navigation/TemplateFileContributor.java b/src/fr/adrienbrault/idea/symfony2plugin/navigation/TemplateFileContributor.java index 0e0ed919a..c2cf371d0 100644 --- a/src/fr/adrienbrault/idea/symfony2plugin/navigation/TemplateFileContributor.java +++ b/src/fr/adrienbrault/idea/symfony2plugin/navigation/TemplateFileContributor.java @@ -21,7 +21,7 @@ public String[] getNames(Project project, boolean b) { return new String[0]; } - Collection twigFileNames = TwigUtil.getTwigFileNames(project); + Collection twigFileNames = TwigUtil.getTemplateMap(project).keySet(); return twigFileNames.toArray(new String[twigFileNames.size()]); } diff --git a/src/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java b/src/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java index 1e137e84e..412752c7c 100644 --- a/src/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java +++ b/src/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java @@ -864,42 +864,49 @@ public static String getPresentableTemplateName(@NotNull PsiElement psiElement, * foo.html.twig => ["views/foo.html.twig", "templates/foo.html.twig"] */ @NotNull - private static synchronized Map> getTemplateMap(@NotNull Project project, boolean useTwig, final boolean usePhp) { - Map> templateMapProxy = null; + public static Map> getTemplateMap(@NotNull Project project) { + return getTemplateMap(project, false); + } + + /** + * Generate a mapped template name file multiple relation: + * + * foo.html.twig => ["views/foo.html.twig", "templates/foo.html.twig"] + */ + @NotNull + public static synchronized Map> getTemplateMap(@NotNull Project project, boolean usePhp) { + Map> templateMapProxy; // cache twig and all files, // only PHP files we dont need to cache - if(useTwig && !usePhp) { + if(!usePhp) { // cache twig files only, most use case CachedValue>> cache = project.getUserData(TEMPLATE_CACHE_TWIG); if (cache == null) { - cache = CachedValuesManager.getManager(project).createCachedValue(new MyTwigOnlyTemplateFileMapCachedValueProvider(project), false); + cache = CachedValuesManager.getManager(project).createCachedValue(new MyAllTemplateFileMapCachedValueProvider(project), false); project.putUserData(TEMPLATE_CACHE_TWIG, cache); } templateMapProxy = cache.getValue(); - - } else if(useTwig && usePhp) { + } else { // cache all files CachedValue>> cache = project.getUserData(TEMPLATE_CACHE_ALL); if (cache == null) { - cache = CachedValuesManager.getManager(project).createCachedValue(new MyAllTemplateFileMapCachedValueProvider(project), false); + cache = CachedValuesManager.getManager(project).createCachedValue(new MyAllTemplateFileMapCachedValueProvider(project, true), false); project.putUserData(TEMPLATE_CACHE_ALL, cache); } templateMapProxy = cache.getValue(); } - // cache-less calls - if(templateMapProxy == null) { - templateMapProxy = getTemplateMapProxy(project, useTwig, usePhp); - } - return templateMapProxy; } + /** + * Cache less visiting template files + */ @NotNull - private static Map> getTemplateMapProxy(@NotNull Project project, boolean useTwig, boolean usePhp) { + private static Map> getTemplateMapProxy(@NotNull Project project, boolean usePhp) { List twigPaths = new ArrayList<>(getTwigNamespaces(project)); if(twigPaths.size() == 0) { return Collections.emptyMap(); @@ -913,39 +920,29 @@ private static Map> getTemplateMapProxy(@NotNull Projec } VirtualFile virtualDirectoryFile = twigPath.getDirectory(project); - if(virtualDirectoryFile != null) { - MyLimitedVirtualFileVisitor visitor = new MyLimitedVirtualFileVisitor(project, twigPath, usePhp, useTwig, 5, 150); - - VfsUtil.visitChildrenRecursively(virtualDirectoryFile, visitor); + if(virtualDirectoryFile == null) { + continue; + } - for (Map.Entry entry : visitor.getResults().entrySet()) { - if(!templateNames.containsKey(entry.getKey())) { - templateNames.put(entry.getKey(), new HashSet<>()); - } + Map visitor = MyLimitedVirtualFileVisitor.createResult( + virtualDirectoryFile, + project, + twigPath, + usePhp + ); - templateNames.get(entry.getKey()).add(entry.getValue()); + for (Map.Entry entry : visitor.entrySet()) { + if(!templateNames.containsKey(entry.getKey())) { + templateNames.put(entry.getKey(), new HashSet<>()); } + + templateNames.get(entry.getKey()).add(entry.getValue()); } } return templateNames; } - @NotNull - static Map> getTwigTemplateFiles(@NotNull Project project) { - return getTemplateMap(project, true, false); - } - - @NotNull - public static Collection getTwigFileNames(@NotNull Project project) { - return getTemplateMap(project, true, false).keySet(); - } - - @NotNull - public static Map> getTwigAndPhpTemplateFiles(@NotNull Project project) { - return getTemplateMap(project, true, true); - } - @Nullable private static TwigNamespaceSetting findManagedTwigNamespace(@NotNull Project project, @NotNull TwigPath twigPath) { List twigNamespaces = Settings.getInstance(project).twigNamespaces; @@ -1481,7 +1478,8 @@ public static Collection getTwigMacroTargets(final Project project, public static Collection getTwigLookupElements(@NotNull Project project) { VirtualFile baseDir = project.getBaseDir(); - return getTwigTemplateFiles(project).entrySet().stream() + return getTemplateMap(project).entrySet() + .stream() .filter(entry -> entry.getValue().size() > 0) .map((java.util.function.Function>, LookupElement>) entry -> new TemplateLookupElement(entry.getKey(), entry.getValue().iterator().next(), baseDir) @@ -1496,7 +1494,8 @@ public static Collection getTwigLookupElements(@NotNull Project p public static Collection getAllTemplateLookupElements(@NotNull Project project) { VirtualFile baseDir = project.getBaseDir(); - return getTwigAndPhpTemplateFiles(project).entrySet().stream() + return getTemplateMap(project, true).entrySet() + .stream() .filter(entry -> entry.getValue().size() > 0) .map((java.util.function.Function>, LookupElement>) entry -> new TemplateLookupElement(entry.getKey(), entry.getValue().iterator().next(), baseDir) @@ -2751,33 +2750,25 @@ public String getDomain() { } } - private static class MyTwigOnlyTemplateFileMapCachedValueProvider implements CachedValueProvider>> { + private static class MyAllTemplateFileMapCachedValueProvider implements CachedValueProvider>> { @NotNull private final Project project; - MyTwigOnlyTemplateFileMapCachedValueProvider(@NotNull Project project) { - this.project = project; - } + private final boolean includePhpFiles; - @Nullable - @Override - public Result>> compute() { - return Result.create(getTemplateMapProxy(project, true, false), PsiModificationTracker.MODIFICATION_COUNT); + MyAllTemplateFileMapCachedValueProvider(@NotNull Project project) { + this(project, false); } - } - - private static class MyAllTemplateFileMapCachedValueProvider implements CachedValueProvider>> { - @NotNull - private final Project project; - MyAllTemplateFileMapCachedValueProvider(@NotNull Project project) { + MyAllTemplateFileMapCachedValueProvider(@NotNull Project project, boolean includePhpFiles) { this.project = project; + this.includePhpFiles = includePhpFiles; } @Nullable @Override public Result>> compute() { - return Result.create(getTemplateMapProxy(project, true, true), PsiModificationTracker.MODIFICATION_COUNT); + return Result.create(getTemplateMapProxy(project, includePhpFiles), PsiModificationTracker.MODIFICATION_COUNT); } } @@ -2798,20 +2789,19 @@ private static class MyLimitedVirtualFileVisitor extends VirtualFileVisitor { @NotNull private Map results = new HashMap<>(); - private boolean withPhp = false; - private boolean withTwig = true; - private int childrenAllowToVisit = 1000; + final private boolean withPhp; + + private int childrenAllowToVisit; @NotNull private Set workedOn = new HashSet<>(); - MyLimitedVirtualFileVisitor(@NotNull Project project, @NotNull TwigPath twigPath, boolean withPhp, boolean withTwig, int maxDepth, int maxDirs) { + private MyLimitedVirtualFileVisitor(@NotNull Project project, @NotNull TwigPath twigPath, boolean withPhp, int maxDepth, int maxDirs) { super(VirtualFileVisitor.limit(maxDepth)); this.project = project; this.twigPath = twigPath; this.withPhp = withPhp; - this.withTwig = withTwig; this.childrenAllowToVisit = maxDirs; } @@ -2852,7 +2842,7 @@ private boolean isProcessable(VirtualFile virtualFile) { return false; } - if(withTwig && virtualFile.getFileType() instanceof TwigFileType) { + if(virtualFile.getFileType() instanceof TwigFileType) { return true; } @@ -2864,8 +2854,15 @@ private boolean isProcessable(VirtualFile virtualFile) { } @NotNull - public Map getResults() { + private Map getResults() { return results; } + + @NotNull + static Map createResult(@NotNull VirtualFile virtualFile, @NotNull Project project, @NotNull TwigPath twigPath, boolean withPhp) { + MyLimitedVirtualFileVisitor visitor = new MyLimitedVirtualFileVisitor(project, twigPath, withPhp, 5, 150); + VfsUtil.visitChildrenRecursively(virtualFile, visitor); + return visitor.getResults(); + } } } diff --git a/tests/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigUtilTempTest.java b/tests/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigUtilTempTest.java index cb47865e9..da50cab22 100644 --- a/tests/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigUtilTempTest.java +++ b/tests/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigUtilTempTest.java @@ -107,30 +107,24 @@ public void testGetTemplateNamesForFile() { ); } - /** - * @see TwigUtil#getTwigFileNames - */ public void testGetTwigFileNames() { createFile("res/foobar/foo.html.twig"); Settings.getInstance(getProject()).twigNamespaces.addAll(createTwigNamespaceSettings()); assertContainsElements( - TwigUtil.getTwigFileNames(getProject()), + TwigUtil.getTemplateMap(getProject()).keySet(), "@Foo/foobar/foo.html.twig", "FooBundle:foobar:foo.html.twig", ":foobar:foo.html.twig", "foobar/foo.html.twig" ); } - /** - * @see TwigUtil#getTwigAndPhpTemplateFiles - */ public void testGetTwigAndPhpTemplateFiles() { createFiles("res/foobar/foo.html.twig", "res/foobar/foo.php"); Settings.getInstance(getProject()).twigNamespaces.addAll(createTwigNamespaceSettings()); assertContainsElements( - TwigUtil.getTwigAndPhpTemplateFiles(getProject()).keySet(), + TwigUtil.getTemplateMap(getProject(), true).keySet(), "@Foo/foobar/foo.html.twig", "FooBundle:foobar:foo.html.twig", ":foobar:foo.html.twig", "foobar/foo.html.twig", "@Foo/foobar/foo.php", "FooBundle:foobar:foo.php", ":foobar:foo.php", "foobar/foo.php" );