Пример #1
0
        private RenameLocationSet(ISymbol symbol, Solution solution, OptionSet optionSet, SearchResult originalSymbolResult, List<SearchResult> overloadsResult, IEnumerable<RenameLocation> stringsResult, IEnumerable<RenameLocation> commentsResult)
        {
            _symbol = symbol;
            _solution = solution;
            _optionSet = optionSet;
            _originalSymbolResult = originalSymbolResult;
            _overloadsResult = overloadsResult;
            _stringsResult = stringsResult;
            _commentsResult = commentsResult;

            var mergedLocations = new HashSet<RenameLocation>();
            var mergedReferencedSymbols = new List<ISymbol>();
            var mergedImplicitLocations = new List<ReferenceLocation>();

            if (optionSet.GetOption(RenameOptions.RenameInStrings))
            {
                mergedLocations.AddRange(stringsResult);
            }

            if (optionSet.GetOption(RenameOptions.RenameInComments))
            {
                mergedLocations.AddRange(commentsResult);
            }

            var overloadsToMerge = (optionSet.GetOption(RenameOptions.RenameOverloads) ? overloadsResult : null) ?? SpecializedCollections.EmptyEnumerable<SearchResult>();
            foreach (var result in overloadsToMerge.Concat(originalSymbolResult))
            {
                mergedLocations.AddRange(result.Locations);
                mergedImplicitLocations.AddRange(result.ImplicitLocations);
                mergedReferencedSymbols.AddRange(result.ReferencedSymbols);
            }

            _mergedResult = new SearchResult(mergedLocations, mergedImplicitLocations, mergedReferencedSymbols);
        }
Пример #2
0
        public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter(
            IEnumerable<IFormattingRule> formattingRules,
            CompilationUnitSyntax root,
            TextLine line,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(formattingRules);
            Contract.ThrowIfNull(root);

            if (!optionSet.GetOption(FeatureOnOffOptions.AutoFormattingOnReturn, LanguageNames.CSharp))
            {
                return false;
            }

            if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart)
            {
                return false;
            }

            var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition();
            if (!firstNonWhitespacePosition.HasValue)
            {
                return false;
            }

            var token = root.FindToken(firstNonWhitespacePosition.Value);
            if (token.IsKind(SyntaxKind.None) ||
                token.SpanStart != firstNonWhitespacePosition)
            {
                return false;
            }

            // first see whether there is a line operation for current token
            var previousToken = token.GetPreviousToken(includeZeroWidth: true);

            // only use smart token formatter when we have two visible tokens.
            if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing)
            {
                return false;
            }

            var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet);
            if (lineOperation == null || lineOperation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine)
            {
                // no indentation operation, nothing to do for smart token formatter
                return false;
            }

            // We're pressing enter between two tokens, have the formatter figure out hte appropriate
            // indentation.
            return true;
        }
            public async Task<IInlineRenameLocationSet> FindRenameLocationsAsync(OptionSet optionSet, CancellationToken cancellationToken)
            {
                var references = new List<InlineRenameLocation>();

                IList<DocumentSpan> renameLocations = await _renameInfo.FindRenameLocationsAsync(
                    renameInStrings: optionSet.GetOption(RenameOptions.RenameInStrings),
                    renameInComments: optionSet.GetOption(RenameOptions.RenameInComments),
                    cancellationToken: cancellationToken).ConfigureAwait(false);

                references.AddRange(renameLocations.Select(ds => new InlineRenameLocation(ds.Document, ds.TextSpan)));

                return new InlineRenameLocationSet(_renameInfo, _document.Project.Solution, references);
            }
        protected override Task<Tuple<ImmutableArray<ISymbol>, SyntaxContext>> GetRecommendedSymbolsAtPositionWorkerAsync(
            Workspace workspace, SemanticModel semanticModel, int position, OptionSet options, CancellationToken cancellationToken)
        {
            var context = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            var filterOutOfScopeLocals = options.GetOption(RecommendationOptions.FilterOutOfScopeLocals, semanticModel.Language);
            var symbols = GetSymbolsWorker(context, filterOutOfScopeLocals, cancellationToken);

            var hideAdvancedMembers = options.GetOption(RecommendationOptions.HideAdvancedMembers, semanticModel.Language);
            symbols = symbols.FilterToVisibleAndBrowsableSymbols(hideAdvancedMembers, semanticModel.Compilation);

            return Task.FromResult(Tuple.Create<ImmutableArray<ISymbol>, SyntaxContext>(symbols, context));
        }
Пример #5
0
        internal static bool IsTriggerCharacter(SourceText text, int characterPosition, OptionSet options)
        {
            var ch = text[characterPosition];
            if (ch == '.')
            {
                return true;
            }

            // Trigger for directive
            if (ch == '#')
            {
                return true;
            }

            // Trigger on pointer member access
            if (ch == '>' && characterPosition >= 1 && text[characterPosition - 1] == '-')
            {
                return true;
            }

            // Trigger on alias name
            if (ch == ':' && characterPosition >= 1 && text[characterPosition - 1] == ':')
            {
                return true;
            }

            if (options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp) && IsStartingNewWord(text, characterPosition))
            {
                return true;
            }

            return false;
        }
Пример #6
0
 internal static bool IsTriggerAfterSpaceOrStartOfWordCharacter(SourceText text, int characterPosition, OptionSet options)
 {
     // Bring up on space or at the start of a word.
     var ch = text[characterPosition];
     return SpaceTypedNotBeforeWord(ch, text, characterPosition) ||
         (IsStartingNewWord(text, characterPosition) && options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp));
 }
 internal override bool IsInsertionTrigger(SourceText text, int characterPosition, OptionSet options)
 {
     var ch = text[characterPosition];
     return ch == ' ' ||
         (CompletionUtilities.IsStartingNewWord(text, characterPosition) &&
         options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp));
 }
Пример #8
0
        public override bool IsTriggerCharacter(SourceText text, int characterPosition, OptionSet options)
        {
            if (!options.GetOption(CSharpCompletionOptions.IncludeSnippets))
            {
                return false;
            }

            return CompletionUtilities.IsTriggerCharacter(text, characterPosition, options);
        }
Пример #9
0
 public CheckBoxOptionViewModel(IOption option, string description, string truePreview, string falsePreview, AbstractOptionPreviewViewModel info, OptionSet options)
 {
     this.Option = option;
     Description = description;
     _truePreview = truePreview;
     _falsePreview = falsePreview;
     _info = info;
     SetProperty(ref _isChecked, (bool)options.GetOption(new OptionKey(option, option.IsPerLanguage ? info.Language : null)));
 }
        protected override bool SendEnterThroughToEditorCore(CompletionItem completionItem, string textTypedSoFar, OptionSet options)
        {
            // If the text doesn't match, no reason to even check the options
            if (completionItem.DisplayText != textTypedSoFar)
            {
                return false;
            }

            return options.GetOption(CSharpCompletionOptions.AddNewLineOnEnterAfterFullyTypedWord);
        }
Пример #11
0
        private OptionSet MergeOptions(OptionSet workspaceOptions, OptionSet userOptions)
        {
            var newOptions = workspaceOptions;
            foreach (var key in userOptions.GetChangedOptions(workspaceOptions))
            {
                newOptions = newOptions.WithChangedOption(key, userOptions.GetOption(key));
            }

            return newOptions;
        }
Пример #12
0
        public static void Log(OptionSet oldOptions, OptionSet newOptions)
        {
            foreach (var optionKey in newOptions.GetChangedOptions(oldOptions))
            {
                var oldValue = oldOptions.GetOption(optionKey);
                var currentValue = newOptions.GetOption(optionKey);

                Logger.Log(FunctionId.Run_Environment_Options, Create(optionKey, oldValue, currentValue));
            }
        }
Пример #13
0
        private protected override object GetOptionCore(OptionKey optionKey)
        {
            // First try to find the option from the .editorconfig options parsed by the compiler.
            if (_analyzerConfigOptions.TryGetEditorConfigOption <object>(optionKey.Option, out var value))
            {
                return(value);
            }

            // Fallback to looking for option from the document's optionset if unsuccessful.
            return(_optionSet?.GetOption(optionKey) ?? optionKey.Option.DefaultValue !);
        }
Пример #14
0
        public CheckBoxWithComboOptionViewModel(IOption option, string description, string truePreview, string falsePreview, AbstractOptionPreviewViewModel info, OptionSet options, IList<NotificationOptionViewModel> items)
            : base(option, description, truePreview, falsePreview, info)
        {
            NotificationOptions = items;

            var codeStyleOption = ((CodeStyleOption<bool>)options.GetOption(new OptionKey(option, option.IsPerLanguage ? info.Language : null)));
            SetProperty(ref _isChecked, codeStyleOption.Value);

            var notificationViewModel = items.Where(i => i.Notification.Value == codeStyleOption.Notification.Value).Single();
            SetProperty(ref _selectedNotificationOption, notificationViewModel);
        }
Пример #15
0
 internal override IEnumerable<OptionKey> GetChangedOptions(OptionSet optionSet)
 {
     foreach (var kvp in _values)
     {
         var currentValue = optionSet.GetOption(kvp.Key);
         if (!object.Equals(currentValue, kvp.Value))
         {
             yield return kvp.Key;
         }
     }
 }
        public override void AddSuppressOperations(List<SuppressOperation> list, SyntaxNode node, OptionSet optionSet, NextAction<SuppressOperation> nextOperation)
        {
            nextOperation.Invoke(list);

            AddBraceSuppressOperations(list, node);

            AddStatementExceptBlockSuppressOperations(list, node);

            AddSpecificNodesSuppressOperations(list, node);

            if (!optionSet.GetOption(CSharpFormattingOptions.WrappingPreserveSingleLine))
            {
                RemoveSuppressOperationForBlock(list, node);
            }

            if (!optionSet.GetOption(CSharpFormattingOptions.WrappingKeepStatementsOnSingleLine))
            {
                RemoveSuppressOperationForStatementMethodDeclaration(list, node);
            }
        }
        public static bool IsClosedFileDiagnosticsEnabled(OptionSet options, string language)
        {
            var option = options.GetOption(ClosedFileDiagnostic, language);
            if (!option.HasValue)
            {
                return language == LanguageNames.CSharp ?
                    CSharpClosedFileDiagnosticsEnabledByDefault :
                    DefaultClosedFileDiagnosticsEnabledByDefault;
            }

            return option.Value;
        }
Пример #18
0
        public static KeyValueLogMessage Create(
            OptionSet optionSet, UserActionOutcome outcome,
            bool conflictResolutionFinishedComputing, bool previewChanges,
            IList<InlineRenameReplacementKind> replacementKinds)
        {
            return KeyValueLogMessage.Create(m =>
            {
                m[RenameInComments] = optionSet.GetOption(RenameOptions.RenameInComments);
                m[RenameInStrings] = optionSet.GetOption(RenameOptions.RenameInStrings);
                m[RenameOverloads] = optionSet.GetOption(RenameOptions.RenameOverloads);

                m[Committed] = (outcome & UserActionOutcome.Committed) == UserActionOutcome.Committed;
                m[Canceled] = (outcome & UserActionOutcome.Canceled) == UserActionOutcome.Canceled;

                m[ConflictResolutionFinishedComputing] = conflictResolutionFinishedComputing;
                m[PreviewChanges] = previewChanges;

                m[RenamedIdentifiersWithoutConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.NoConflict);
                m[ResolvableReferenceConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.ResolvedReferenceConflict);
                m[ResolvableNonReferenceConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.ResolvedNonReferenceConflict);
                m[UnresolvableConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.UnresolvedConflict);
            });
        }
 public override bool IsTriggerCharacter(SourceText text, int characterPosition, OptionSet options)
 {
     // Bring up on space or at the start of a word, or after a ( or [.
     //
     // Note: we don't want to bring this up after traditional enum operators like & or |.
     // That's because we don't like the experience where the enum appears directly after the
     // operator.  Instead, the user normally types <space> and we will bring up the list
     // then.
     var ch = text[characterPosition];
     return
         ch == ' ' ||
         ch == '[' ||
         ch == '(' ||
         (options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp) && CompletionUtilities.IsStartingNewWord(text, characterPosition));
 }
Пример #20
0
        protected override SyntaxNode InsertNamespaceImport(SyntaxNode root, SyntaxGenerator gen, SyntaxNode import, OptionSet options)
        {
            var comparer = options.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.CSharp)
                    ? UsingsAndExternAliasesDirectiveComparer.SystemFirstInstance
                    : UsingsAndExternAliasesDirectiveComparer.NormalInstance;

            // find insertion point
            foreach (var existingImport in gen.GetNamespaceImports(root))
            {
                if (comparer.Compare(import, existingImport) < 0)
                {
                    return gen.InsertNodesBefore(root, existingImport, new[] { import });
                }
            }

            return gen.AddNamespaceImports(root, import);
        }
        public BooleanCodeStyleOptionViewModel(
            IOption option, 
            string description, 
            string truePreview, 
            string falsePreview, 
            AbstractOptionPreviewViewModel info, 
            OptionSet options, 
            string groupName, 
            List<CodeStylePreference> preferences = null, 
            List<NotificationOptionViewModel> notificationPreferences = null) 
            : base(option, description, truePreview, falsePreview, info, options, groupName, preferences, notificationPreferences)
        {
            var booleanOption = (bool)options.GetOption(new OptionKey(option, option.IsPerLanguage ? info.Language : null));
            _selectedPreference = Preferences.Single(c => c.IsChecked == booleanOption);

            NotifyPropertyChanged(nameof(SelectedPreference));
        }
