private IEnumerable <RazorPage> ParsePages(RazorProject project) { if (project.Items == null || project.Items.Count == 0) { yield break; } HashSet <string> intermediatePaths = new HashSet <string>(); bool hasProjectDirectory = !string.IsNullOrWhiteSpace(project.ProjectDirectory); foreach (RazorProjectItem item in project.Items.NotNull()) { bool hasProjectPath = !string.IsNullOrWhiteSpace(item.ProjectPath); if (string.IsNullOrWhiteSpace(item.FullPath)) { throw new InvalidOperationException($"Error parsing file at index {project.Items.IndexOf(item)}. Path cannot be empty."); } else if (!Path.IsPathRooted(item.FullPath)) { throw new InvalidOperationException(Error("Path must be rooted.")); } else if (!File.Exists(item.FullPath)) { throw new FileNotFoundException(Error("File not found.")); } else if (!hasProjectDirectory && !hasProjectPath) { throw new InvalidOperationException(Error($"ProjectPath must be specified when no ProjectDirectory is present.")); } string projectPath = hasProjectPath ? item.ProjectPath : null; if (hasProjectDirectory) { projectPath = PathHelper.MakeRelativePath(project.ProjectDirectory, projectPath ?? item.FullPath); } if (projectPath == null) { throw new InvalidOperationException(Error($"ProjectPath '{item.ProjectPath}' must be relative to to ProjectDirectory '{project.ProjectDirectory}'.")); } RazorPageData pageData = this.Parse(item.FullPath); yield return(new RazorPage() { Data = pageData, Path = Path.GetFullPath(item.FullPath), ProjectPath = projectPath, IntermediatePath = this.MakeIntermediatePath(project, item, pageData, intermediatePaths), }); string Error(string s) => $"Error parsing file '{item.FullPath}'. {s}"; } }
private RazorPageData Parse(ISource source, IEnumerable <Lexeme> lexemes, string sourceName, string sourceChecksum) { RazorPageData pageData = new RazorPageData() { SourceName = sourceName, SourceChecksum = sourceChecksum, }; foreach (Lexeme lex in lexemes) { switch (lex.Rule) { case CSharpBlock cs when cs.Type == CSharpType.Expression || cs.Type == CSharpType.Statement || cs.Type == CSharpType.Comment: pageData.Content.Add(this.CreateCodeFragment(source, lex.Span, sourceName, cs.Type)); break; case CSharpBlock cs when cs.RazorType == RazorType.Model: pageData.Model = this.CreateFragment(source, lex.Span, sourceName); break; case CSharpBlock cs when cs.RazorType == RazorType.Result: pageData.Result = this.CreateFragment(source, lex.Span, sourceName); break; case CSharpBlock cs when cs.RazorType == RazorType.Import: pageData.Imports.Add(this.CreateFragment(source, lex.Span, sourceName)); break; case CSharpBlock cs when cs.RazorType == RazorType.Injection || cs.RazorType == RazorType.Projection: { Token[] arguments = lex.Tokens.Where(t => t.Symbol is Argument).ToArray(); InjectDirective directive = new InjectDirective(); if (arguments.Length == 1) { directive.Type = this.CreateFragment(source, arguments[0].Span, sourceName); } else if (arguments.Length > 1) { directive.Type = this.CreateFragment(source, arguments[0].Span, sourceName); directive.Variable = this.CreateFragment(source, arguments[1].Span, sourceName); } if (cs.RazorType == RazorType.Injection) { pageData.Injections.Add(directive); } else { pageData.Projections.Add(directive); } } break; case CSharpBlock cs when cs.RazorType == RazorType.Template: pageData.Template = this.CreateFragment(source, lex.Span, sourceName); break; case CSharpBlock cs when cs.RazorType == RazorType.Namespace: pageData.Namespace = this.CreateFragment(source, lex.Span, sourceName); break; case CSharpBlock cs when cs.RazorType == RazorType.Class: pageData.Class = this.CreateFragment(source, lex.Span, sourceName); break; case SqlBlock sql: pageData.Content.Add(this.CreateSqlFragment(source, lex, sourceName)); break; } } return(pageData); }
private string MakeIntermediatePath(RazorProject project, RazorProjectItem item, RazorPageData pageData, HashSet <string> currentPaths) { if (string.IsNullOrWhiteSpace(project.IntermediateDirectory)) { return(null); } int hashCode = (item.FullPath + "|" + item.ProjectPath + "|" + pageData.SourceChecksum).GetStableHashCode(); string baseFileName = Path.GetFileNameWithoutExtension(item.ProjectPath); string fileName = $"{baseFileName}.{hashCode:x2}.g.cssql.cs"; string fullName = Path.Combine(project.IntermediateDirectory, fileName); int n = 0; while (currentPaths.Contains(fullName, StringComparer.OrdinalIgnoreCase)) { fileName = $"{baseFileName}.{hashCode:x2}.g{n++}.cssql.cs"; fullName = Path.Combine(project.IntermediateDirectory, fileName); } currentPaths.Add(fullName); return(fullName); }