internal AbstractFormatEngine( TreeData treeData, AnalyzerConfigOptions options, ChainedFormattingRules formattingRules, SyntaxToken token1, SyntaxToken token2 ) { Contract.ThrowIfNull(options); Contract.ThrowIfNull(treeData); Contract.ThrowIfNull(formattingRules); Contract.ThrowIfTrue(treeData.Root.IsInvalidTokenRange(token1, token2)); this.Options = options; this.TreeData = treeData; _formattingRules = formattingRules; _token1 = token1; _token2 = token2; // get span and common root this.SpanToFormat = GetSpanToFormat(); _commonRoot = token1.GetCommonRoot(token2) ?? throw ExceptionUtilities.Unreachable; }
internal AbstractFormatEngine( TreeData treeData, AnalyzerConfigOptions options, ChainedFormattingRules formattingRules, SyntaxToken token1, SyntaxToken token2) { Contract.ThrowIfNull(options); Contract.ThrowIfNull(treeData); Contract.ThrowIfNull(formattingRules); Contract.ThrowIfTrue(treeData.Root.IsInvalidTokenRange(token1, token2)); this.Options = options; this.TreeData = treeData; _formattingRules = formattingRules; _token1 = token1; _token2 = token2; // get span and common root this.SpanToFormat = GetSpanToFormat(); _commonRoot = token1.GetCommonRoot(token2); if (token1 == default) { _language = token2.Language; } else { _language = token1.Language; } }
public IList <TextChange> FormatRange( SyntaxToken startToken, SyntaxToken endToken, CancellationToken cancellationToken) { Contract.ThrowIfTrue(startToken.Kind() is SyntaxKind.None or SyntaxKind.EndOfFileToken); Contract.ThrowIfTrue(endToken.Kind() is SyntaxKind.None or SyntaxKind.EndOfFileToken); var smartTokenformattingRules = _formattingRules; var common = startToken.GetCommonRoot(endToken); RoslynDebug.AssertNotNull(common); // if there are errors, do not touch lines // Exception 1: In the case of try-catch-finally block, a try block without a catch/finally block is considered incomplete // but we would like to apply line operation in a completed try block even if there is no catch/finally block // Exception 2: Similar behavior for do-while if (common.ContainsDiagnostics && !CloseBraceOfTryOrDoBlock(endToken)) { smartTokenformattingRules = ImmutableArray <AbstractFormattingRule> .Empty.Add( new NoLineChangeFormattingRule()).AddRange(_formattingRules); } var formatter = CSharpSyntaxFormatting.Instance; var result = formatter.GetFormattingResult( _root, new[] { TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End) }, _options.FormattingOptions, smartTokenformattingRules, cancellationToken); return(result.GetTextChanges(cancellationToken)); }
private List <IndentBlockOperation> GetInitialIndentBlockOperations(SyntaxToken startToken, SyntaxToken endToken) { var span = TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End); var node = startToken.GetCommonRoot(endToken).GetParentWithBiggerSpan(); var previous = default(SyntaxNode); // starting from the common node, move up to the parent var operations = new List <IndentBlockOperation>(); var list = new List <IndentBlockOperation>(); while (node != null) { // get all operations for the nodes that contains the formatting span, but not ones contained by the span node.DescendantNodesAndSelf(n => n != previous && n.Span.IntersectsWith(span) && !span.Contains(n.Span)) .Do(n => { _formattingRules.AddIndentBlockOperations(list, n); foreach (var element in list) { if (element != null) { operations.Add(element); } } list.Clear(); }); // found some. use these as initial indentation if (operations.Any(o => o.TextSpan.Contains(span))) { break; } previous = node; node = node.Parent; } // make sure operations we have has effects over the formatting span operations.RemoveAll(o => o == null || !o.TextSpan.IntersectsWith(span)); // we couldn't find anything // return initial location so that we can get base indentation correctly if (operations.Count == 0) { operations.Add(new IndentBlockOperation( startToken: _rootNode.GetFirstToken(includeZeroWidth: true), endToken: _rootNode.GetLastToken(includeZeroWidth: true), textSpan: _rootNode.FullSpan, indentationDelta: 0, option: IndentBlockOption.AbsolutePosition)); return(operations); } operations.Sort(CommonFormattingHelpers.IndentBlockOperationComparer); return(operations); }
private List<IndentBlockOperation> GetInitialIndentBlockOperations(SyntaxToken startToken, SyntaxToken endToken) { var span = TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End); var node = startToken.GetCommonRoot(endToken).GetParentWithBiggerSpan(); var previous = default(SyntaxNode); // starting from the common node, move up to the parent var operations = new List<IndentBlockOperation>(); var list = new List<IndentBlockOperation>(); while (node != null) { // get all operations for the nodes that contains the formatting span, but not ones contained by the span node.DescendantNodesAndSelf(n => n != previous && n.Span.IntersectsWith(span) && !span.Contains(n.Span)) .Do(n => { this.formattingRules.AddIndentBlockOperations(list, n); foreach (var element in list) { if (element != null) { operations.Add(element); } } list.Clear(); }); // found some. use these as initial indentation if (operations.Any(o => o.TextSpan.Contains(span))) { break; } previous = node; node = node.Parent; } // make sure operations we have has effects over the formatting span operations.RemoveAll(o => o == null || !o.TextSpan.IntersectsWith(span)); // we couldn't find anything // return initial location so that we can get base indentation correctly if (operations.Count == 0) { operations.Add(new IndentBlockOperation( startToken: this.rootNode.GetFirstToken(includeZeroWidth: true), endToken: this.rootNode.GetLastToken(includeZeroWidth: true), textSpan: this.rootNode.FullSpan, indentationDelta: 0, option: IndentBlockOption.AbsolutePosition)); return operations; } operations.Sort(CommonFormattingHelpers.IndentBlockOperationComparer); return operations; }
internal SyntaxNode GetNodeWithTokens(SyntaxToken startToken, SyntaxToken endToken, SyntaxNode root) { if (IsEndOfFileToken(endToken)) { return(root); } else { return(startToken.GetCommonRoot(endToken)); } }
private void SetInnermostNodeForSpan(SyntaxNode root, ref TextSpan span, out SyntaxToken token1, out SyntaxToken token2, out SyntaxNode commonNode) { commonNode = default(SyntaxNode); GetTokens(root, span, out token1, out token2); span = GetSpanFromTokens(span, token1, token2); if (token1.RawKind == 0 || token2.RawKind == 0) { return; } commonNode = token1.GetCommonRoot(token2); }
public IList<TextChange> FormatRange( Workspace workspace, SyntaxToken startToken, SyntaxToken endToken, CancellationToken cancellationToken) { Contract.ThrowIfTrue(startToken.Kind() == SyntaxKind.None || startToken.Kind() == SyntaxKind.EndOfFileToken); Contract.ThrowIfTrue(endToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.EndOfFileToken); var smartTokenformattingRules = _formattingRules; var common = startToken.GetCommonRoot(endToken); if (common.ContainsDiagnostics) { // if there is errors, do not touch lines smartTokenformattingRules = (new NoLineChangeFormattingRule()).Concat(_formattingRules); } return Formatter.GetFormattedTextChanges(_root, new TextSpan[] { TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End) }, workspace, _optionSet, smartTokenformattingRules, cancellationToken); }
public IList <TextChange> FormatRange( Workspace workspace, SyntaxToken startToken, SyntaxToken endToken, CancellationToken cancellationToken) { Contract.ThrowIfTrue(startToken.Kind() == SyntaxKind.None || startToken.Kind() == SyntaxKind.EndOfFileToken); Contract.ThrowIfTrue(endToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.EndOfFileToken); var smartTokenformattingRules = _formattingRules; var common = startToken.GetCommonRoot(endToken); if (common.ContainsDiagnostics) { // if there is errors, do not touch lines smartTokenformattingRules = (new NoLineChangeFormattingRule()).Concat(_formattingRules); } return(Formatter.GetFormattedTextChanges(_root, new TextSpan[] { TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End) }, workspace, _optionSet, smartTokenformattingRules, cancellationToken)); }
public IList<TextChange> FormatRange( Workspace workspace, SyntaxToken startToken, SyntaxToken endToken, CancellationToken cancellationToken) { Contract.ThrowIfTrue(startToken.Kind() == SyntaxKind.None || startToken.Kind() == SyntaxKind.EndOfFileToken); Contract.ThrowIfTrue(endToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.EndOfFileToken); var smartTokenformattingRules = _formattingRules; var common = startToken.GetCommonRoot(endToken); // if there are errors, do not touch lines // Exception: In the case of try-catch-finally block, a try block without a catch/finally block is considered incomplete // but we would like to apply line operation in a completed try block even if there is no catch/finally block if (common.ContainsDiagnostics && !CloseBraceOfTryBlock(endToken)) { smartTokenformattingRules = (new NoLineChangeFormattingRule()).Concat(_formattingRules); } return Formatter.GetFormattedTextChanges(_root, new TextSpan[] { TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End) }, workspace, _optionSet, smartTokenformattingRules, cancellationToken); }
internal AbstractFormatEngine( TreeData treeData, OptionSet optionSet, ChainedFormattingRules formattingRules, SyntaxToken token1, SyntaxToken token2, TaskExecutor executor) { Contract.ThrowIfNull(optionSet); Contract.ThrowIfNull(treeData); Contract.ThrowIfNull(formattingRules); Contract.ThrowIfNull(executor); Contract.ThrowIfTrue(treeData.Root.IsInvalidTokenRange(token1, token2)); this.OptionSet = optionSet; this.TreeData = treeData; _formattingRules = formattingRules; _token1 = token1; _token2 = token2; // get span and common root this.SpanToFormat = GetSpanToFormat(); _commonRoot = token1.GetCommonRoot(token2); if (token1 == default) { _language = token2.Language; } else { _language = token1.Language; } // set synchronous task executor if it is enabled (explicitly or as part of debug mode) or if there is not // many things to format var synchronousExecutorAllowed = !optionSet.GetOption(FormattingOptions.AllowConcurrent) || optionSet.GetOption(FormattingOptions.DebugMode, _language); var useSynchronousExecutor = synchronousExecutorAllowed || SpanToFormat.Length < ConcurrentThreshold; TaskExecutor = useSynchronousExecutor ? TaskExecutor.Synchronous : executor; }
internal AbstractFormatEngine( TreeData treeData, SyntaxFormattingOptions options, ChainedFormattingRules formattingRules, SyntaxToken startToken, SyntaxToken endToken) { Contract.ThrowIfTrue(treeData.Root.IsInvalidTokenRange(startToken, endToken)); this.Options = options; this.TreeData = treeData; _formattingRules = formattingRules; _startToken = startToken; _endToken = endToken; // get span and common root this.SpanToFormat = GetSpanToFormat(); _commonRoot = startToken.GetCommonRoot(endToken) ?? throw ExceptionUtilities.Unreachable; }
public IList <TextChange> FormatRange( Workspace workspace, SyntaxToken startToken, SyntaxToken endToken, CancellationToken cancellationToken) { Contract.ThrowIfTrue(startToken.Kind() == SyntaxKind.None || startToken.Kind() == SyntaxKind.EndOfFileToken); Contract.ThrowIfTrue(endToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.EndOfFileToken); var smartTokenformattingRules = _formattingRules; var common = startToken.GetCommonRoot(endToken); // if there are errors, do not touch lines // Exception 1: In the case of try-catch-finally block, a try block without a catch/finally block is considered incomplete // but we would like to apply line operation in a completed try block even if there is no catch/finally block // Exception 2: Similar behavior for do-while if (common.ContainsDiagnostics && !CloseBraceOfTryOrDoBlock(endToken)) { smartTokenformattingRules = (new NoLineChangeFormattingRule()).Concat(_formattingRules); } return(Formatter.GetFormattedTextChanges(_root, new TextSpan[] { TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End) }, workspace, _optionSet, smartTokenformattingRules, cancellationToken)); }
internal AbstractFormatEngine( TreeData treeData, OptionSet optionSet, ChainedFormattingRules formattingRules, SyntaxToken token1, SyntaxToken token2, TaskExecutor executor) { Contract.ThrowIfNull(optionSet); Contract.ThrowIfNull(treeData); Contract.ThrowIfNull(formattingRules); Contract.ThrowIfNull(executor); Contract.ThrowIfTrue(treeData.Root.IsInvalidTokenRange(token1, token2)); this.OptionSet = optionSet; this.TreeData = treeData; this.formattingRules = formattingRules; this.token1 = token1; this.token2 = token2; // get span and common root this.SpanToFormat = GetSpanToFormat(); this.commonRoot = token1.GetCommonRoot(token2); if (token1 == default(SyntaxToken)) { this.language = token2.Language; } else { this.language = token1.Language; } // set synchronous task executor if it is debug mode or if there is not many things to format this.TaskExecutor = optionSet.GetOption(FormattingOptions.DebugMode, this.language) ? TaskExecutor.Synchronous : (SpanToFormat.Length < ConcurrentThreshold) ? TaskExecutor.Synchronous : executor; }
internal SyntaxNode GetNodeWithTokens(SyntaxToken startToken, SyntaxToken endToken, SyntaxNode root) { if (IsEndOfFileToken(endToken)) { return root; } else { return startToken.GetCommonRoot(endToken); } }
private void SetInnermostNodeForSpan(SyntaxNode root, ref TextSpan span, out SyntaxToken token1, out SyntaxToken token2, out SyntaxNode commonNode) { commonNode = default(SyntaxNode); GetTokens(root, span, out token1, out token2); span = GetSpanFromTokens(span, token1, token2); if (token1.RawKind == 0 || token2.RawKind == 0) { return; } commonNode = token1.GetCommonRoot(token2); }