private static void ResolveImportResources(Templates start, HashSet <Templates> resourcesFound, Dictionary <string, Templates> cachedTemplates, Stack <Templates> parentTemplates) { resourcesFound.Add(start); parentTemplates.Push(start); foreach (var import in start.Imports) { LGResource resource; try { var originalResource = new LGResource(start.Id, start.Source, start.Content); resource = start.ImportResolver(originalResource, import.Id); } catch (Exception e) { var diagnostic = new Diagnostic(import.SourceRange.Range, e.Message, DiagnosticSeverity.Error, start.Source); throw new TemplateException(e.Message, new List <Diagnostic>() { diagnostic }); } // Cycle reference would throw exception to avoid infinite Loop. // Import self is allowed, and would ignore it. if (parentTemplates.Peek().Id != resource.Id && parentTemplates.Any(u => u.Id == resource.Id)) { var errorMsg = $"{TemplateErrors.LoopDetected} {resource.Id} => {start.Id}"; var diagnostic = new Diagnostic(import.SourceRange.Range, errorMsg, DiagnosticSeverity.Error, start.Source); throw new TemplateException(errorMsg, new List <Diagnostic>() { diagnostic }); } if (resourcesFound.All(u => u.Id != resource.Id)) { Templates childResource; if (cachedTemplates.ContainsKey(resource.Id)) { childResource = cachedTemplates[resource.Id]; } else { childResource = InnerParseResource(resource, start.ImportResolver, start.ExpressionParser, cachedTemplates, parentTemplates); cachedTemplates.Add(resource.Id, childResource); } ResolveImportResources(childResource, resourcesFound, cachedTemplates, parentTemplates); } } parentTemplates.Pop(); }
private static void ResolveImportResources(Templates start, HashSet <Templates> resourcesFound, Dictionary <string, Templates> cachedTemplates) { resourcesFound.Add(start); foreach (var import in start.Imports) { LGResource resource; try { var originalResource = new LGResource(start.Id, start.Source, start.Content); resource = start.ImportResolver(originalResource, import.Id); } catch (Exception e) { var diagnostic = new Diagnostic(import.SourceRange.Range, e.Message, DiagnosticSeverity.Error, start.Source); throw new TemplateException(e.Message, new List <Diagnostic>() { diagnostic }); } if (resourcesFound.All(u => u.Id != resource.Id)) { Templates childResource; if (cachedTemplates.ContainsKey(resource.Id)) { childResource = cachedTemplates[resource.Id]; } else { childResource = ParseResource(resource, start.ImportResolver, start.ExpressionParser, cachedTemplates); cachedTemplates.Add(resource.Id, childResource); } ResolveImportResources(childResource, resourcesFound, cachedTemplates); } } }