private string TransformTemplate(CompileFile assemblyFile) { // 读取文件,解析其语法树。 var originalText = File.ReadAllText(assemblyFile.FullName); var syntaxTree = CSharpSyntaxTree.ParseText(originalText); var visitor = new PlaceholderVisitor(); visitor.Visit(syntaxTree.GetRoot()); var builder = new StringBuilder(); var currentTextPosition = 0; var placeholders = visitor.Placeholders; foreach (var placeholder in placeholders) { var actualText = placeholder.Execute(_compilingContext); builder.Append(originalText.Substring(currentTextPosition, placeholder.Span.Start)); builder.Append(actualText); currentTextPosition = placeholder.Span.End; } builder.Append(originalText.Substring(currentTextPosition, originalText.Length - currentTextPosition)); builder.Replace("[CompileTimeTemplate]", ""); builder.Replace("using dotnetCampus.SourceFusion;", ""); var targetText = builder.ToString(); var fileName = Path.GetFileNameWithoutExtension(assemblyFile.FullName); var targetFile = Path.Combine(_generatedCodeFolder, $"{fileName}.g.cs"); File.WriteAllText(targetFile, targetText); return(assemblyFile.FullName); }
private string TransformTemplate(CompileFile assemblyFile) { // 读取文件,去掉非期望字符。 var originalText = File.ReadAllText(assemblyFile.FullName); originalText = originalText.Replace("[CompileTimeTemplate]", AssemblyInfo.GeneratedCodeAttribute); originalText = _usingRegex.Replace(originalText, ""); foreach (Match match in _projectPropertyRegex.Matches(originalText)) { var propertyName = match.Groups["propertyName"].Value; var propertyValue = _context.GetProperty(propertyName); originalText = originalText.Replace(match.Value, propertyValue); } // 解析其语法树。 var symbols = _context.PreprocessorSymbols.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); var syntaxTree = CSharpSyntaxTree.ParseText(originalText, new CSharpParseOptions( LanguageVersion.Latest, DocumentationMode.None, SourceCodeKind.Regular, symbols)); // 访问语法节点。 var visitor = new PlaceholderVisitor(); visitor.Visit(syntaxTree.GetRoot()); // 初始化字符串。 var builder = new StringBuilder(AssemblyInfo.GeneratedCodeComment); var namespaceIndex = builder.Length; var currentTextPosition = 0; // 替换占位符。 var placeholders = visitor.Placeholders; foreach (var placeholder in placeholders) { var actualText = placeholder.Fill(_compilingContext); builder.Append( originalText.Substring(currentTextPosition, placeholder.Span.Start - currentTextPosition)); builder.Append(actualText); currentTextPosition = placeholder.Span.End; } // 把文件剩余的部分拼接起来。 builder.Append(originalText.Substring(currentTextPosition)); // 去掉原来的命名空间,添加上新补充的命名空间。 var requiredNamespaces = string.Join(Environment.NewLine, placeholders .SelectMany(x => x.RequiredNamespaces) .Union(visitor.Namespaces.Select(x => x.@namespace)) .Distinct() .OrderBy(s => s, new SystemFirstNamespaceComparer()) .Select(x => $"using {x};")); var namespaceStart = visitor.Namespaces.Min(x => x.span.Start); var namespaceEnd = visitor.Namespaces.Max(x => x.span.End); builder.Remove(namespaceIndex, namespaceEnd - namespaceStart); builder.Insert(namespaceIndex, requiredNamespaces); // 将新的代码写入到文件。 var targetText = builder.ToString(); var fileName = Path.GetFileNameWithoutExtension(assemblyFile.FullName); var targetFile = Path.Combine(_generatedCodeFolder, $"{fileName}.g.cs"); File.WriteAllText(targetFile, targetText); return(assemblyFile.FullName); }