Пример #22
0
        private RenameLocations(
            SymbolAndProjectId symbolAndProjectId,
            Solution solution,
            OptionSet options,
            SearchResult originalSymbolResult,
            List<SearchResult> overloadsResult,
            IEnumerable<RenameLocation> stringsResult,
            IEnumerable<RenameLocation> commentsResult)
        {
            _symbolAndProjectId = symbolAndProjectId;
            _solution = solution;
            Options = options;
            _originalSymbolResult = originalSymbolResult;
            _overloadsResult = overloadsResult;
            _stringsResult = stringsResult;
            _commentsResult = commentsResult;

            var mergedLocations = new HashSet<RenameLocation>();
            var mergedReferencedSymbols = new List<SymbolAndProjectId>();
            var mergedImplicitLocations = new List<ReferenceLocation>();

            if (options.GetOption(RenameOptions.RenameInStrings))
            {
                mergedLocations.AddRange(stringsResult);
            }

            if (options.GetOption(RenameOptions.RenameInComments))
            {
                mergedLocations.AddRange(commentsResult);
            }

            var renameMethodGroupReferences = 
                options.GetOption(RenameOptions.RenameOverloads) || !GetOverloadedSymbols(symbolAndProjectId).Any();
            var overloadsToMerge = (options.GetOption(RenameOptions.RenameOverloads) ? overloadsResult : null) ?? SpecializedCollections.EmptyEnumerable<SearchResult>();
            foreach (var result in overloadsToMerge.Concat(originalSymbolResult))
            {
                mergedLocations.AddRange(renameMethodGroupReferences
                    ? result.Locations
                    : result.Locations.Where(x => !x.IsMethodGroupReference));

                mergedImplicitLocations.AddRange(result.ImplicitLocations);
                mergedReferencedSymbols.AddRange(result.ReferencedSymbols);
            }

            _mergedResult = new SearchResult(mergedLocations, mergedImplicitLocations, mergedReferencedSymbols);
        }
        public override void AddIndentBlockOperations(List<IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet, NextAction<IndentBlockOperation> nextOperation)
        {
            nextOperation.Invoke(list);

            var bracePair = node.GetBracePair();

            // don't put block indentation operation if the block only contains lambda expression body block
            if (node.IsLambdaBodyBlock() || !bracePair.IsValidBracePair())
            {
                return;
            }

            if (optionSet.GetOption(CSharpFormattingOptions.OpenCloseBracesIndent))
            {
                AddIndentBlockOperation(list, bracePair.Item1, bracePair.Item1, bracePair.Item1.Span);
                AddIndentBlockOperation(list, bracePair.Item2, bracePair.Item2, bracePair.Item2.Span);
            }
        }
        public IFormattingResult Format(SyntaxNode node, IEnumerable<TextSpan> spans, OptionSet options, IEnumerable<IFormattingRule> rules, CancellationToken cancellationToken)
        {
            CheckArguments(node, spans, options, rules);

            // quick exit check
            var spansToFormat = new NormalizedTextSpanCollection(spans.Where(NotEmpty));
            if (spansToFormat.Count == 0)
            {
                return CreateAggregatedFormattingResult(node, SpecializedCollections.EmptyList<AbstractFormattingResult>());
            }

            // check what kind of formatting strategy to use
            if (AllowDisjointSpanMerging(spansToFormat, options.GetOption(FormattingOptions.AllowDisjointSpanMerging)))
            {
                return FormatMergedSpan(node, options, rules, spansToFormat, cancellationToken);
            }

            return FormatIndividually(node, options, rules, spansToFormat, cancellationToken);
        }
        public SimpleCodeStyleOptionViewModel(
            IOption option,
            string description,
            string truePreview,
            string falsePreview,
            AbstractOptionPreviewViewModel info,
            OptionSet options,
            string groupName,
            List<CodeStylePreference> preferences = null,
            List<NotificationOptionViewModel> notificationPreferences = null)
            : base(option, description, truePreview, falsePreview, info, options, groupName, preferences, notificationPreferences)
        {
            var codeStyleOption = ((CodeStyleOption<bool>)options.GetOption(new OptionKey(option, option.IsPerLanguage ? info.Language : null)));
            _selectedPreference = Preferences.Single(c => c.IsChecked == codeStyleOption.Value);

            var notificationViewModel = NotificationPreferences.Single(i => i.Notification.Value == codeStyleOption.Notification.Value);
            _selectedNotificationPreference = NotificationPreferences.Single(p => p.Notification.Value == notificationViewModel.Notification.Value);

            NotifyPropertyChanged(nameof(SelectedPreference));
            NotifyPropertyChanged(nameof(SelectedNotificationPreference));
        }
Пример #26
0
        private void AddSwitchIndentationOperation(List<IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet)
        {
            var section = node as SwitchSectionSyntax;
            if (section == null || !optionSet.GetOption(CSharpFormattingOptions.IndentSwitchCaseSection))
            {
                return;
            }

            // can this ever happen?
            if (section.Labels.Count == 0 &&
                section.Statements.Count == 0)
            {
                return;
            }

            // see whether we are the last statement
            var switchStatement = node.Parent as SwitchStatementSyntax;
            var lastSection = switchStatement.Sections.Last() == node;

            if (section.Statements.Count == 0)
            {
                // even if there is no statement under section, we still want indent operation
                var lastTokenOfLabel = section.Labels.Last().GetLastToken(includeZeroWidth: true);
                var nextToken = lastTokenOfLabel.GetNextToken(includeZeroWidth: true);

                AddIndentBlockOperation(list, lastTokenOfLabel, lastTokenOfLabel,
                    lastSection ?
                        TextSpan.FromBounds(lastTokenOfLabel.FullSpan.End, nextToken.SpanStart) : TextSpan.FromBounds(lastTokenOfLabel.FullSpan.End, lastTokenOfLabel.FullSpan.End));
                return;
            }

            var startToken = section.Statements.First().GetFirstToken(includeZeroWidth: true);
            var endToken = section.Statements.Last().GetLastToken(includeZeroWidth: true);

            // see whether we are the last statement
            var span = CommonFormattingHelpers.GetSpanIncludingTrailingAndLeadingTriviaOfAdjacentTokens(startToken, endToken);
            span = lastSection ? span : TextSpan.FromBounds(span.Start, endToken.FullSpan.End);

            AddIndentBlockOperation(list, startToken, endToken, span);
        }
Пример #27
0
        public async Task<Document> AddImportsAsync(
            Document document, IEnumerable<TextSpan> spans,
            OptionSet options, CancellationToken cancellationToken)
        {
            options = options ?? await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            // Create a simple interval tree for simplification spans.
            var spansTree = new SimpleIntervalTree<TextSpan>(TextSpanIntervalIntrospector.Instance, spans);

            Func<SyntaxNodeOrToken, bool> isInSpan = nodeOrToken =>
                spansTree.GetOverlappingIntervals(nodeOrToken.FullSpan.Start, nodeOrToken.FullSpan.Length).Any();

            var nodesWithExplicitNamespaces = root.DescendantNodesAndSelf().Where(n => isInSpan(n) && GetExplicitNamespaceSymbol(n, model) != null).ToList();

            var namespacesToAdd = new HashSet<INamespaceSymbol>();
            namespacesToAdd.AddRange(nodesWithExplicitNamespaces.Select(
                n => GetExplicitNamespaceSymbol(n, model)));

            var generator = SyntaxGenerator.GetGenerator(document);
            var imports = namespacesToAdd.Select(ns => generator.NamespaceImportDeclaration(ns.ToDisplayString()).WithAdditionalAnnotations(Simplifier.Annotation))
                                         .ToArray();

            // annotate these nodes so they get simplified later
            var newRoot = root.ReplaceNodes(
                nodesWithExplicitNamespaces,
                (o, r) => r.WithAdditionalAnnotations(Simplifier.Annotation));

            var placeSystemNamespaceFirst = options.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, document.Project.Language);
            var addImportsService = document.GetLanguageService<IAddImportsService>();
            var finalRoot = addImportsService.AddImports(
                model.Compilation, newRoot, newRoot, imports, placeSystemNamespaceFirst);

            return document.WithSyntaxRoot(finalRoot);
        }
 private static bool PreferLiveErrorsOnOpenedFiles(OptionSet options)
 => options.GetOption(InternalDiagnosticsOptions.PreferLiveErrorsOnOpenedFiles);
