// use static method so we don't capture references to this private static Tuple <ValueSource <TextAndVersion>, TreeAndVersion> CreateRecoverableTextAndTree( SyntaxNode newRoot, string filePath, VersionStamp textVersion, VersionStamp treeVersion, Encoding encoding, DocumentInfo.DocumentAttributes attributes, ParseOptions options, ImmutableDictionary <string, ReportDiagnostic> treeDiagnosticReportingOptionsOpt, ISyntaxTreeFactoryService factory, PreservationMode mode) { SyntaxTree tree = null; ValueSource <TextAndVersion> lazyTextAndVersion = null; if ((mode == PreservationMode.PreserveIdentity) || !factory.CanCreateRecoverableTree(newRoot)) { // its okay to use a strong cached AsyncLazy here because the compiler layer SyntaxTree will also keep the text alive once its built. lazyTextAndVersion = new TreeTextSource( new AsyncLazy <SourceText>( c => tree.GetTextAsync(c), c => tree.GetText(c), cacheResult: true), textVersion, filePath); tree = factory.CreateSyntaxTree(filePath, options, encoding, newRoot, treeDiagnosticReportingOptionsOpt); } else { // uses CachedWeakValueSource so the document and tree will return the same SourceText instance across multiple accesses as long // as the text is referenced elsewhere. lazyTextAndVersion = new TreeTextSource( new CachedWeakValueSource <SourceText>( new AsyncLazy <SourceText>( c => BuildRecoverableTreeTextAsync(tree, encoding, c), c => BuildRecoverableTreeText(tree, encoding, c), cacheResult: false)), textVersion, filePath); tree = factory.CreateRecoverableTree(attributes.Id.ProjectId, filePath, options, lazyTextAndVersion, encoding, newRoot, treeDiagnosticReportingOptionsOpt); } return(Tuple.Create(lazyTextAndVersion, TreeAndVersion.Create(tree, treeVersion))); }
internal static async Task <SyntaxTree> FixOneAsync(SyntaxTree syntaxTree, FormattingProvider formattingProvider, SyntaxFormattingOptions options, Diagnostic diagnostic, CancellationToken cancellationToken) { // The span to format is the full line(s) containing the diagnostic var text = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var diagnosticSpan = diagnostic.Location.SourceSpan; var diagnosticLinePositionSpan = text.Lines.GetLinePositionSpan(diagnosticSpan); var spanToFormat = TextSpan.FromBounds( text.Lines[diagnosticLinePositionSpan.Start.Line].Start, text.Lines[diagnosticLinePositionSpan.End.Line].End); var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var formattedRoot = Formatter.Format(root, spanToFormat, formattingProvider, options, cancellationToken); return(syntaxTree.WithRootAndOptions(formattedRoot, syntaxTree.Options)); }
internal static async Task <SyntaxTree> FixOneAsync( SyntaxTree syntaxTree, FormatterState formatterState, OptionSet options, Diagnostic diagnostic, CancellationToken cancellationToken ) { // The span to format is the full line(s) containing the diagnostic var text = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var diagnosticSpan = diagnostic.Location.SourceSpan; var diagnosticLinePositionSpan = text.Lines.GetLinePositionSpan(diagnosticSpan); var spanToFormat = TextSpan.FromBounds( text.Lines[diagnosticLinePositionSpan.Start.Line].Start, text.Lines[diagnosticLinePositionSpan.End.Line].End ); var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); #if CODE_STYLE var formattedRoot = Formatter.Format( root, formatterState, new[] { spanToFormat }, options, Formatter.GetDefaultFormattingRules(formatterState), cancellationToken ); #else var formattedRoot = Formatter.Format( root, spanToFormat, formatterState, options, cancellationToken ); #endif return(syntaxTree.WithRootAndOptions(formattedRoot, syntaxTree.Options)); }
private async Task WriteDbContext(NewDbContextTemplateModel dbContextTemplateModel, SyntaxTree newDbContextTree) { //ToDo: What's the best place to write the DbContext? var appBasePath = _environment.ApplicationBasePath; var outputPath = Path.Combine( appBasePath, "Models", dbContextTemplateModel.DbContextTypeName + ".cs"); if (File.Exists(outputPath)) { // Odd case, a file exists with the same name as the DbContextTypeName but perhaps // the type defined in that file is different, what should we do in this case? // How likely is the above scenario? // Perhaps we can enumerate files with prefix and generate a safe name? For now, just throw. throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "There was an error creating a DbContext, the file {0} already exists", outputPath)); } var sourceText = await newDbContextTree.GetTextAsync(); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var fileStream = new FileStream(outputPath, FileMode.CreateNew, FileAccess.Write)) { using (var streamWriter = new StreamWriter(stream: fileStream, encoding: Encoding.UTF8)) { sourceText.Write(streamWriter); } } _logger.LogMessage("Added DbContext : " + outputPath.Substring(appBasePath.Length)); }