Пример #29
0
        public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustSpacesOperation> nextOperation)
        {
            if (optionSet == null)
            {
                return(nextOperation.Invoke());
            }

            System.Diagnostics.Debug.Assert(previousToken.Parent != null && currentToken.Parent != null);

            var previousKind       = previousToken.Kind();
            var currentKind        = currentToken.Kind();
            var previousParentKind = previousToken.Parent.Kind();
            var currentParentKind  = currentToken.Parent.Kind();

            // For Method Declaration
            if (currentToken.IsOpenParenInParameterList() && previousKind == SyntaxKind.IdentifierToken)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            // For Generic Method Declaration
            if (currentToken.IsOpenParenInParameterList() && previousKind == SyntaxKind.GreaterThanToken && previousParentKind == SyntaxKind.TypeParameterList)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            // Case: public static implicit operator string(Program p) { return null; }
            if (previousToken.IsKeyword() && currentToken.IsOpenParenInParameterListOfAConversionOperatorDeclaration())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            // Case: public static Program operator !(Program p) { return null; }
            if (previousToken.Parent.IsKind(SyntaxKind.OperatorDeclaration) && currentToken.IsOpenParenInParameterListOfAOperationDeclaration())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            if (previousToken.IsOpenParenInParameterList() && currentToken.IsCloseParenInParameterList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBetweenEmptyMethodDeclarationParentheses));
            }

            if (previousToken.IsOpenParenInParameterList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodDeclarationParenthesis));
            }

            if (currentToken.IsCloseParenInParameterList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodDeclarationParenthesis));
            }

            // For Method Call
            if (currentToken.IsOpenParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterMethodCallName));
            }

            if (previousToken.IsOpenParenInArgumentList() && currentToken.IsCloseParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBetweenEmptyMethodCallParentheses));
            }

            if (previousToken.IsOpenParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            if (currentToken.IsCloseParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            // For spacing around: typeof, default, and sizeof; treat like a Method Call
            if (currentKind == SyntaxKind.OpenParenToken && IsFunctionLikeKeywordExpressionKind(currentParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterMethodCallName));
            }

            if (previousKind == SyntaxKind.OpenParenToken && IsFunctionLikeKeywordExpressionKind(previousParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            if (currentKind == SyntaxKind.CloseParenToken && IsFunctionLikeKeywordExpressionKind(currentParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            // For Spacing b/n control flow keyword and paren. Parent check not needed.
            if (currentKind == SyntaxKind.OpenParenToken &&
                (previousKind == SyntaxKind.IfKeyword || previousKind == SyntaxKind.WhileKeyword || previousKind == SyntaxKind.SwitchKeyword ||
                 previousKind == SyntaxKind.ForKeyword || previousKind == SyntaxKind.ForEachKeyword || previousKind == SyntaxKind.CatchKeyword ||
                 previousKind == SyntaxKind.UsingKeyword || previousKind == SyntaxKind.WhenKeyword))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterControlFlowStatementKeyword));
            }

            // For spacing between parenthesis and expression
            if ((previousParentKind == SyntaxKind.ParenthesizedExpression && previousKind == SyntaxKind.OpenParenToken) ||
                (currentParentKind == SyntaxKind.ParenthesizedExpression && currentKind == SyntaxKind.CloseParenToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinExpressionParentheses));
            }

            // For spacing between the parenthesis and the cast expression
            if ((previousParentKind == SyntaxKind.CastExpression && previousKind == SyntaxKind.OpenParenToken) ||
                (currentParentKind == SyntaxKind.CastExpression && currentKind == SyntaxKind.CloseParenToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinCastParentheses));
            }

            // For spacing between the parenthesis and the expression inside the control flow expression
            if (previousKind == SyntaxKind.OpenParenToken && IsControlFlowLikeKeywordStatementKind(previousParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinOtherParentheses));
            }

            // Semicolons in an empty for statement.  i.e.   for(;;)
            if (previousKind == SyntaxKind.OpenParenToken || previousKind == SyntaxKind.SemicolonToken)
            {
                if (previousToken.Parent.Kind() == SyntaxKind.ForStatement)
                {
                    var forStatement = (ForStatementSyntax)previousToken.Parent;
                    if (forStatement.Initializers.Count == 0 &&
                        forStatement.Declaration == null &&
                        forStatement.Condition == null &&
                        forStatement.Incrementors.Count == 0)
                    {
                        return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
                    }
                }
            }

            if (currentKind == SyntaxKind.CloseParenToken && IsControlFlowLikeKeywordStatementKind(currentParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinOtherParentheses));
            }

            // For spacing after the cast
            if (previousParentKind == SyntaxKind.CastExpression && previousKind == SyntaxKind.CloseParenToken)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterCast));
            }

            // For spacing Before Square Braces
            if (currentKind == SyntaxKind.OpenBracketToken && HasFormattableBracketParent(currentToken) && !previousToken.IsOpenBraceOrCommaOfObjectInitializer())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeOpenSquareBracket));
            }

            // For spacing empty square braces, also treat [,] as empty
            if (((currentKind == SyntaxKind.CloseBracketToken && previousKind == SyntaxKind.OpenBracketToken) ||
                 currentKind == SyntaxKind.OmittedArraySizeExpressionToken) &&
                HasFormattableBracketParent(previousToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBetweenEmptySquareBrackets));
            }

            // For spacing square brackets within
            if (previousKind == SyntaxKind.OpenBracketToken && HasFormattableBracketParent(previousToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinSquareBrackets));
            }

            if (currentKind == SyntaxKind.CloseBracketToken && previousKind != SyntaxKind.OmittedArraySizeExpressionToken && HasFormattableBracketParent(currentToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinSquareBrackets));
            }

            // For spacing delimiters - after colon
            if (previousToken.IsColonInTypeBaseList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterColonInBaseTypeDeclaration));
            }

            // For spacing delimiters - before colon
            if (currentToken.IsColonInTypeBaseList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeColonInBaseTypeDeclaration));
            }

            // For spacing delimiters - after comma
            if ((previousToken.IsCommaInArgumentOrParameterList() && currentKind != SyntaxKind.OmittedTypeArgumentToken) ||
                previousToken.IsCommaInInitializerExpression() ||
                (previousKind == SyntaxKind.CommaToken &&
                 currentKind != SyntaxKind.OmittedArraySizeExpressionToken &&
                 HasFormattableBracketParent(previousToken)))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterComma));
            }

            // For spacing delimiters - before comma
            if ((currentToken.IsCommaInArgumentOrParameterList() && previousKind != SyntaxKind.OmittedTypeArgumentToken) ||
                currentToken.IsCommaInInitializerExpression() ||
                (currentKind == SyntaxKind.CommaToken &&
                 previousKind != SyntaxKind.OmittedArraySizeExpressionToken &&
                 HasFormattableBracketParent(currentToken)))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeComma));
            }

            // For Spacing delimiters - after Dot
            if (previousToken.IsDotInMemberAccessOrQualifiedName())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterDot));
            }

            // For spacing delimiters - before Dot
            if (currentToken.IsDotInMemberAccessOrQualifiedName())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeDot));
            }

            // For spacing delimiters - after semicolon
            if (previousToken.IsSemicolonInForStatement() && currentKind != SyntaxKind.CloseParenToken)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterSemicolonsInForStatement));
            }

            // For spacing delimiters - before semicolon
            if (currentToken.IsSemicolonInForStatement())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement));
            }

            // For spacing around the binary operators
            if (currentToken.Parent is BinaryExpressionSyntax ||
                previousToken.Parent is BinaryExpressionSyntax ||
                currentToken.Parent is AssignmentExpressionSyntax ||
                previousToken.Parent is AssignmentExpressionSyntax)
            {
                switch (optionSet.GetOption(CSharpFormattingOptions.SpacingAroundBinaryOperator))
                {
                case BinaryOperatorSpacingOptions.Single:
                    return(CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine));

                case BinaryOperatorSpacingOptions.Remove:
                    if (currentKind == SyntaxKind.IsKeyword ||
                        currentKind == SyntaxKind.AsKeyword ||
                        previousKind == SyntaxKind.IsKeyword ||
                        previousKind == SyntaxKind.AsKeyword)
                    {
                        // User want spaces removed but at least one is required for the "as" & "is" keyword
                        return(CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine));
                    }
                    else
                    {
                        return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpacesIfOnSingleLine));
                    }

                case BinaryOperatorSpacingOptions.Ignore:
                    return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.PreserveSpaces));

                default:
                    System.Diagnostics.Debug.Assert(false, "Invalid BinaryOperatorSpacingOptions");
                    break;
                }
            }

            // No space after $" and $@" at the start of an interpolated string
            if (previousKind == SyntaxKind.InterpolatedStringStartToken ||
                previousKind == SyntaxKind.InterpolatedVerbatimStringStartToken)
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // No space before " at the end of an interpolated string
            if (currentKind == SyntaxKind.InterpolatedStringEndToken)
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // No space before { or after } in interpolations
            if ((currentKind == SyntaxKind.OpenBraceToken && currentToken.Parent is InterpolationSyntax) ||
                (previousKind == SyntaxKind.CloseBraceToken && previousToken.Parent is InterpolationSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // Preserve space after { or before } in interpolations (i.e. between the braces and the expression)
            if ((previousKind == SyntaxKind.OpenBraceToken && previousToken.Parent is InterpolationSyntax) ||
                (currentKind == SyntaxKind.CloseBraceToken && currentToken.Parent is InterpolationSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.PreserveSpaces));
            }

            // No space before or after , in interpolation alignment clause
            if ((previousKind == SyntaxKind.CommaToken && previousToken.Parent is InterpolationAlignmentClauseSyntax) ||
                (currentKind == SyntaxKind.CommaToken && currentToken.Parent is InterpolationAlignmentClauseSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // No space before or after : in interpolation format clause
            if ((previousKind == SyntaxKind.ColonToken && previousToken.Parent is InterpolationFormatClauseSyntax) ||
                (currentKind == SyntaxKind.ColonToken && currentToken.Parent is InterpolationFormatClauseSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            return(nextOperation.Invoke());
        }
Пример #30
0
 public T GetOption <T>(PerLanguageOption2 <T> option, string language) =>
 _options.GetOption(option, language);
 public static OmniSharpImplementTypePropertyGenerationBehavior GetPropertyGenerationBehavior(OptionSet options, string language)
 => (OmniSharpImplementTypePropertyGenerationBehavior)options.GetOption(ImplementTypeOptions.Metadata.PropertyGenerationBehavior, language);
        private Task <ImmutableArray <ISymbol> > GetSymbolsCoreAsync(
            SyntaxContext context, int position, OptionSet options, bool preselect, CancellationToken cancellationToken)
        {
            var newExpression = GetObjectCreationNewExpression(context.SyntaxTree, position, cancellationToken);

            if (newExpression == null)
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            var typeInferenceService = context.GetLanguageService <ITypeInferenceService>();
            var type = typeInferenceService.InferType(
                context.SemanticModel, position, objectAsDefault: false, cancellationToken: cancellationToken);

            // Unwrap an array type fully.  We only want to offer the underlying element type in the
            // list of completion items.
            var isArray = false;

            while (type is IArrayTypeSymbol)
            {
                isArray = true;
                type    = ((IArrayTypeSymbol)type).ElementType;
            }

            if (type == null ||
                (isArray && preselect))
            {
                // In the case of array creation, we don't offer a preselected/hard-selected item because
                // the user may want an implicitly-typed array creation

                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            // Unwrap nullable
            if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
            {
                type = type.GetTypeArguments().FirstOrDefault();
            }

            if (type.SpecialType == SpecialType.System_Void)
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            if (type.ContainsAnonymousType())
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            if (!type.CanBeReferencedByName)
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            // Normally the user can't say things like "new IList".  Except for "IList[] x = new |".
            // In this case we do want to allow them to preselect certain types in the completion
            // list even if they can't new them directly.
            if (!isArray)
            {
                if (type.TypeKind == TypeKind.Interface ||
                    type.TypeKind == TypeKind.Pointer ||
                    type.TypeKind == TypeKind.Dynamic ||
                    type.IsAbstract)
                {
                    return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
                }

                if (type.TypeKind == TypeKind.TypeParameter &&
                    !((ITypeParameterSymbol)type).HasConstructorConstraint)
                {
                    return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
                }
            }

            if (!type.IsEditorBrowsable(options.GetOption(RecommendationOptions.HideAdvancedMembers, context.SemanticModel.Language), context.SemanticModel.Compilation))
            {
                return(SpecializedTasks.EmptyImmutableArray <ISymbol>());
            }

            return(Task.FromResult(ImmutableArray.Create((ISymbol)type)));
        }
Пример #33
0
        public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation)
        {
            var operation = nextOperation.Invoke();

            // else condition is actually handled in the GetAdjustSpacesOperation()

            // For Object Initialization Expression
            if (previousToken.Kind() == SyntaxKind.CommaToken && previousToken.Parent.Kind() == SyntaxKind.ObjectInitializerExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForMembersInObjectInit))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    // we never force it to move up unless it is already on same line
                    return(CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines));
                }
            }

            // For Anonymous Object Creation Expression
            if (previousToken.Kind() == SyntaxKind.CommaToken && previousToken.Parent.Kind() == SyntaxKind.AnonymousObjectCreationExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForMembersInAnonymousTypes))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    // we never force it to move up unless it is already on same line
                    return(CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines));
                }
            }

            // } else in the if else context
            if (previousToken.IsKind(SyntaxKind.CloseBraceToken) && currentToken.IsKind(SyntaxKind.ElseKeyword))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForElse))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * catch in the try catch context
            if (currentToken.Kind() == SyntaxKind.CatchKeyword)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForCatch))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * Finally
            if (currentToken.Kind() == SyntaxKind.FinallyKeyword)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForFinally))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the type declaration context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && (currentToken.Parent is BaseTypeDeclarationSyntax || currentToken.Parent is NamespaceDeclarationSyntax))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInTypes))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // new { - Anonymous object creation
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null && currentToken.Parent.Kind() == SyntaxKind.AnonymousObjectCreationExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // new { - Object Initialization
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null && currentToken.Parent.Kind() == SyntaxKind.ObjectInitializerExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectInitializers))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            var currentTokenParentParent = currentToken.Parent.Parent;

            // * { - in the member declaration context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken &&
                currentTokenParentParent != null && (currentTokenParentParent is MemberDeclarationSyntax || currentTokenParentParent is AccessorDeclarationSyntax))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInMethods))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the anonymous Method context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null && currentTokenParentParent.Kind() == SyntaxKind.AnonymousMethodExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLinesIfOnSingleLine));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the simple Lambda context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null &&
                (currentTokenParentParent.Kind() == SyntaxKind.SimpleLambdaExpression || currentTokenParentParent.Kind() == SyntaxKind.ParenthesizedLambdaExpression))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLinesIfOnSingleLine));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the control statement context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && IsControlBlock(currentToken.Parent))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // Wrapping - Leave statements on same line (false):
            // Insert a newline between the previous statement and this one.
            // ; *
            if (previousToken.Kind() == SyntaxKind.SemicolonToken &&
                (previousToken.Parent is StatementSyntax && !previousToken.Parent.IsKind(SyntaxKind.ForStatement)) &&
                !optionSet.GetOption(CSharpFormattingOptions.WrappingKeepStatementsOnSingleLine))
            {
                return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
            }

            return(operation);
        }
Пример #34
0
        /// <inheritdoc />
        public void Push(char ch)
        {
            // append this char to the wordbuf if it can form a valid keyword, otherwise check
            // if the last sequence of chars form a valid keyword and reset the wordbuf.
            if ((wordToken.Length == 0 ? char.IsLetter(ch) : char.IsLetterOrDigit(ch)) || ch == '_')
            {
                wordToken.Append(ch);
            }
            else if (wordToken.Length > 0)
            {
                currentState.CheckKeyword(wordToken.ToString());
                previousKeyword            = wordToken.ToString();
                wordToken.Length           = 0;
                isLineStartBeforeWordToken = false;
            }

            var isNewLine = NewLine.IsNewLine(ch);

            if (!isNewLine)
            {
                currentState.Push(currentChar = ch);
                offset++;
                previousNewline = '\0';
                // ignore whitespace and newline chars
                var isWhitespace = currentChar == ' ' || currentChar == '\t';
                if (!isWhitespace)
                {
                    previousChar = currentChar;
                    isLineStart  = false;
                }

                if (isLineStart)
                {
                    currentIndent.Append(ch);
                }

                if (ch == '\t')
                {
                    var indentSize  = options.GetOption(FormattingOptions.IndentationSize, LanguageNames.CSharp);
                    var nextTabStop = (column - 1 + indentSize) / indentSize;
                    column = 1 + nextTabStop * indentSize;
                }
                else
                {
                    column++;
                }
            }
            else
            {
                if (ch == NewLine.LF && previousNewline == NewLine.CR)
                {
                    offset++;
                    return;
                }
                currentState.Push(currentChar = newLineChar);
                offset++;

                previousNewline = ch;
                // there can be more than one chars that determine the EOL,
                // the engine uses only one of them defined with newLineChar
                if (currentChar != newLineChar)
                {
                    return;
                }
                currentIndent.Length       = 0;
                isLineStart                = true;
                isLineStartBeforeWordToken = true;
                column = 1;
                line++;

                lineBeganInsideMultiLineComment = IsInsideMultiLineComment;
                lineBeganInsideVerbatimString   = IsInsideVerbatimString;
            }
        }
Пример #35
0
 internal static object GetOptionOrDefault(OptionSet options, IOption option, string language)
 {
     return(options.GetOption(new OptionKey(option, option.IsPerLanguage ? language : null)) ?? option.DefaultValue);
 }
Пример #36
0
        private bool IsFrameworkTypePreferred(OptionSet optionSet, PerLanguageOption <CodeStyleOption <bool> > option, string language)
        {
            var optionValue = optionSet.GetOption(option, language);

            return(OptionSettingPrefersFrameworkType(optionValue, optionValue.Notification.Value));
        }
        public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation<AdjustNewLinesOperation> nextOperation)
        {
            var operation = nextOperation.Invoke();

            // else condition is actually handled in the GetAdjustSpacesOperation()

            // For Object Initialization Expression
            if (previousToken.CSharpKind() == SyntaxKind.CommaToken && previousToken.Parent.CSharpKind() == SyntaxKind.ObjectInitializerExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForMembersInObjectInit))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    // we never force it to move up unless it is already on same line
                    return CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines);
                }
            }

            // For Anonymous Object Creation Expression
            if (previousToken.CSharpKind() == SyntaxKind.CommaToken && previousToken.Parent.CSharpKind() == SyntaxKind.AnonymousObjectCreationExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForMembersInAnonymousTypes))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    // we never force it to move up unless it is already on same line
                    return CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines);
                }
            }

            // } else in the if else context
            if (previousToken.IsKind(SyntaxKind.CloseBraceToken) && currentToken.IsKind(SyntaxKind.ElseKeyword))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForElse))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // * catch in the try catch context
            if (currentToken.CSharpKind() == SyntaxKind.CatchKeyword)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForCatch))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // * Finally
            if (currentToken.CSharpKind() == SyntaxKind.FinallyKeyword)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForFinally))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // * { - in the type declaration context
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && (currentToken.Parent is BaseTypeDeclarationSyntax || currentToken.Parent is NamespaceDeclarationSyntax))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForTypes))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // new { - Anonymous object creation
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null && currentToken.Parent.CSharpKind() == SyntaxKind.AnonymousObjectCreationExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForAnonymousType))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // new { - Object Initialization
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null && currentToken.Parent.CSharpKind() == SyntaxKind.ObjectInitializerExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForObjectInitializers))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            var currentTokenParentParent = currentToken.Parent.Parent;

            // * { - in the member declaration context
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken &&
                currentTokenParentParent != null && (currentTokenParentParent is MemberDeclarationSyntax || currentTokenParentParent is AccessorDeclarationSyntax))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForMethods))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // * { - in the anonymous Method context
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null && currentTokenParentParent.CSharpKind() == SyntaxKind.AnonymousMethodExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForAnonymousMethods))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // * { - in the simple Lambda context
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null &&
               (currentTokenParentParent.CSharpKind() == SyntaxKind.SimpleLambdaExpression || currentTokenParentParent.CSharpKind() == SyntaxKind.ParenthesizedLambdaExpression))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForLambda))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceIfSameLine);
                }
                else
                {
                    return null;
                }
            }

            // * { - in the control statement context
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && IsControlBlock(currentToken.Parent))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForControl))
                {
                    return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
                }
                else
                {
                    return null;
                }
            }

            // Wrapping - Leave statements on same line (false): 
            // Insert a newline between the previous statement and this one.
            // ; *
            if (previousToken.CSharpKind() == SyntaxKind.SemicolonToken
                && previousToken.Parent is StatementSyntax
                && !optionSet.GetOption(CSharpFormattingOptions.LeaveStatementMethodDeclarationSameLine))
            {
                return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines);
            }

            return operation;
        }
        public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation)
        {
            var operation = nextOperation.Invoke();

            // else condition is actually handled in the GetAdjustSpacesOperation()

            // For Object Initialization Expression
            if (previousToken.Kind() == SyntaxKind.CommaToken && previousToken.Parent.Kind() == SyntaxKind.ObjectInitializerExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForMembersInObjectInit))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    // we never force it to move up unless it is already on same line
                    return(CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines));
                }
            }

            // For Anonymous Object Creation Expression
            if (previousToken.Kind() == SyntaxKind.CommaToken && previousToken.Parent.Kind() == SyntaxKind.AnonymousObjectCreationExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForMembersInAnonymousTypes))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    // we never force it to move up unless it is already on same line
                    return(CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines));
                }
            }

            // } else in the if else context
            if (previousToken.IsKind(SyntaxKind.CloseBraceToken) && currentToken.IsKind(SyntaxKind.ElseKeyword))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForElse))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * catch in the try catch context
            if (currentToken.Kind() == SyntaxKind.CatchKeyword)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForCatch))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * Finally
            if (currentToken.Kind() == SyntaxKind.FinallyKeyword)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLineForFinally))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the type declaration context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && (currentToken.Parent is BaseTypeDeclarationSyntax || currentToken.Parent is NamespaceDeclarationSyntax))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInTypes))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // new { - Anonymous object creation
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null && currentToken.Parent.Kind() == SyntaxKind.AnonymousObjectCreationExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // new MyObject { - Object Initialization
            // new List<int> { - Collection Initialization
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null &&
                (currentToken.Parent.Kind() == SyntaxKind.ObjectInitializerExpression ||
                 currentToken.Parent.Kind() == SyntaxKind.CollectionInitializerExpression))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // Array Initialization Expression
            // int[] arr = new int[] {
            //             new[] {
            //             { - Implicit Array
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null &&
                (currentToken.Parent.Kind() == SyntaxKind.ArrayInitializerExpression ||
                 currentToken.Parent.Kind() == SyntaxKind.ImplicitArrayCreationExpression))
            {
                return(null);
            }

            var currentTokenParentParent = currentToken.Parent.Parent;

            // * { - in the member declaration context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null && currentTokenParentParent is MemberDeclarationSyntax)
            {
                var option = currentTokenParentParent is BasePropertyDeclarationSyntax
                    ? CSharpFormattingOptions.NewLinesForBracesInProperties
                    : CSharpFormattingOptions.NewLinesForBracesInMethods;

                if (optionSet.GetOption(option))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the property accessor context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null && currentTokenParentParent is AccessorDeclarationSyntax)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAccessors))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the anonymous Method context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null && currentTokenParentParent.Kind() == SyntaxKind.AnonymousMethodExpression)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLinesIfOnSingleLine));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the local function context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null && currentTokenParentParent.Kind() == SyntaxKind.LocalFunctionStatement)
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInMethods))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the simple Lambda context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null &&
                (currentTokenParentParent.Kind() == SyntaxKind.SimpleLambdaExpression || currentTokenParentParent.Kind() == SyntaxKind.ParenthesizedLambdaExpression))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLinesIfOnSingleLine));
                }
                else
                {
                    return(null);
                }
            }

            // * { - in the control statement context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && IsControlBlock(currentToken.Parent))
            {
                if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks))
                {
                    return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines));
                }
                else
                {
                    return(null);
                }
            }

            return(operation);
        }
Пример #39
0
        internal override bool IsInsertionTrigger(SourceText text, int characterPosition, OptionSet options)
        {
            var ch = text[characterPosition];

            return(ch == ' ' || (CompletionUtilities.IsStartingNewWord(text, characterPosition) && options.GetOption(CompletionOptions.TriggerOnTypingLetters, LanguageNames.CSharp)));
        }
 private static bool PreferBuildErrors(OptionSet options)
 => options.GetOption(InternalDiagnosticsOptions.PreferBuildErrorsOverLiveErrors);
Пример #41
0
        public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet options, CancellationToken cancellationToken)
        {
            if (project == null || symbol == null)
            {
                return(false);
            }

            options = options ?? project.Solution.Workspace.Options;
            symbol  = symbol.OriginalDefinition;

            // Prefer visible source locations if possible.
            var sourceLocations        = symbol.Locations.Where(loc => loc.IsInSource);
            var visibleSourceLocations = sourceLocations.Where(loc => loc.IsVisibleSourceLocation());
            var sourceLocation         = visibleSourceLocations.FirstOrDefault() ?? sourceLocations.FirstOrDefault();

            if (sourceLocation != null)
            {
                var targetDocument = project.Solution.GetDocument(sourceLocation.SourceTree);
                if (targetDocument != null)
                {
                    var editorWorkspace   = targetDocument.Project.Solution.Workspace;
                    var navigationService = editorWorkspace.Services.GetService <IDocumentNavigationService>();
                    return(navigationService.TryNavigateToSpan(editorWorkspace, targetDocument.Id, sourceLocation.SourceSpan, options));
                }
            }

            // We don't have a source document, so show the Metadata as Source view in a preview tab.

            var metadataLocation = symbol.Locations.Where(loc => loc.IsInMetadata).FirstOrDefault();

            if (metadataLocation == null || !_metadataAsSourceFileService.IsNavigableMetadataSymbol(symbol))
            {
                return(false);
            }

            // Should we prefer navigating to the Object Browser over metadata-as-source?
            if (options.GetOption(VisualStudioNavigationOptions.NavigateToObjectBrowser, project.Language))
            {
                var libraryService = project.LanguageServices.GetService <ILibraryService>();
                if (libraryService == null)
                {
                    return(false);
                }

                var compilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken);
                var navInfo     = libraryService.NavInfoFactory.CreateForSymbol(symbol, project, compilation);
                if (navInfo == null)
                {
                    navInfo = libraryService.NavInfoFactory.CreateForProject(project);
                }

                if (navInfo != null)
                {
                    var navigationTool = _serviceProvider.GetService <SVsObjBrowser, IVsNavigationTool>();
                    return(navigationTool.NavigateToNavInfo(navInfo) == VSConstants.S_OK);
                }

                // Note: we'll fallback to Metadata-As-Source if we fail to get IVsNavInfo, but that should never happen.
            }

            // Generate new source or retrieve existing source for the symbol in question
            var result = _metadataAsSourceFileService.GetGeneratedFileAsync(project, symbol, cancellationToken).WaitAndGetResult(cancellationToken);

            var vsRunningDocumentTable4 = _serviceProvider.GetService <SVsRunningDocumentTable, IVsRunningDocumentTable4>();
            var fileAlreadyOpen         = vsRunningDocumentTable4.IsMonikerValid(result.FilePath);

            var openDocumentService = _serviceProvider.GetService <SVsUIShellOpenDocument, IVsUIShellOpenDocument>();

            openDocumentService.OpenDocumentViaProject(result.FilePath, VSConstants.LOGVIEWID.TextView_guid, out var localServiceProvider, out var hierarchy, out var itemId, out var windowFrame);

            var documentCookie = vsRunningDocumentTable4.GetDocumentCookie(result.FilePath);

            var vsTextBuffer = (IVsTextBuffer)vsRunningDocumentTable4.GetDocumentData(documentCookie);
            var textBuffer   = _editorAdaptersFactory.GetDataBuffer(vsTextBuffer);

            if (!fileAlreadyOpen)
            {
                ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID5.VSFPROPID_IsProvisional, true));
                ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID5.VSFPROPID_OverrideCaption, result.DocumentTitle));
                ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID5.VSFPROPID_OverrideToolTip, result.DocumentTooltip));
            }

            windowFrame.Show();

            var openedDocument = textBuffer.AsTextContainer().GetRelatedDocuments().FirstOrDefault();

            if (openedDocument != null)
            {
                var editorWorkspace   = openedDocument.Project.Solution.Workspace;
                var navigationService = editorWorkspace.Services.GetService <IDocumentNavigationService>();

                return(navigationService.TryNavigateToSpan(
                           workspace: editorWorkspace,
                           documentId: openedDocument.Id,
                           textSpan: result.IdentifierLocation.SourceSpan,
                           options: options.WithChangedOption(NavigationOptions.PreferProvisionalTab, true)));
            }

            return(true);
        }
Пример #42
0
 public override bool IsApplicable(OptionSet optionSet)
 => optionSet.GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes).Value ||
 optionSet.GetOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent).Value ||
 optionSet.GetOption(CSharpCodeStyleOptions.VarElsewhere).Value;
Пример #43
0
 internal static bool PreferPredefinedTypeKeywordInMemberAccess(OptionSet optionSet, string language)
 {
     return(optionSet.GetOption(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, language).Value);
 }
 private static bool PreferPredefinedTypeKeywordInMemberAccess(ExpressionSyntax memberAccess, OptionSet optionSet, SemanticModel semanticModel)
 {
     return (((memberAccess.Parent != null) && (memberAccess.Parent is MemberAccessExpressionSyntax)) || InsideCrefReference(memberAccess)) &&
            !InsideNameOfExpression(memberAccess, semanticModel) &&
            optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.CSharp);
 }
Пример #45
0
        internal virtual bool SupportsTriggerOnDeletion(OptionSet options)
        {
            var opt = options.GetOption(CompletionOptions.TriggerOnDeletion, Language);

            return(opt == true);
        }
Пример #46
0
        public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter(
            IEnumerable <AbstractFormattingRule> formattingRules,
            CompilationUnitSyntax root,
            TextLine line,
            IOptionService optionService,
            OptionSet optionSet,
            out SyntaxToken token)
        {
            Contract.ThrowIfNull(formattingRules);
            Contract.ThrowIfNull(root);

            token = default;
            if (!optionSet.GetOption(FormattingOptions.AutoFormattingOnReturn, LanguageNames.CSharp))
            {
                return(false);
            }

            if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart)
            {
                return(false);
            }

            var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition();

            if (!firstNonWhitespacePosition.HasValue)
            {
                return(false);
            }

            token = root.FindToken(firstNonWhitespacePosition.Value);
            if (IsInvalidToken(token))
            {
                return(false);
            }

            if (token.IsKind(SyntaxKind.None) ||
                token.SpanStart != firstNonWhitespacePosition)
            {
                return(false);
            }

            // first see whether there is a line operation for current token
            var previousToken = token.GetPreviousToken(includeZeroWidth: true);

            // only use smart token formatter when we have two visible tokens.
            if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing)
            {
                return(false);
            }

            var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet.AsAnalyzerConfigOptions(optionService, LanguageNames.CSharp));

            if (lineOperation == null || lineOperation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine)
            {
                // no indentation operation, nothing to do for smart token formatter
                return(false);
            }

            // We're pressing enter between two tokens, have the formatter figure out hte appropriate
            // indentation.
            return(true);
        }
Пример #47
0
        public static bool TryReduceOrSimplifyExplicitName(
            this CrefSyntax crefSyntax,
            SemanticModel semanticModel,
            out CrefSyntax replacementNode,
            out TextSpan issueSpan,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            replacementNode = null;
            issueSpan       = default(TextSpan);

            // Currently Qualified Cref is the only CrefSyntax We are handling separately
            if (crefSyntax.Kind() != SyntaxKind.QualifiedCref)
            {
                return(false);
            }

            var qualifiedCrefSyntax = (QualifiedCrefSyntax)crefSyntax;
            var memberCref          = qualifiedCrefSyntax.Member;

            // Currently we are dealing with only the NameMemberCrefs
            if (optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.CSharp) &&
                (memberCref.Kind() == SyntaxKind.NameMemberCref))
            {
                var nameMemberCref = ((NameMemberCrefSyntax)memberCref).Name;
                var symbolInfo     = semanticModel.GetSymbolInfo(nameMemberCref, cancellationToken);
                var symbol         = symbolInfo.Symbol;

                if (symbol == null)
                {
                    return(false);
                }

                if (symbol is INamespaceOrTypeSymbol)
                {
                    var namespaceOrTypeSymbol = (INamespaceOrTypeSymbol)symbol;

                    // 1. Check for Predefined Types
                    if (symbol is INamedTypeSymbol)
                    {
                        var namedSymbol = (INamedTypeSymbol)symbol;
                        var keywordKind = ExpressionSyntaxExtensions.GetPredefinedKeywordKind(namedSymbol.SpecialType);

                        if (keywordKind != SyntaxKind.None)
                        {
                            replacementNode = SyntaxFactory.TypeCref(
                                SyntaxFactory.PredefinedType(
                                    SyntaxFactory.Token(crefSyntax.GetLeadingTrivia(), keywordKind, crefSyntax.GetTrailingTrivia())));
                            replacementNode = crefSyntax.CopyAnnotationsTo(replacementNode);

                            // we want to show the whole name expression as unnecessary
                            issueSpan = crefSyntax.Span;

                            return(true);
                        }
                    }
                }
            }

            var oldSymbol = semanticModel.GetSymbolInfo(crefSyntax, cancellationToken).Symbol;

            if (oldSymbol != null)
            {
                var speculativeBindingOption = SpeculativeBindingOption.BindAsExpression;
                if (oldSymbol is INamespaceOrTypeSymbol)
                {
                    speculativeBindingOption = SpeculativeBindingOption.BindAsTypeOrNamespace;
                }

                var newSymbol = semanticModel.GetSpeculativeSymbolInfo(crefSyntax.SpanStart, memberCref, speculativeBindingOption).Symbol;

                if (newSymbol == oldSymbol)
                {
                    // Copy Trivia and Annotations
                    memberCref      = memberCref.WithLeadingTrivia(crefSyntax.GetLeadingTrivia());
                    memberCref      = crefSyntax.CopyAnnotationsTo(memberCref);
                    issueSpan       = qualifiedCrefSyntax.Container.Span;
                    replacementNode = memberCref;
                    return(true);
                }
            }

            return(false);
        }
Пример #48
0
            // The method which performs rename, resolves the conflict locations and returns the result of the rename operation
            public async Task <ConflictResolution> ResolveConflictsAsync()
            {
                try
                {
                    await FindDocumentsAndPossibleNameConflicts().ConfigureAwait(false);

                    var baseSolution = _renameLocationSet.Solution;

                    // Process rename one project at a time to improve caching and reduce syntax tree serialization.
                    var documentsGroupedByTopologicallySortedProjectId = _documentsIdsToBeCheckedForConflict
                                                                         .GroupBy(d => d.ProjectId)
                                                                         .OrderBy(g => _topologicallySortedProjects.IndexOf(g.Key));

                    _replacementTextValid = IsIdentifierValid_Worker(baseSolution, _replacementText, documentsGroupedByTopologicallySortedProjectId.Select(g => g.Key));
                    var renamedSpansTracker = new RenamedSpansTracker();
                    var conflictResolution  = new ConflictResolution(baseSolution, renamedSpansTracker, _replacementText, _replacementTextValid);

                    foreach (var documentsByProject in documentsGroupedByTopologicallySortedProjectId)
                    {
                        var documentIdsThatGetsAnnotatedAndRenamed = new HashSet <DocumentId>(documentsByProject);
                        using (baseSolution.Services.CacheService?.EnableCaching(documentsByProject.Key))
                        {
                            // Rename is going to be in 5 phases.
                            // 1st phase - Does a simple token replacement
                            // If the 1st phase results in conflict then we perform then:
                            //      2nd phase is to expand and simplify only the reference locations with conflicts
                            //      3rd phase is to expand and simplify all the conflict locations (both reference and non-reference)
                            // If there are unresolved Conflicts after the 3rd phase then in 4th phase,
                            //      We complexify and resolve locations that were resolvable and for the other locations we perform the normal token replacement like the first the phase.
                            // If the OptionSet has RenameFile to true, we rename files with the type declaration
                            for (var phase = 0; phase < 4; phase++)
                            {
                                // Step 1:
                                // The rename process and annotation for the bookkeeping is performed in one-step
                                // The Process in short is,
                                // 1. If renaming a token which is no conflict then replace the token and make a map of the oldspan to the newspan
                                // 2. If we encounter a node that has to be expanded( because there was a conflict in previous phase), we expand it.
                                //    If the node happens to contain a token that needs to be renamed then we annotate it and rename it after expansion else just expand and proceed
                                // 3. Through the whole process we maintain a map of the oldspan to newspan. In case of expansion & rename, we map the expanded node and the renamed token
                                conflictResolution.UpdateCurrentSolution(await AnnotateAndRename_WorkerAsync(
                                                                             baseSolution,
                                                                             conflictResolution.NewSolution,
                                                                             documentIdsThatGetsAnnotatedAndRenamed,
                                                                             _renameLocationSet.Locations,
                                                                             renamedSpansTracker,
                                                                             _replacementTextValid).ConfigureAwait(false));

                                // Step 2: Check for conflicts in the renamed solution
                                var foundResolvableConflicts = await IdentifyConflictsAsync(
                                    documentIdsForConflictResolution : documentIdsThatGetsAnnotatedAndRenamed,
                                    allDocumentIdsInProject : documentsByProject,
                                    projectId : documentsByProject.Key,
                                    conflictResolution : conflictResolution).ConfigureAwait(false);

                                if (!foundResolvableConflicts || phase == 3)
                                {
                                    break;
                                }

                                if (phase == 0)
                                {
                                    _conflictLocations = conflictResolution.RelatedLocations
                                                         .Where(loc => (documentIdsThatGetsAnnotatedAndRenamed.Contains(loc.DocumentId) && loc.Type == RelatedLocationType.PossiblyResolvableConflict && loc.IsReference))
                                                         .Select(loc => new ConflictLocationInfo(loc))
                                                         .ToSet();

                                    // If there were no conflicting locations in references, then the first conflict phase has to be skipped.
                                    if (_conflictLocations.Count == 0)
                                    {
                                        phase++;
                                    }
                                }

                                if (phase == 1)
                                {
                                    _conflictLocations = _conflictLocations.Concat(conflictResolution.RelatedLocations
                                                                                   .Where(loc => documentIdsThatGetsAnnotatedAndRenamed.Contains(loc.DocumentId) && loc.Type == RelatedLocationType.PossiblyResolvableConflict)
                                                                                   .Select(loc => new ConflictLocationInfo(loc)))
                                                         .ToSet();
                                }

                                // Set the documents with conflicts that need to be processed in the next phase.
                                // Note that we need to get the conflictLocations here since we're going to remove some locations below if phase == 2
                                documentIdsThatGetsAnnotatedAndRenamed = new HashSet <DocumentId>(_conflictLocations.Select(l => l.DocumentId));

                                if (phase == 2)
                                {
                                    // After phase 2, if there are still conflicts then remove the conflict locations from being expanded
                                    var unresolvedLocations = conflictResolution.RelatedLocations
                                                              .Where(l => (l.Type & RelatedLocationType.UnresolvedConflict) != 0)
                                                              .Select(l => Tuple.Create(l.ComplexifiedTargetSpan, l.DocumentId)).Distinct();

                                    _conflictLocations = _conflictLocations.Where(l => !unresolvedLocations.Any(c => c.Item2 == l.DocumentId && c.Item1.Contains(l.OriginalIdentifierSpan))).ToSet();
                                }

                                // Clean up side effects from rename before entering the next phase
                                conflictResolution.ClearDocuments(documentIdsThatGetsAnnotatedAndRenamed);
                            }

                            // Step 3: Simplify the project
                            conflictResolution.UpdateCurrentSolution(await renamedSpansTracker.SimplifyAsync(conflictResolution.NewSolution, documentsByProject, _replacementTextValid, _renameAnnotations, _cancellationToken).ConfigureAwait(false));
                            await conflictResolution.RemoveAllRenameAnnotationsAsync(documentsByProject, _renameAnnotations, _cancellationToken).ConfigureAwait(false);
                        }
                    }

                    // This rename could break implicit references of this symbol (e.g. rename MoveNext on a collection like type in a
                    // foreach/for each statement
                    var renamedSymbolInNewSolution = await GetRenamedSymbolInCurrentSolutionAsync(conflictResolution).ConfigureAwait(false);

                    if (IsRenameValid(conflictResolution, renamedSymbolInNewSolution))
                    {
                        await AddImplicitConflictsAsync(
                            renamedSymbolInNewSolution,
                            _renameLocationSet.Symbol,
                            _renameLocationSet.ImplicitLocations,
                            await conflictResolution.NewSolution.GetDocument(_documentIdOfRenameSymbolDeclaration).GetSemanticModelAsync(_cancellationToken).ConfigureAwait(false),
                            _renameSymbolDeclarationLocation,
                            renamedSpansTracker.GetAdjustedPosition(_renameSymbolDeclarationLocation.SourceSpan.Start, _documentIdOfRenameSymbolDeclaration),
                            conflictResolution,
                            _cancellationToken).ConfigureAwait(false);
                    }

                    foreach (var relatedLocation in conflictResolution.RelatedLocations)
                    {
                        if (relatedLocation.Type == RelatedLocationType.PossiblyResolvableConflict)
                        {
                            relatedLocation.Type = RelatedLocationType.UnresolvedConflict;
                        }
                    }
#if DEBUG
                    await DebugVerifyNoErrorsAsync(conflictResolution, _documentsIdsToBeCheckedForConflict).ConfigureAwait(false);
#endif

                    // Step 5: Rename declaration files
                    if (_optionSet.GetOption(RenameOptions.RenameFile))
                    {
                        var definitionLocations = _renameLocationSet.Symbol.Locations;
                        var definitionDocuments = definitionLocations
                                                  .Select(l => conflictResolution.OldSolution.GetDocument(l.SourceTree))
                                                  .Distinct();

                        if (definitionDocuments.Count() == 1)
                        {
                            // At the moment, only single document renaming is allowed
                            conflictResolution.RenameDocumentToMatchNewSymbol(definitionDocuments.Single());
                        }
                    }

                    return(conflictResolution);
                }
                catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
 public static OmniSharpImplementTypeInsertionBehavior GetInsertionBehavior(OptionSet options, string language)
 => (OmniSharpImplementTypeInsertionBehavior)options.GetOption(ImplementTypeOptions.Metadata.InsertionBehavior, language);
Пример #50
0
        public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet options, CancellationToken cancellationToken)
        {
            if (project == null || symbol == null)
            {
                return(false);
            }

            options ??= project.Solution.Workspace.Options;
            symbol = symbol.OriginalDefinition;

            // Prefer visible source locations if possible.
            var sourceLocations        = symbol.Locations.Where(loc => loc.IsInSource);
            var visibleSourceLocations = sourceLocations.Where(loc => loc.IsVisibleSourceLocation());
            var sourceLocation         = visibleSourceLocations.FirstOrDefault() ?? sourceLocations.FirstOrDefault();

            if (sourceLocation != null)
            {
                var targetDocument = project.Solution.GetDocument(sourceLocation.SourceTree);
                if (targetDocument != null)
                {
                    var editorWorkspace   = targetDocument.Project.Solution.Workspace;
                    var navigationService = editorWorkspace.Services.GetService <IDocumentNavigationService>();
                    return(navigationService.TryNavigateToSpan(editorWorkspace, targetDocument.Id, sourceLocation.SourceSpan, options));
                }
            }

            // We don't have a source document, so show the Metadata as Source view in a preview tab.

            var metadataLocation = symbol.Locations.Where(loc => loc.IsInMetadata).FirstOrDefault();

            if (metadataLocation == null || !_metadataAsSourceFileService.IsNavigableMetadataSymbol(symbol))
            {
                return(false);
            }

            // Should we prefer navigating to the Object Browser over metadata-as-source?
            if (options.GetOption(VisualStudioNavigationOptions.NavigateToObjectBrowser, project.Language))
            {
                var libraryService = project.LanguageServices.GetService <ILibraryService>();
                if (libraryService == null)
                {
                    return(false);
                }

                var compilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken);
                var navInfo     = libraryService.NavInfoFactory.CreateForSymbol(symbol, project, compilation);
                if (navInfo == null)
                {
                    navInfo = libraryService.NavInfoFactory.CreateForProject(project);
                }

                if (navInfo != null)
                {
                    var navigationTool = _serviceProvider.GetService <SVsObjBrowser, IVsNavigationTool>();
                    return(navigationTool.NavigateToNavInfo(navInfo) == VSConstants.S_OK);
                }

                // Note: we'll fallback to Metadata-As-Source if we fail to get IVsNavInfo, but that should never happen.
            }

            // Generate new source or retrieve existing source for the symbol in question
            var allowDecompilation = false;

            // Check whether decompilation is supported for the project. We currently only support this for C# projects.
            if (project.LanguageServices.GetService <IDecompiledSourceService>() != null)
            {
                allowDecompilation = project.Solution.Workspace.Options.GetOption(FeatureOnOffOptions.NavigateToDecompiledSources) && !symbol.IsFromSource();
                if (allowDecompilation && !project.Solution.Workspace.Options.GetOption(FeatureOnOffOptions.AcceptedDecompilerDisclaimer))
                {
                    var notificationService = project.Solution.Workspace.Services.GetService <INotificationService>();
                    allowDecompilation = notificationService.ConfirmMessageBox(ServicesVSResources.Decompiler_Legal_Notice_Message, ServicesVSResources.Decompiler_Legal_Notice_Title, NotificationSeverity.Warning);
                    if (allowDecompilation)
                    {
                        var workspace = project.Solution.Workspace;
                        workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options
                                                                                        .WithChangedOption(FeatureOnOffOptions.AcceptedDecompilerDisclaimer, true)));
                    }
                }
            }

            var result = _metadataAsSourceFileService.GetGeneratedFileAsync(project, symbol, allowDecompilation, cancellationToken).WaitAndGetResult(cancellationToken);

            var vsRunningDocumentTable4 = _serviceProvider.GetService <SVsRunningDocumentTable, IVsRunningDocumentTable4>();
            var fileAlreadyOpen         = vsRunningDocumentTable4.IsMonikerValid(result.FilePath);

            var openDocumentService = _serviceProvider.GetService <SVsUIShellOpenDocument, IVsUIShellOpenDocument>();

            openDocumentService.OpenDocumentViaProject(result.FilePath, VSConstants.LOGVIEWID.TextView_guid, out var localServiceProvider, out var hierarchy, out var itemId, out var windowFrame);

            var documentCookie = vsRunningDocumentTable4.GetDocumentCookie(result.FilePath);

            // The cast from dynamic to object doesn't change semantics, but avoids loading the dynamic binder
            // which saves us JIT time in this method.
            var vsTextBuffer = (IVsTextBuffer)(object)vsRunningDocumentTable4.GetDocumentData(documentCookie);
            var textBuffer   = _editorAdaptersFactory.GetDataBuffer(vsTextBuffer);

            if (!fileAlreadyOpen)
            {
                ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID5.VSFPROPID_IsProvisional, true));
                ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID5.VSFPROPID_OverrideCaption, result.DocumentTitle));
                ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID5.VSFPROPID_OverrideToolTip, result.DocumentTooltip));
            }

            windowFrame.Show();

            var openedDocument = textBuffer.AsTextContainer().GetRelatedDocuments().FirstOrDefault();

            if (openedDocument != null)
            {
                var editorWorkspace   = openedDocument.Project.Solution.Workspace;
                var navigationService = editorWorkspace.Services.GetService <IDocumentNavigationService>();

                return(navigationService.TryNavigateToSpan(
                           workspace: editorWorkspace,
                           documentId: openedDocument.Id,
                           textSpan: result.IdentifierLocation.SourceSpan,
                           options: options.WithChangedOption(NavigationOptions.PreferProvisionalTab, true)));
            }

            return(true);
        }
Пример #51
0
        private void AddSwitchIndentationOperation(List <IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet)
        {
            var section = node as SwitchSectionSyntax;

            if (section == null)
            {
                return;
            }

            // can this ever happen?
            if (section.Labels.Count == 0 &&
                section.Statements.Count == 0)
            {
                return;
            }

            var indentSwitchCase          = optionSet.GetOption(CSharpFormattingOptions.IndentSwitchCaseSection);
            var indentSwitchCaseWhenBlock = optionSet.GetOption(CSharpFormattingOptions.IndentSwitchCaseSectionWhenBlock);

            if (!indentSwitchCase && !indentSwitchCaseWhenBlock)
            {
                // Never indent
                return;
            }

            var alwaysIndent = indentSwitchCase && indentSwitchCaseWhenBlock;

            if (!alwaysIndent)
            {
                // Only one of these values can be true at this point.
                Debug.Assert(indentSwitchCase != indentSwitchCaseWhenBlock);

                var firstStatementIsBlock =
                    section.Statements.Count > 0 &&
                    section.Statements[0].IsKind(SyntaxKind.Block);

                if (indentSwitchCaseWhenBlock != firstStatementIsBlock)
                {
                    return;
                }
            }

            // see whether we are the last statement
            var switchStatement = node.Parent as SwitchStatementSyntax;
            var lastSection     = switchStatement.Sections.Last() == node;

            if (section.Statements.Count == 0)
            {
                // even if there is no statement under section, we still want indent operation
                var lastTokenOfLabel = section.Labels.Last().GetLastToken(includeZeroWidth: true);
                var nextToken        = lastTokenOfLabel.GetNextToken(includeZeroWidth: true);

                AddIndentBlockOperation(list, lastTokenOfLabel, lastTokenOfLabel,
                                        lastSection ?
                                        TextSpan.FromBounds(lastTokenOfLabel.FullSpan.End, nextToken.SpanStart) : TextSpan.FromBounds(lastTokenOfLabel.FullSpan.End, lastTokenOfLabel.FullSpan.End));
                return;
            }

            var startToken = section.Statements.First().GetFirstToken(includeZeroWidth: true);
            var endToken   = section.Statements.Last().GetLastToken(includeZeroWidth: true);

            // see whether we are the last statement
            var span = CommonFormattingHelpers.GetSpanIncludingTrailingAndLeadingTriviaOfAdjacentTokens(startToken, endToken);

            span = lastSection ? span : TextSpan.FromBounds(span.Start, endToken.FullSpan.End);

            AddIndentBlockOperation(list, startToken, endToken, span);
        }
Пример #52
0
            public override IndentationResult?GetDesiredIndentation()
            {
                var indentStyle = OptionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp);

                if (indentStyle == FormattingOptions.IndentStyle.None)
                {
                    return(null);
                }

                // find previous line that is not blank
                var previousLine = GetPreviousNonBlankOrPreprocessorLine();

                // it is beginning of the file, there is no previous line exists.
                // in that case, indentation 0 is our base indentation.
                if (previousLine == null)
                {
                    return(IndentFromStartOfLine(0));
                }

                // okay, now see whether previous line has anything meaningful
                var lastNonWhitespacePosition = previousLine.GetLastNonWhitespacePosition();

                if (!lastNonWhitespacePosition.HasValue)
                {
                    return(null);
                }

                // there is known parameter list "," parse bug. if previous token is "," from parameter list,
                // FindToken will not be able to find them.
                var token = Tree.GetRoot(CancellationToken).FindToken(lastNonWhitespacePosition.Value);

                if (token.IsKind(SyntaxKind.None) || indentStyle == FormattingOptions.IndentStyle.Block)
                {
                    return(GetIndentationOfLine(previousLine));
                }

                // okay, now check whether the text we found is trivia or actual token.
                if (token.Span.Contains(lastNonWhitespacePosition.Value))
                {
                    // okay, it is a token case, do special work based on type of last token on previous line
                    return(GetIndentationBasedOnToken(token));
                }
                else
                {
                    // there must be trivia that contains or touch this position
                    Contract.Assert(token.FullSpan.Contains(lastNonWhitespacePosition.Value));

                    // okay, now check whether the trivia is at the beginning of the line
                    var firstNonWhitespacePosition = previousLine.GetFirstNonWhitespacePosition();
                    if (!firstNonWhitespacePosition.HasValue)
                    {
                        return(IndentFromStartOfLine(0));
                    }

                    var trivia = Tree.GetRoot(CancellationToken).FindTrivia(firstNonWhitespacePosition.Value, findInsideTrivia: true);
                    if (trivia.Kind() == SyntaxKind.None || this.LineToBeIndented.LineNumber > previousLine.LineNumber + 1)
                    {
                        // If the token belongs to the next statement and is also the first token of the statement, then it means the user wants
                        // to start type a new statement. So get indentation from the start of the line but not based on the token.
                        // Case:
                        // static void Main(string[] args)
                        // {
                        //     // A
                        //     // B
                        //
                        //     $$
                        //     return;
                        // }

                        var containingStatement = token.GetAncestor <StatementSyntax>();
                        if (containingStatement != null && containingStatement.GetFirstToken() == token)
                        {
                            var position = GetCurrentPositionNotBelongToEndOfFileToken(LineToBeIndented.Start);
                            return(IndentFromStartOfLine(Finder.GetIndentationOfCurrentPosition(Tree, token, position, CancellationToken)));
                        }

                        // If the token previous of the base token happens to be a Comma from a separation list then we need to handle it different
                        // Case:
                        // var s = new List<string>
                        //                 {
                        //                     """",
                        //                             """",/*sdfsdfsdfsdf*/
                        //                                  // dfsdfsdfsdfsdf
                        //
                        //                             $$
                        //                 };
                        var previousToken = token.GetPreviousToken();
                        if (previousToken.IsKind(SyntaxKind.CommaToken))
                        {
                            return(GetIndentationFromCommaSeparatedList(previousToken));
                        }

                        // okay, beginning of the line is not trivia, use the last token on the line as base token
                        return(GetIndentationBasedOnToken(token));
                    }

                    // this case we will keep the indentation of this trivia line
                    // this trivia can't be preprocessor by the way.
                    return(GetIndentationOfLine(previousLine));
                }
            }
Пример #53
0
        public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustSpacesOperation> nextOperation)
        {
            if (optionSet == null)
            {
                return(nextOperation.Invoke());
            }

            System.Diagnostics.Debug.Assert(previousToken.Parent != null && currentToken.Parent != null);

            var previousKind       = previousToken.Kind();
            var currentKind        = currentToken.Kind();
            var previousParentKind = previousToken.Parent.Kind();
            var currentParentKind  = currentToken.Parent.Kind();

            // For Method Declaration
            if (currentToken.IsOpenParenInParameterList() && previousKind == SyntaxKind.IdentifierToken)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            // For Generic Method Declaration
            if (currentToken.IsOpenParenInParameterList() && previousKind == SyntaxKind.GreaterThanToken && previousParentKind == SyntaxKind.TypeParameterList)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            // Case: public static implicit operator string(Program p) { return null; }
            if (previousToken.IsKeyword() && currentToken.IsOpenParenInParameterListOfAConversionOperatorDeclaration())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            // Case: public static Program operator !(Program p) { return null; }
            if (previousToken.Parent.IsKind(SyntaxKind.OperatorDeclaration) && currentToken.IsOpenParenInParameterListOfAOperationDeclaration())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpacingAfterMethodDeclarationName));
            }

            if (previousToken.IsOpenParenInParameterList() && currentToken.IsCloseParenInParameterList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBetweenEmptyMethodDeclarationParentheses));
            }

            if (previousToken.IsOpenParenInParameterList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodDeclarationParenthesis));
            }

            if (currentToken.IsCloseParenInParameterList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodDeclarationParenthesis));
            }

            // For Method Call
            if (currentToken.IsOpenParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterMethodCallName));
            }

            if (previousToken.IsOpenParenInArgumentList() && currentToken.IsCloseParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBetweenEmptyMethodCallParentheses));
            }

            if (previousToken.IsOpenParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            if (currentToken.IsCloseParenInArgumentList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            // For spacing around: typeof, default, and sizeof; treat like a Method Call
            if (currentKind == SyntaxKind.OpenParenToken && IsFunctionLikeKeywordExpressionKind(currentParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterMethodCallName));
            }

            if (previousKind == SyntaxKind.OpenParenToken && IsFunctionLikeKeywordExpressionKind(previousParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            if (currentKind == SyntaxKind.CloseParenToken && IsFunctionLikeKeywordExpressionKind(currentParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinMethodCallParentheses));
            }

            // For Spacing b/n control flow keyword and paren. Parent check not needed.
            if (currentKind == SyntaxKind.OpenParenToken &&
                (previousKind == SyntaxKind.IfKeyword || previousKind == SyntaxKind.WhileKeyword || previousKind == SyntaxKind.SwitchKeyword ||
                 previousKind == SyntaxKind.ForKeyword || previousKind == SyntaxKind.ForEachKeyword || previousKind == SyntaxKind.CatchKeyword ||
                 previousKind == SyntaxKind.UsingKeyword || previousKind == SyntaxKind.WhenKeyword || previousKind == SyntaxKind.LockKeyword))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterControlFlowStatementKeyword));
            }

            // For spacing between parenthesis and expression
            if ((previousParentKind == SyntaxKind.ParenthesizedExpression && previousKind == SyntaxKind.OpenParenToken) ||
                (currentParentKind == SyntaxKind.ParenthesizedExpression && currentKind == SyntaxKind.CloseParenToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinExpressionParentheses));
            }

            // For spacing between the parenthesis and the cast expression
            if ((previousParentKind == SyntaxKind.CastExpression && previousKind == SyntaxKind.OpenParenToken) ||
                (currentParentKind == SyntaxKind.CastExpression && currentKind == SyntaxKind.CloseParenToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinCastParentheses));
            }

            // Semicolons in an empty for statement.  i.e.   for(;;)
            if (previousParentKind == SyntaxKind.ForStatement &&
                this.IsEmptyForStatement((ForStatementSyntax)previousToken.Parent))
            {
                if (currentKind == SyntaxKind.SemicolonToken &&
                    (previousKind != SyntaxKind.SemicolonToken ||
                     optionSet.GetOption <bool>(CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement)))
                {
                    return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement));
                }

                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterSemicolonsInForStatement));
            }

            // For spacing between the parenthesis and the expression inside the control flow expression
            if (previousKind == SyntaxKind.OpenParenToken && IsControlFlowLikeKeywordStatementKind(previousParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinOtherParentheses));
            }

            if (currentKind == SyntaxKind.CloseParenToken && IsControlFlowLikeKeywordStatementKind(currentParentKind))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinOtherParentheses));
            }

            // For spacing after the cast
            if (previousParentKind == SyntaxKind.CastExpression && previousKind == SyntaxKind.CloseParenToken)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterCast));
            }

            // For spacing Before Square Braces
            if (currentKind == SyntaxKind.OpenBracketToken && HasFormattableBracketParent(currentToken) && !previousToken.IsOpenBraceOrCommaOfObjectInitializer())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeOpenSquareBracket));
            }

            // For spacing empty square braces, also treat [,] as empty
            if (((currentKind == SyntaxKind.CloseBracketToken && previousKind == SyntaxKind.OpenBracketToken) ||
                 currentKind == SyntaxKind.OmittedArraySizeExpressionToken) &&
                HasFormattableBracketParent(previousToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBetweenEmptySquareBrackets));
            }

            // For spacing square brackets within
            if (previousKind == SyntaxKind.OpenBracketToken && HasFormattableBracketParent(previousToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinSquareBrackets));
            }

            if (currentKind == SyntaxKind.CloseBracketToken && previousKind != SyntaxKind.OmittedArraySizeExpressionToken && HasFormattableBracketParent(currentToken))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinSquareBrackets));
            }

            // attribute case ] *
            // Place a space between the attribute and the next member if they're on the same line.
            if (previousKind == SyntaxKind.CloseBracketToken && previousToken.Parent.IsKind(SyntaxKind.AttributeList))
            {
                var attributeOwner = previousToken.Parent?.Parent;
                if (attributeOwner is MemberDeclarationSyntax)
                {
                    return(CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine));
                }
            }

            // For spacing delimiters - after colon
            if (previousToken.IsColonInTypeBaseList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterColonInBaseTypeDeclaration));
            }

            // For spacing delimiters - before colon
            if (currentToken.IsColonInTypeBaseList())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeColonInBaseTypeDeclaration));
            }

            // For spacing delimiters - after comma
            if ((previousToken.IsCommaInArgumentOrParameterList() && currentKind != SyntaxKind.OmittedTypeArgumentToken) ||
                previousToken.IsCommaInInitializerExpression() ||
                (previousKind == SyntaxKind.CommaToken &&
                 currentKind != SyntaxKind.OmittedArraySizeExpressionToken &&
                 HasFormattableBracketParent(previousToken)))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterComma));
            }

            // For spacing delimiters - before comma
            if ((currentToken.IsCommaInArgumentOrParameterList() && previousKind != SyntaxKind.OmittedTypeArgumentToken) ||
                currentToken.IsCommaInInitializerExpression() ||
                (currentKind == SyntaxKind.CommaToken &&
                 previousKind != SyntaxKind.OmittedArraySizeExpressionToken &&
                 HasFormattableBracketParent(currentToken)))
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeComma));
            }

            // For Spacing delimiters - after Dot
            if (previousToken.IsDotInMemberAccessOrQualifiedName())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterDot));
            }

            // For spacing delimiters - before Dot
            if (currentToken.IsDotInMemberAccessOrQualifiedName())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeDot));
            }

            // For spacing delimiters - after semicolon
            if (previousToken.IsSemicolonInForStatement() && currentKind != SyntaxKind.CloseParenToken)
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterSemicolonsInForStatement));
            }

            // For spacing delimiters - before semicolon
            if (currentToken.IsSemicolonInForStatement())
            {
                return(AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement));
            }

            // For spacing around the binary operators
            if (currentToken.Parent is BinaryExpressionSyntax ||
                previousToken.Parent is BinaryExpressionSyntax ||
                currentToken.Parent is AssignmentExpressionSyntax ||
                previousToken.Parent is AssignmentExpressionSyntax)
            {
                switch (optionSet.GetOption(CSharpFormattingOptions.SpacingAroundBinaryOperator))
                {
                case BinaryOperatorSpacingOptions.Single:
                    return(CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine));

                case BinaryOperatorSpacingOptions.Remove:
                    if (currentKind == SyntaxKind.IsKeyword ||
                        currentKind == SyntaxKind.AsKeyword ||
                        previousKind == SyntaxKind.IsKeyword ||
                        previousKind == SyntaxKind.AsKeyword)
                    {
                        // User want spaces removed but at least one is required for the "as" & "is" keyword
                        return(CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine));
                    }
                    else
                    {
                        return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpacesIfOnSingleLine));
                    }

                case BinaryOperatorSpacingOptions.Ignore:
                    return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.PreserveSpaces));

                default:
                    System.Diagnostics.Debug.Assert(false, "Invalid BinaryOperatorSpacingOptions");
                    break;
                }
            }

            // No space after $" and $@" and @$" at the start of an interpolated string
            if (previousKind == SyntaxKind.InterpolatedStringStartToken ||
                previousKind == SyntaxKind.InterpolatedVerbatimStringStartToken)
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // No space before " at the end of an interpolated string
            if (currentKind == SyntaxKind.InterpolatedStringEndToken)
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // No space before { or after } in interpolations
            if ((currentKind == SyntaxKind.OpenBraceToken && currentToken.Parent is InterpolationSyntax) ||
                (previousKind == SyntaxKind.CloseBraceToken && previousToken.Parent is InterpolationSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // Preserve space after { or before } in interpolations (i.e. between the braces and the expression)
            if ((previousKind == SyntaxKind.OpenBraceToken && previousToken.Parent is InterpolationSyntax) ||
                (currentKind == SyntaxKind.CloseBraceToken && currentToken.Parent is InterpolationSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.PreserveSpaces));
            }

            // No space before or after , in interpolation alignment clause
            if ((previousKind == SyntaxKind.CommaToken && previousToken.Parent is InterpolationAlignmentClauseSyntax) ||
                (currentKind == SyntaxKind.CommaToken && currentToken.Parent is InterpolationAlignmentClauseSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // No space before or after : in interpolation format clause
            if ((previousKind == SyntaxKind.ColonToken && previousToken.Parent is InterpolationFormatClauseSyntax) ||
                (currentKind == SyntaxKind.ColonToken && currentToken.Parent is InterpolationFormatClauseSyntax))
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // Always put a space in the var form of deconstruction-declaration
            if (currentToken.IsOpenParenInVarDeconstructionDeclaration())
            {
                return(CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces));
            }

            // Index expressions
            if (previousKind == SyntaxKind.CaretToken && previousParentKind == SyntaxKindEx.IndexExpression)
            {
                return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
            }

            // Right of Range expressions
            if (previousKind == SyntaxKindEx.DotDotToken && previousParentKind == SyntaxKindEx.RangeExpression)
            {
#if !CODE_STYLE
                var rangeExpression = (RangeExpressionSyntax)previousToken.Parent;
                var hasRightOperand = rangeExpression.RightOperand != null;
#else
                var childSyntax     = previousToken.Parent.ChildNodesAndTokens();
                var hasRightOperand = childSyntax.Count > 1 && childSyntax[childSyntax.Count - 2].IsKind(SyntaxKindEx.DotDotToken);
#endif
                if (hasRightOperand)
                {
                    return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
                }
            }

            // Left of Range expressions
            if (currentKind == SyntaxKindEx.DotDotToken && currentParentKind == SyntaxKindEx.RangeExpression)
            {
#if !CODE_STYLE
                var rangeExpression = (RangeExpressionSyntax)currentToken.Parent;
                var hasLeftOperand  = rangeExpression.LeftOperand != null;
#else
                var childSyntax    = currentToken.Parent.ChildNodesAndTokens();
                var hasLeftOperand = childSyntax.Count > 1 && childSyntax[1].IsKind(SyntaxKindEx.DotDotToken);
#endif
                if (hasLeftOperand)
                {
                    return(CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces));
                }
            }

            // Put a space between the type and a positional pattern
            // ex: `e is Type ( /*positional*/ )`
            if (currentToken.IsKind(SyntaxKind.OpenParenToken) &&
                currentParentKind == SyntaxKindEx.PositionalPatternClause)
            {
#if !CODE_STYLE
                var recursivePatternType = ((RecursivePatternSyntax)currentToken.Parent.Parent).Type;
#else
                var childNodesAndTokens  = currentToken.Parent.Parent.ChildNodesAndTokens();
                var recursivePatternType = childNodesAndTokens.Count > 0 ? childNodesAndTokens[0].AsNode() as TypeSyntax : null;
#endif

                if (recursivePatternType != null)
                {
                    return(CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces));
                }
            }

            return(nextOperation.Invoke());
        }
Пример #54
0
 public CheckBoxOptionViewModel(IOption option, string description, string truePreview, string falsePreview, AbstractOptionPreviewViewModel info, OptionSet options)
     : base(option, description, truePreview, falsePreview, info)
 {
     SetProperty(ref _isChecked, (bool)options.GetOption(new OptionKey(option, option.IsPerLanguage ? info.Language : null)));
 }
 private static bool PreferPredefinedTypeKeywordInDeclarations(NameSyntax name, OptionSet optionSet, SemanticModel semanticModel)
 {
     return (name.Parent != null) && !(name.Parent is MemberAccessExpressionSyntax) &&
            !InsideCrefReference(name) && !InsideNameOfExpression(name, semanticModel) &&
            optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, LanguageNames.CSharp);
 }
 private static TypeSyntax GenerateTypeSyntax(ITypeSymbol type, OptionSet options)
 {
     return(type.ContainsAnonymousType() || (options.GetOption(CSharpCodeStyleOptions.UseVarWhenDeclaringLocals) && type.TypeKind != TypeKind.Delegate)
         ? SyntaxFactory.IdentifierName("var")
         : type.GenerateTypeSyntax());
 }
        public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustSpacesOperation> nextOperation)
        {
            var operation = nextOperation.Invoke();

            // } else in the if else context
            if (previousToken.IsKind(SyntaxKind.CloseBraceToken) && currentToken.IsKind(SyntaxKind.ElseKeyword))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLineForElse))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * catch in the try catch context
            if (currentToken.IsKind(SyntaxKind.CatchKeyword))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLineForCatch))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * finally
            if (currentToken.IsKind(SyntaxKind.FinallyKeyword))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLineForFinally))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { in the type declaration context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && (currentToken.Parent is BaseTypeDeclarationSyntax || currentToken.Parent is NamespaceDeclarationSyntax))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInTypes))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // new { - Anonymous object creation
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null && currentToken.Parent.IsKind(SyntaxKind.AnonymousObjectCreationExpression))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // new { - Object Initialization
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null && currentToken.Parent.IsKind(SyntaxKind.ObjectInitializerExpression))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            var currentTokenParentParent = currentToken.Parent.Parent;

            // * { - in the member declaration context
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null && currentTokenParentParent is MemberDeclarationSyntax)
            {
                var option = currentTokenParentParent is BasePropertyDeclarationSyntax
                    ? CSharpFormattingOptions.NewLinesForBracesInProperties
                    : CSharpFormattingOptions.NewLinesForBracesInMethods;

                if (!optionSet.GetOption(option))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null && currentTokenParentParent is AccessorDeclarationSyntax)
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAccessors))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { - in the anonymous Method context
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null && currentTokenParentParent.IsKind(SyntaxKind.AnonymousMethodExpression))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { - in the local function context
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null && currentTokenParentParent.IsKind(SyntaxKind.LocalFunctionStatement))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInMethods))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { - in the Lambda context
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null &&
                (currentTokenParentParent.IsKind(SyntaxKind.SimpleLambdaExpression) || currentTokenParentParent.IsKind(SyntaxKind.ParenthesizedLambdaExpression)))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { - in the control statement context
            if (currentToken.Kind() == SyntaxKind.OpenBraceToken && IsControlBlock(currentToken.Parent))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            return(operation);
        }
Пример #58
0
        internal static Diagnostic CreateDiagnostic(SemanticModel model, OptionSet optionSet, TextSpan issueSpan, string diagnosticId, bool inDeclaration)
        {
            PerLanguageOption <CodeStyleOption <bool> > option;
            DiagnosticDescriptor descriptor;
            ReportDiagnostic     severity;

            switch (diagnosticId)
            {
            case IDEDiagnosticIds.SimplifyNamesDiagnosticId:
                descriptor = s_descriptorSimplifyNames;
                severity   = descriptor.DefaultSeverity.ToReportDiagnostic();
                break;

            case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId:
                descriptor = s_descriptorSimplifyMemberAccess;
                severity   = descriptor.DefaultSeverity.ToReportDiagnostic();
                break;

            case IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId:
                option = inDeclaration
                        ? CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration
                        : CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess;
                descriptor = s_descriptorPreferBuiltinOrFrameworkType;

                var optionValue = optionSet.GetOption(option, model.Language);
                severity = optionValue.Notification.Severity;
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(diagnosticId);
            }

            var tree    = model.SyntaxTree;
            var builder = ImmutableDictionary.CreateBuilder <string, string>();

            builder["OptionName"]     = nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess); // TODO: need the actual one
            builder["OptionLanguage"] = model.Language;
            var diagnostic = DiagnosticHelper.Create(descriptor, tree.GetLocation(issueSpan), severity, additionalLocations: null, builder.ToImmutable());

#if LOG
            var sourceText = tree.GetText();
            sourceText.GetLineAndOffset(issueSpan.Start, out var startLineNumber, out var startOffset);
            sourceText.GetLineAndOffset(issueSpan.End, out var endLineNumber, out var endOffset);
            var logLine = tree.FilePath + "," + startLineNumber + "\t" + diagnosticId + "\t" + inDeclaration + "\t";

            var leading = sourceText.ToString(TextSpan.FromBounds(
                                                  sourceText.Lines[startLineNumber].Start, issueSpan.Start));
            var mid      = sourceText.ToString(issueSpan);
            var trailing = sourceText.ToString(TextSpan.FromBounds(
                                                   issueSpan.End, sourceText.Lines[endLineNumber].End));

            var contents = leading + "[|" + s_newlinePattern.Replace(mid, " ") + "|]" + trailing;
            logLine += contents + "\r\n";

            lock (_logGate)
            {
                File.AppendAllText(_logFile, logLine);
            }
#endif

            return(diagnostic);
        }
        public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation<AdjustSpacesOperation> nextOperation)
        {
            var operation = nextOperation.Invoke();

            // } else in the if else context
            if (previousToken.IsKind(SyntaxKind.CloseBraceToken) && currentToken.IsKind(SyntaxKind.ElseKeyword))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLineForElse))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * catch in the try catch context
            if (currentToken.IsKind(SyntaxKind.CatchKeyword))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLineForCatch))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * finally
            if (currentToken.IsKind(SyntaxKind.FinallyKeyword))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.NewLineForFinally))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { in the type declaration context
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && (currentToken.Parent is BaseTypeDeclarationSyntax || currentToken.Parent is NamespaceDeclarationSyntax))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForTypes))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // new { - Anonymous object creation
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null && currentToken.Parent.IsKind(SyntaxKind.AnonymousObjectCreationExpression))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForAnonymousType))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // new { - Object Initialization
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null && currentToken.Parent.IsKind(SyntaxKind.ObjectInitializerExpression))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForObjectInitializers))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            var currentTokenParentParent = currentToken.Parent.Parent;

            // * { - in the member declaration context
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null &&
               (currentTokenParentParent is MemberDeclarationSyntax || currentTokenParentParent is AccessorDeclarationSyntax))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForMethods))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { - in the anonymous Method context
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null && currentTokenParentParent.IsKind(SyntaxKind.AnonymousMethodExpression))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForAnonymousMethods))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { - in the Lambda context
            if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentTokenParentParent != null &&
               (currentTokenParentParent.IsKind(SyntaxKind.SimpleLambdaExpression) || currentTokenParentParent.IsKind(SyntaxKind.ParenthesizedLambdaExpression)))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForLambda))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            // * { - in the control statement context
            if (currentToken.CSharpKind() == SyntaxKind.OpenBraceToken && IsControlBlock(currentToken.Parent))
            {
                if (!optionSet.GetOption(CSharpFormattingOptions.OpenBracesInNewLineForControl))
                {
                    operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces);
                }
            }

            return operation;
        }
            private IndentationResult?GetIndentationBasedOnToken(SyntaxToken token)
            {
                Contract.ThrowIfNull(LineToBeIndented);
                Contract.ThrowIfNull(Tree);
                Contract.ThrowIfTrue(token.Kind() == SyntaxKind.None);

                // special cases
                // case 1: token belongs to verbatim token literal
                // case 2: $@"$${0}"
                // case 3: $@"Comment$$ inbetween{0}"
                // case 4: $@"{0}$$"
                if (token.IsVerbatimStringLiteral() ||
                    token.IsKind(SyntaxKind.InterpolatedVerbatimStringStartToken) ||
                    token.IsKind(SyntaxKind.InterpolatedStringTextToken) ||
                    (token.IsKind(SyntaxKind.CloseBraceToken) && token.Parent.IsKind(SyntaxKind.Interpolation)))
                {
                    return(IndentFromStartOfLine(0));
                }

                // if previous statement belong to labeled statement, don't follow label's indentation
                // but its previous one.
                if (token.Parent is LabeledStatementSyntax || token.IsLastTokenInLabelStatement())
                {
                    token = token.GetAncestor <LabeledStatementSyntax>().GetFirstToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true);
                }

                var position = GetCurrentPositionNotBelongToEndOfFileToken(LineToBeIndented.Start);

                // first check operation service to see whether we can determine indentation from it
                var indentation = Finder.FromIndentBlockOperations(Tree, token, position, CancellationToken);

                if (indentation.HasValue)
                {
                    return(IndentFromStartOfLine(indentation.Value));
                }

                var alignmentTokenIndentation = Finder.FromAlignTokensOperations(Tree, token);

                if (alignmentTokenIndentation.HasValue)
                {
                    return(IndentFromStartOfLine(alignmentTokenIndentation.Value));
                }

                // if we couldn't determine indentation from the service, use heuristic to find indentation.
                var snapshot = LineToBeIndented.Snapshot;

                // If this is the last token of an embedded statement, walk up to the top-most parenting embedded
                // statement owner and use its indentation.
                //
                // cases:
                //   if (true)
                //     if (false)
                //       Foo();
                //
                //   if (true)
                //     { }

                if (token.IsSemicolonOfEmbeddedStatement() ||
                    token.IsCloseBraceOfEmbeddedBlock())
                {
                    Contract.Requires(
                        token.Parent != null &&
                        (token.Parent.Parent is StatementSyntax || token.Parent.Parent is ElseClauseSyntax));

                    var embeddedStatementOwner = token.Parent.Parent;
                    while (embeddedStatementOwner.IsEmbeddedStatement())
                    {
                        embeddedStatementOwner = embeddedStatementOwner.Parent;
                    }

                    return(GetIndentationOfLine(snapshot.GetLineFromPosition(embeddedStatementOwner.GetFirstToken(includeZeroWidth: true).SpanStart)));
                }

                switch (token.Kind())
                {
                case SyntaxKind.SemicolonToken:
                {
                    // special cases
                    if (token.IsSemicolonInForStatement())
                    {
                        return(GetDefaultIndentationFromToken(token));
                    }

                    return(IndentFromStartOfLine(Finder.GetIndentationOfCurrentPosition(Tree, token, position, CancellationToken)));
                }

                case SyntaxKind.CloseBraceToken:
                {
                    if (token.Parent.IsKind(SyntaxKind.AccessorList) &&
                        token.Parent.Parent.IsKind(SyntaxKind.PropertyDeclaration))
                    {
                        if (token.GetNextToken().IsEqualsTokenInAutoPropertyInitializers())
                        {
                            return(GetDefaultIndentationFromToken(token));
                        }
                    }

                    return(IndentFromStartOfLine(Finder.GetIndentationOfCurrentPosition(Tree, token, position, CancellationToken)));
                }

                case SyntaxKind.OpenBraceToken:
                {
                    return(IndentFromStartOfLine(Finder.GetIndentationOfCurrentPosition(Tree, token, position, CancellationToken)));
                }

                case SyntaxKind.ColonToken:
                {
                    var nonTerminalNode = token.Parent;
                    Contract.ThrowIfNull(nonTerminalNode, @"Malformed code or bug in parser???");

                    if (nonTerminalNode is SwitchLabelSyntax)
                    {
                        return(GetIndentationOfLine(snapshot.GetLineFromPosition(nonTerminalNode.GetFirstToken(includeZeroWidth: true).SpanStart), OptionSet.GetOption(FormattingOptions.IndentationSize, token.Language)));
                    }

                    // default case
                    return(GetDefaultIndentationFromToken(token));
                }

                case SyntaxKind.CloseBracketToken:
                {
                    var nonTerminalNode = token.Parent;
                    Contract.ThrowIfNull(nonTerminalNode, @"Malformed code or bug in parser???");

                    // if this is closing an attribute, we shouldn't indent.
                    if (nonTerminalNode is AttributeListSyntax)
                    {
                        return(GetIndentationOfLine(snapshot.GetLineFromPosition(nonTerminalNode.GetFirstToken(includeZeroWidth: true).SpanStart)));
                    }

                    // default case
                    return(GetDefaultIndentationFromToken(token));
                }

                case SyntaxKind.XmlTextLiteralToken:
                {
                    return(GetIndentationOfLine(snapshot.GetLineFromPosition(token.SpanStart)));
                }

                case SyntaxKind.CommaToken:
                {
                    return(GetIndentationFromCommaSeparatedList(token));
                }

                default:
                {
                    return(GetDefaultIndentationFromToken(token));
                }
                }
            }