diff --git a/.editorconfig b/.editorconfig index 87f3c996a..4b4a34520 100644 --- a/.editorconfig +++ b/.editorconfig @@ -82,6 +82,30 @@ csharp_new_line_before_finally = true csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_anonymous_types = true +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = do_not_ignore +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + [*.cs] # Disable enforcement of items covered by StyleCop Analyzers dotnet_style_qualification_for_field = false:none diff --git a/eng/Versions.props b/eng/Versions.props index 216fe8140..8d3bd6b04 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -13,58 +13,63 @@ 3.8.0-4.20464.1 16.1.1 - - - - 3.0.0 - 3.3.1 - 3.3.1 - 3.3.1 - 3.3.1 - 3.3.1 + + + + + + 3.3.2 + 3.8.0 + 3.8.0 + 3.8.0 + 3.8.0 + 3.8.0 + - - 7.0.3300 - 12.0.4 - 8.0.1 8.0.0 - 16.4.280 - 16.4.280 - 16.4.280 - 16.4.280 - 7.10.6071 - 16.5.29911.84 - 16.5.29911.84 - 7.10.6072 - 8.0.50728 - 9.0.30730 - 10.0.30320 - 11.0.61031 - 12.1.30329 - 14.3.26929 - 15.7.1 - 16.4.280 - 16.4.280 - 7.10.6071 - 16.4.280 - 16.4.280 - 16.5.29903.186 - 16.5.132 + 8.0.1 + 2.7.100 + 16.8.239 + 16.8.239 + 16.8.239 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30329.63 + 16.8.239 + 16.7.9 + 16.7.30329.88 + 16.7.30329.88 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30328.74 + 16.7.30328.74 + 16.8.239 + 16.8.239 + 16.7.30328.74 + 16.8.239 + 16.8.55 + 16.3.23 + 16.8.33 5.6.0 - 2.3.99 + 2.6.121 + 16.7.30508.193 + 12.0.4 + - 1.3.1 - 1.1.0 - 1.4.2 1.4.4 + 2.6.1 3.8.0 1.0.1-beta1.20374.2 1.2.7 0.1.49-beta + 2.9.8 1.2.0-beta.164 diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 682ceac12..a6bde5ece 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -13,14 +13,16 @@ - 15.5 + 16 - 8.0 + 9 + 9999 + enable @@ -39,4 +41,4 @@ $(CopyrightMicrosoft) MIT - \ No newline at end of file + diff --git a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/Roslyn.SDK.Template.Wizard.csproj b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/Roslyn.SDK.Template.Wizard.csproj index 71eac5d5a..b06da45af 100644 --- a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/Roslyn.SDK.Template.Wizard.csproj +++ b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/Roslyn.SDK.Template.Wizard.csproj @@ -7,26 +7,17 @@ - - - - - - + + - - + + + - - - - - - - - + + diff --git a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKAnalyzerTemplateWizard.cs b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKAnalyzerTemplateWizard.cs index eb1a6acd6..b0a5791a5 100644 --- a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKAnalyzerTemplateWizard.cs +++ b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKAnalyzerTemplateWizard.cs @@ -4,7 +4,7 @@ public class RoslynSDKAnalyzerTemplateWizard : RoslynSDKChildTemplateWizard { - public static Project Project { get; private set; } + public static Project? Project { get; private set; } public override void OnProjectFinishedGenerating(Project project) { diff --git a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKChildTemplateWizard.InterfaceMembers.cs b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKChildTemplateWizard.InterfaceMembers.cs index 0d4a299e7..8d6ba5d8f 100644 --- a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKChildTemplateWizard.InterfaceMembers.cs +++ b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKChildTemplateWizard.InterfaceMembers.cs @@ -18,7 +18,9 @@ public void ProjectItemFinishedGenerating(ProjectItem projectItem) { } public void RunStarted(object automationObject, Dictionary replacementsDictionary, WizardRunKind runKind, object[] customParams) { ThreadHelper.ThrowIfNotOnUIThread(); - - OnRunStarted(automationObject as DTE, replacementsDictionary, runKind, customParams); + if (automationObject is DTE dte) + { + OnRunStarted(dte, replacementsDictionary, runKind, customParams); + } } } diff --git a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKCodeFixTemplateWizard.cs b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKCodeFixTemplateWizard.cs index e46896a57..f19a27dea 100644 --- a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKCodeFixTemplateWizard.cs +++ b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKCodeFixTemplateWizard.cs @@ -6,7 +6,7 @@ public class RoslynSDKCodeFixTemplateWizard : RoslynSDKChildTemplateWizard { - public static Project Project { get; private set; } + public static Project? Project { get; private set; } public override void OnProjectFinishedGenerating(Project project) { diff --git a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKRootTemplateWizard.InterfaceMembers.cs b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKRootTemplateWizard.InterfaceMembers.cs index 51e48abb4..d6559c2fd 100644 --- a/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKRootTemplateWizard.InterfaceMembers.cs +++ b/src/VisualStudio.Roslyn.SDK/Roslyn.SDK.Template.Wizard/RoslynSDKRootTemplateWizard.InterfaceMembers.cs @@ -16,6 +16,9 @@ public void RunStarted(object automationObject, Dictionary repla { ThreadHelper.ThrowIfNotOnUIThread(); - OnRunStarted(automationObject as DTE, replacementsDictionary, runKind, customParams); + if (automationObject is DTE dte) + { + OnRunStarted(dte, replacementsDictionary, runKind, customParams); + } } } diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ColorPickerViewModel.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ColorPickerViewModel.cs index 96c9f4687..269184d4e 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ColorPickerViewModel.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ColorPickerViewModel.cs @@ -184,7 +184,7 @@ private void UpdateColorComponents() } #region NotifyPropertyChanged - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; private bool SetProperty(ref T backingField, T value, [CallerMemberName] string propertyName = "") { if (EqualityComparer.Default.Equals(backingField, value)) diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ControlExtensions.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ControlExtensions.cs index 81cefbb70..e09144d91 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ControlExtensions.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/ControlExtensions.cs @@ -29,7 +29,7 @@ internal static Color GetColorAtOffset(this GradientStopCollection collection, d } GradientStop left = stops[0]; - GradientStop right = null; + GradientStop? right = null; foreach (GradientStop stop in stops) { @@ -42,6 +42,11 @@ internal static Color GetColorAtOffset(this GradientStopCollection collection, d left = stop; } + if (right is null) + { + return left.Color; + } + double percent = Math.Round((offset - left.Offset) / (right.Offset - left.Offset), 3); byte a = (byte)((right.Color.A - left.Color.A) * percent + left.Color.A); byte r = (byte)((right.Color.R - left.Color.R) * percent + left.Color.R); diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/Roslyn.SyntaxVisualizer.Control.csproj b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/Roslyn.SyntaxVisualizer.Control.csproj index b49c1a4c9..6882f3400 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/Roslyn.SyntaxVisualizer.Control.csproj +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/Roslyn.SyntaxVisualizer.Control.csproj @@ -11,16 +11,25 @@ - - - - - + + + + + + + + + - + + + + + + diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SymbolDisplay/BasePropertyGridAdapter.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SymbolDisplay/BasePropertyGridAdapter.cs index f2299d455..d9470090a 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SymbolDisplay/BasePropertyGridAdapter.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SymbolDisplay/BasePropertyGridAdapter.cs @@ -12,12 +12,12 @@ internal abstract class BasePropertyGridAdapter : ICustomTypeDescriptor public virtual string GetComponentName() => TypeDescriptor.GetClassName(this, true); public virtual TypeConverter GetConverter() => TypeDescriptor.GetConverter(this, true); public virtual EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this, true); - public virtual PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this, true); + public virtual PropertyDescriptor? GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this, true); public virtual object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(this, editorBaseType, true); public virtual EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(this, true); public virtual EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(this, attributes, true); public virtual PropertyDescriptorCollection GetProperties() => TypeDescriptor.GetProperties(this, true); public virtual PropertyDescriptorCollection GetProperties(Attribute[] attributes) => TypeDescriptor.GetProperties(this, attributes, true); - public virtual object GetPropertyOwner(PropertyDescriptor pd) => null; + public virtual object? GetPropertyOwner(PropertyDescriptor pd) => null; } } diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxKindHelper.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxKindHelper.cs index 15ce4a261..6d7ac4f45 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxKindHelper.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxKindHelper.cs @@ -12,67 +12,23 @@ public static class SyntaxKindHelper // SyntaxNode / SyntaxToken / SyntaxTrivia. public static string GetKind(this SyntaxNodeOrToken nodeOrToken) - { - var kind = string.Empty; - - if (nodeOrToken.IsNode) - { - kind = nodeOrToken.AsNode().GetKind(); - } - else - { - kind = nodeOrToken.AsToken().GetKind(); - } - - return kind; - } + => nodeOrToken.AsNode() is SyntaxNode node + ? node.GetKind() + : nodeOrToken.AsToken().GetKind(); public static string GetKind(this SyntaxNode node) - { - var kind = string.Empty; - - if (node.Language == LanguageNames.CSharp) - { - kind = CSharpExtensions.Kind(node).ToString(); - } - else - { - kind = VisualBasicExtensions.Kind(node).ToString(); - } - - return kind; - } + => node.Language == LanguageNames.CSharp + ? CSharpExtensions.Kind(node).ToString() + : VisualBasicExtensions.Kind(node).ToString(); public static string GetKind(this SyntaxToken token) - { - var kind = string.Empty; - - if (token.Language == LanguageNames.CSharp) - { - kind = CSharpExtensions.Kind(token).ToString(); - } - else - { - kind = VisualBasicExtensions.Kind(token).ToString(); - } - - return kind; - } + => token.Language == LanguageNames.CSharp + ? CSharpExtensions.Kind(token).ToString() + : VisualBasicExtensions.Kind(token).ToString(); public static string GetKind(this SyntaxTrivia trivia) - { - var kind = string.Empty; - - if (trivia.Language == LanguageNames.CSharp) - { - kind = CSharpExtensions.Kind(trivia).ToString(); - } - else - { - kind = VisualBasicExtensions.Kind(trivia).ToString(); - } - - return kind; - } + => trivia.Language == LanguageNames.CSharp + ? CSharpExtensions.Kind(trivia).ToString() + : VisualBasicExtensions.Kind(trivia).ToString(); } } diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxVisualizerControl.xaml.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxVisualizerControl.xaml.cs index 507834971..fd5f6ea10 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxVisualizerControl.xaml.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/SyntaxVisualizerControl.xaml.cs @@ -3,17 +3,16 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.ComponentModel.Composition; using System.Globalization; using System.Linq; using System.Windows; using System.Windows.Controls; -using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; + using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Text; @@ -23,7 +22,9 @@ using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Text.Adornments; using Microsoft.VisualStudio.Text.Classification; + using Roslyn.SyntaxVisualizer.Control.SymbolDisplay; + using SystemInformation = System.Windows.Forms.SystemInformation; namespace Roslyn.SyntaxVisualizer.Control @@ -52,16 +53,16 @@ private class SyntaxTag { internal TextSpan Span { get; set; } internal TextSpan FullSpan { get; set; } - internal TreeViewItem ParentItem { get; set; } - internal string Kind { get; set; } - internal SyntaxNode SyntaxNode { get; set; } + internal TreeViewItem? ParentItem { get; set; } + internal string? Kind { get; set; } + internal SyntaxNode? SyntaxNode { get; set; } internal SyntaxToken SyntaxToken { get; set; } internal SyntaxTrivia SyntaxTrivia { get; set; } internal SyntaxCategory Category { get; set; } } #region Private State - private TreeViewItem _currentSelection; + private TreeViewItem? _currentSelection; private bool _isNavigatingFromSourceToTree; private bool _isNavigatingFromTreeToSource; private readonly System.Windows.Forms.PropertyGrid _propertyGrid; @@ -94,26 +95,26 @@ private class SyntaxTag /// we temporarily clear the specified foreground color and restore it when the item is /// unselected. This field is used to save and restore that foreground color. /// - private Brush _currentSelectionUnselectedForeground; + private Brush? _currentSelectionUnselectedForeground; private ImmutableArray classifiedSpans; #endregion #region Public Properties, Events - public SyntaxTree SyntaxTree { get; private set; } - public SemanticModel SemanticModel { get; private set; } + public SyntaxTree? SyntaxTree { get; private set; } + public SemanticModel? SemanticModel { get; private set; } public bool IsLazy { get; private set; } - public delegate void SyntaxNodeDelegate(SyntaxNode node); - public event SyntaxNodeDelegate SyntaxNodeDirectedGraphRequested; - public event SyntaxNodeDelegate SyntaxNodeNavigationToSourceRequested; + public delegate void SyntaxNodeDelegate(SyntaxNode? node); + public event SyntaxNodeDelegate? SyntaxNodeDirectedGraphRequested; + public event SyntaxNodeDelegate? SyntaxNodeNavigationToSourceRequested; public delegate void SyntaxTokenDelegate(SyntaxToken token); - public event SyntaxTokenDelegate SyntaxTokenDirectedGraphRequested; - public event SyntaxTokenDelegate SyntaxTokenNavigationToSourceRequested; + public event SyntaxTokenDelegate? SyntaxTokenDirectedGraphRequested; + public event SyntaxTokenDelegate? SyntaxTokenNavigationToSourceRequested; public delegate void SyntaxTriviaDelegate(SyntaxTrivia trivia); - public event SyntaxTriviaDelegate SyntaxTriviaDirectedGraphRequested; - public event SyntaxTriviaDelegate SyntaxTriviaNavigationToSourceRequested; + public event SyntaxTriviaDelegate? SyntaxTriviaDirectedGraphRequested; + public event SyntaxTriviaDelegate? SyntaxTriviaNavigationToSourceRequested; private ClassifiedSpan? _classifiedSpan; public ClassifiedSpan? ClassifiedSpan @@ -142,7 +143,10 @@ public ClassifiedSpan? ClassifiedSpan { colorLabel.Visibility = Visibility.Visible; colorPickerGrid.Visibility = Visibility.Visible; - colorPickerButton.Background = new SolidColorBrush(color.Value); + if (color is not null) + { + colorPickerButton.Background = new SolidColorBrush(color.Value); + } var textValue = _classifiedSpan?.ClassificationType; if (string.IsNullOrEmpty(textValue)) @@ -219,7 +223,11 @@ private void ColorPickerButton_Click(object sender, RoutedEventArgs e) if (popup.ShowDialog() == true) { - FontsAndColorsHelper.UpdateClassificationColor(_classifiedSpan.Value, popup.Color); + if (_classifiedSpan is not null) + { + FontsAndColorsHelper.UpdateClassificationColor(_classifiedSpan.Value, popup.Color); + } + colorPickerButton.Background = new SolidColorBrush(popup.Color); } @@ -323,7 +331,7 @@ public void Clear() // the children for any given item are only populated when the item is selected. If lazy is // false then the entire tree is populated at once (and this can result in bad performance when // displaying large trees). - public void DisplaySyntaxTree(SyntaxTree tree, SemanticModel model = null, bool lazy = true, Workspace workspace = null) + public void DisplaySyntaxTree(SyntaxTree tree, SemanticModel? model = null, bool lazy = true, Workspace? workspace = null) { if (tree != null) { @@ -347,7 +355,7 @@ public void DisplaySyntaxTree(SyntaxTree tree, SemanticModel model = null, bool // the children for any given item are only populated when the item is selected. If lazy is // false then the entire tree is populated at once (and this can result in bad performance when // displaying large trees). - public void DisplaySyntaxNode(SyntaxNode node, SemanticModel model = null, bool lazy = true) + public void DisplaySyntaxNode(SyntaxNode node, SemanticModel? model = null, bool lazy = true) { if (node != null) { @@ -359,11 +367,11 @@ public void DisplaySyntaxNode(SyntaxNode node, SemanticModel model = null, bool } // Select the SyntaxNode / SyntaxToken / SyntaxTrivia whose position best matches the supplied position. - public bool NavigateToBestMatch(int position, string kind = null, + public bool NavigateToBestMatch(int position, string? kind = null, SyntaxCategory category = SyntaxCategory.None, bool highlightMatch = false) { - TreeViewItem match = null; + TreeViewItem? match = null; if (treeView.HasItems && !_isNavigatingFromTreeToSource) { @@ -372,20 +380,18 @@ public bool NavigateToBestMatch(int position, string kind = null, _isNavigatingFromSourceToTree = false; } - var matchFound = match != null; + if (!highlightMatch || match is null) + return false; - if (highlightMatch && matchFound) - { - match.Background = Brushes.Yellow; - match.BorderBrush = Brushes.Black; - match.BorderThickness = s_defaultBorderThickness; - } + match.Background = Brushes.Yellow; + match.BorderBrush = Brushes.Black; + match.BorderThickness = s_defaultBorderThickness; - return matchFound; + return true; } // Select the SyntaxNode / SyntaxToken / SyntaxTrivia whose span best matches the supplied span. - public bool NavigateToBestMatch(int start, int length, string kind = null, + public bool NavigateToBestMatch(int start, int length, string? kind = null, SyntaxCategory category = SyntaxCategory.None, bool highlightMatch = false) { @@ -393,11 +399,11 @@ public bool NavigateToBestMatch(int start, int length, string kind = null, } // Select the SyntaxNode / SyntaxToken / SyntaxTrivia whose span best matches the supplied span. - public bool NavigateToBestMatch(TextSpan span, string kind = null, + public bool NavigateToBestMatch(TextSpan span, string? kind = null, SyntaxCategory category = SyntaxCategory.None, bool highlightMatch = false) { - TreeViewItem match = null; + TreeViewItem? match = null; if (treeView.HasItems && !_isNavigatingFromTreeToSource) { @@ -406,16 +412,14 @@ public bool NavigateToBestMatch(TextSpan span, string kind = null, _isNavigatingFromSourceToTree = false; } - var matchFound = match != null; + if (!highlightMatch || match is null) + return false; - if (highlightMatch && matchFound) - { - match.Background = Brushes.Yellow; - match.BorderBrush = Brushes.Black; - match.BorderThickness = s_defaultBorderThickness; - } + match.Background = Brushes.Yellow; + match.BorderBrush = Brushes.Black; + match.BorderThickness = s_defaultBorderThickness; - return matchFound; + return true; } #endregion @@ -447,7 +451,7 @@ private void DeepCollapse(TreeViewItem item) } // Ensure that the supplied treeview item and all its ancestors are expanded. - private void ExpandPathTo(TreeViewItem item) + private void ExpandPathTo(TreeViewItem? item) { if (item != null) { @@ -457,10 +461,10 @@ private void ExpandPathTo(TreeViewItem item) } // Select the SyntaxNode / SyntaxToken / SyntaxTrivia whose position best matches the supplied position. - private TreeViewItem NavigateToBestMatch(TreeViewItem current, int position, string kind = null, + private TreeViewItem? NavigateToBestMatch(TreeViewItem current, int position, string? kind = null, SyntaxCategory category = SyntaxCategory.None) { - TreeViewItem match = null; + TreeViewItem? match = null; if (current != null) { @@ -490,10 +494,10 @@ private TreeViewItem NavigateToBestMatch(TreeViewItem current, int position, str } // Select the SyntaxNode / SyntaxToken / SyntaxTrivia whose span best matches the supplied span. - private TreeViewItem NavigateToBestMatch(TreeViewItem current, TextSpan span, string kind = null, + private TreeViewItem? NavigateToBestMatch(TreeViewItem current, TextSpan span, string? kind = null, SyntaxCategory category = SyntaxCategory.None) { - TreeViewItem match = null; + TreeViewItem? match = null; if (current != null) { @@ -669,8 +673,13 @@ static IEnumerable GetOperationInterfaces(IOperation operation) } } - private void AddNode(TreeViewItem parentItem, SyntaxNode node) + private void AddNode(TreeViewItem? parentItem, SyntaxNode? node) { + if (node is null) + { + return; + } + var kind = node.GetKind(); var tag = new SyntaxTag() { @@ -724,10 +733,13 @@ private void AddNode(TreeViewItem parentItem, SyntaxNode node) // Remove placeholder child and populate real children. item.Items.RemoveAt(0); - var operation = SemanticModel.GetOperation(node); - if (operation is { Parent: null }) + if (SemanticModel is not null) { - AddOperation(item, operation); + var operation = SemanticModel.GetOperation(node); + if (operation is { Parent: null }) + { + AddOperation(item, operation); + } } foreach (var child in node.ChildNodesAndTokens()) @@ -988,7 +1000,7 @@ private TreeViewItem CreateTreeViewItem(SyntaxTag tag, string text, bool contain #endregion #region Private Helpers - Other - private void DisplaySymbolInPropertyGrid(ISymbol symbol) + private void DisplaySymbolInPropertyGrid(ISymbol? symbol) { if (symbol == null) { @@ -1010,7 +1022,7 @@ private void DisplaySymbolInPropertyGrid(ISymbol symbol) } } - private static TreeViewItem FindTreeViewItem(DependencyObject source) + private static TreeViewItem? FindTreeViewItem(DependencyObject source) { while (source != null && !(source is TreeViewItem)) { @@ -1024,7 +1036,7 @@ private static TreeViewItem FindTreeViewItem(DependencyObject source) } } - return (TreeViewItem)source; + return (TreeViewItem?)source; } #endregion @@ -1133,7 +1145,7 @@ private void SymbolDetailsMenuItem_Click(object sender, RoutedEventArgs e) } var currentTag = (SyntaxTag)_currentSelection.Tag; - if ((SemanticModel != null) && (currentTag.Category == SyntaxCategory.SyntaxNode)) + if ((SemanticModel != null) && (currentTag.Category == SyntaxCategory.SyntaxNode) && currentTag.SyntaxNode is not null) { var symbol = SemanticModel.GetSymbolInfo(currentTag.SyntaxNode).Symbol; if (symbol == null) @@ -1159,6 +1171,12 @@ private void TypeSymbolDetailsMenuItem_Click(object sender, RoutedEventArgs e) } var currentTag = (SyntaxTag)_currentSelection.Tag; + if (currentTag.SyntaxNode is null) + { + e.Handled = true; + return; + } + if ((SemanticModel != null) && (currentTag.Category == SyntaxCategory.SyntaxNode)) { var symbol = SemanticModel.GetTypeInfo(currentTag.SyntaxNode).Type; @@ -1175,6 +1193,12 @@ private void ConvertedTypeSymbolDetailsMenuItem_Click(object sender, RoutedEvent } var currentTag = (SyntaxTag)_currentSelection.Tag; + if (currentTag.SyntaxNode is null) + { + e.Handled = true; + return; + } + if ((SemanticModel != null) && (currentTag.Category == SyntaxCategory.SyntaxNode)) { var symbol = SemanticModel.GetTypeInfo(currentTag.SyntaxNode).ConvertedType; @@ -1191,6 +1215,12 @@ private void AliasSymbolDetailsMenuItem_Click(object sender, RoutedEventArgs e) } var currentTag = (SyntaxTag)_currentSelection.Tag; + if (currentTag.SyntaxNode is null) + { + e.Handled = true; + return; + } + if ((SemanticModel != null) && (currentTag.Category == SyntaxCategory.SyntaxNode)) { var symbol = SemanticModel.GetAliasInfo(currentTag.SyntaxNode); @@ -1207,7 +1237,9 @@ private void ConstantValueDetailsMenuItem_Click(object sender, RoutedEventArgs e } var currentTag = (SyntaxTag)_currentSelection.Tag; - if ((SemanticModel != null) && (currentTag.Category == SyntaxCategory.SyntaxNode)) + if (SemanticModel != null && + currentTag.Category == SyntaxCategory.SyntaxNode && + currentTag.SyntaxNode is not null) { var value = SemanticModel.GetConstantValue(currentTag.SyntaxNode); kindTextLabel.Visibility = Visibility.Hidden; diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/TabStopPanel.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/TabStopPanel.cs index b23843966..7add4f10d 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/TabStopPanel.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Control/TabStopPanel.cs @@ -14,13 +14,13 @@ namespace Roslyn.SyntaxVisualizer.Control internal class TabStopPanel : Panel { private readonly HwndHost _wpfHost; - private PropertyGrid _propertyGrid; + private PropertyGrid? _propertyGrid; public TabStopPanel(HwndHost wpfHost) { _wpfHost = wpfHost; } - public PropertyGrid PropertyGrid + public PropertyGrid? PropertyGrid { get => _propertyGrid; set diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.DgmlHelper/Roslyn.SyntaxVisualizer.DgmlHelper.vbproj b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.DgmlHelper/Roslyn.SyntaxVisualizer.DgmlHelper.vbproj index d54d6e607..262a8975c 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.DgmlHelper/Roslyn.SyntaxVisualizer.DgmlHelper.vbproj +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.DgmlHelper/Roslyn.SyntaxVisualizer.DgmlHelper.vbproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/HelperExtensionMethods.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/HelperExtensionMethods.cs index e580b801e..91be1f6cb 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/HelperExtensionMethods.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/HelperExtensionMethods.cs @@ -12,9 +12,9 @@ namespace Roslyn.SyntaxVisualizer.Extension { internal static class HelperExtensionMethods { - internal static IWpfTextView ToWpfTextView(this IVsWindowFrame vsWindowFrame) + internal static IWpfTextView? ToWpfTextView(this IVsWindowFrame vsWindowFrame) { - IWpfTextView wpfTextView = null; + IWpfTextView? wpfTextView = null; var vsTextView = VsShellUtilities.GetTextView(vsWindowFrame); if (vsTextView != null) diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/Roslyn.SyntaxVisualizer.Extension.csproj b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/Roslyn.SyntaxVisualizer.Extension.csproj index 1619cb016..9baf55972 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/Roslyn.SyntaxVisualizer.Extension.csproj +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/Roslyn.SyntaxVisualizer.Extension.csproj @@ -25,26 +25,27 @@ - - - - - + + + + - + + - - - + + + + + - - + - + diff --git a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/SyntaxVisualizerContainer.xaml.cs b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/SyntaxVisualizerContainer.xaml.cs index 72c5c3a93..ca8f3cfd9 100644 --- a/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/SyntaxVisualizerContainer.xaml.cs +++ b/src/VisualStudio.Roslyn.SDK/SyntaxVisualizer/Roslyn.SyntaxVisualizer.Extension/SyntaxVisualizerContainer.xaml.cs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Immutable; using System.IO; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; using System.Xml.Linq; + +using Microsoft; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio; using Microsoft.VisualStudio.ComponentModelHost; @@ -17,6 +17,7 @@ using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Text.Editor; + using Roslyn.SyntaxVisualizer.DgmlHelper; namespace Roslyn.SyntaxVisualizer.Extension @@ -26,11 +27,11 @@ namespace Roslyn.SyntaxVisualizer.Extension internal partial class SyntaxVisualizerContainer : UserControl, IVsRunningDocTableEvents, IVsSolutionEvents, IDisposable { private readonly SyntaxVisualizerToolWindow parent; - private IWpfTextView activeWpfTextView; - private IClassificationFormatMap activeClassificationFormatMap; - private IEditorFormatMap activeEditorFormatMap; - private SyntaxTree activeSyntaxTree; - private DispatcherTimer typingTimer; + private IWpfTextView? activeWpfTextView; + private IClassificationFormatMap? activeClassificationFormatMap; + private IEditorFormatMap? activeEditorFormatMap; + private SyntaxTree? activeSyntaxTree; + private DispatcherTimer? typingTimer; private const string CSharpContentType = "CSharp"; private const string VisualBasicContentType = "Basic"; @@ -44,7 +45,7 @@ internal SyntaxVisualizerContainer(SyntaxVisualizerToolWindow parent) InitializeRunningDocumentTable(); - var shellService = GetService(GlobalServiceProvider); + var shellService = GetRequiredMefService(GlobalServiceProvider); if (shellService != null) { @@ -62,14 +63,14 @@ internal SyntaxVisualizerContainer(SyntaxVisualizerToolWindow parent) UpdateThemedColors(); - syntaxVisualizer.SyntaxNodeNavigationToSourceRequested += node => NavigateToSource(node.Span); + syntaxVisualizer.SyntaxNodeNavigationToSourceRequested += node => NavigateToSource(node?.Span); syntaxVisualizer.SyntaxTokenNavigationToSourceRequested += token => NavigateToSource(token.Span); syntaxVisualizer.SyntaxTriviaNavigationToSourceRequested += trivia => NavigateToSource(trivia.Span); } internal void UpdateThemedColors() { - var uiShellService = GetService(GlobalServiceProvider); + var uiShellService = GetRequiredMefService(GlobalServiceProvider); if (uiShellService != null) { syntaxVisualizer.SetPropertyGridColors(uiShellService); @@ -77,8 +78,11 @@ internal void UpdateThemedColors() if (activeClassificationFormatMap != null && activeEditorFormatMap != null) { - var classificationTypeRegistryService = GetMefService(); - syntaxVisualizer.SetTreeViewColors(classificationTypeRegistryService, activeClassificationFormatMap, activeEditorFormatMap); + var classificationTypeRegistryService = GetRequiredMefService(); + if (classificationTypeRegistryService is not null) + { + syntaxVisualizer.SetTreeViewColors(classificationTypeRegistryService, activeClassificationFormatMap, activeEditorFormatMap); + } } } @@ -121,7 +125,7 @@ internal void Clear() } #region Helpers - GetService - private static Microsoft.VisualStudio.OLE.Interop.IServiceProvider globalServiceProvider; + private static Microsoft.VisualStudio.OLE.Interop.IServiceProvider? globalServiceProvider; private static Microsoft.VisualStudio.OLE.Interop.IServiceProvider GlobalServiceProvider { get @@ -138,11 +142,11 @@ private static Microsoft.VisualStudio.OLE.Interop.IServiceProvider GlobalService } } - private TServiceInterface GetService() + private TServiceInterface? GetService() where TServiceInterface : class where TService : class { - TServiceInterface service = null; + TServiceInterface? service = null; if (parent != null) { @@ -152,12 +156,12 @@ private TServiceInterface GetService() return service; } - private static object GetService( + private static object? GetService( Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider, Guid guidService, bool unique) { var guidInterface = VSConstants.IID_IUnknown; var ptr = IntPtr.Zero; - object service = null; + object? service = null; #pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread if (serviceProvider.QueryService(ref guidService, ref guidInterface, out ptr) == 0 && @@ -184,39 +188,35 @@ private static object GetService( return service; } - private static TServiceInterface GetService( + private static TServiceInterface GetRequiredMefService( Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider) where TServiceInterface : class where TService : class { - return (TServiceInterface)GetService(serviceProvider, typeof(TService).GUID, false); + var service = (TServiceInterface?)GetService(serviceProvider, typeof(TService).GUID, false); + Assumes.Present(service); + return service; } - private static TServiceInterface GetMefService() where TServiceInterface : class + private static TServiceInterface GetRequiredMefService() where TServiceInterface : class { - TServiceInterface service = null; - var componentModel = GetService(GlobalServiceProvider); - - if (componentModel != null) - { - service = componentModel.GetService(); - } - - return service; + var componentModel = GetRequiredMefService(GlobalServiceProvider); + Assumes.Present(componentModel); + return componentModel.GetService(); ; } #endregion #region Helpers - Initialize and Dispose IVsRunningDocumentTable private uint runningDocumentTableCookie; - private IVsRunningDocumentTable runningDocumentTable; - private IVsRunningDocumentTable RunningDocumentTable + private IVsRunningDocumentTable? runningDocumentTable; + private IVsRunningDocumentTable? RunningDocumentTable { get { if (runningDocumentTable == null) { - runningDocumentTable = GetService(GlobalServiceProvider); + runningDocumentTable = GetRequiredMefService(GlobalServiceProvider); } return runningDocumentTable; @@ -238,7 +238,7 @@ void IDisposable.Dispose() if (runningDocumentTableCookie != 0) { #pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread - runningDocumentTable.UnadviseRunningDocTableEvents(runningDocumentTableCookie); + runningDocumentTable?.UnadviseRunningDocTableEvents(runningDocumentTableCookie); #pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread runningDocumentTableCookie = 0; } @@ -268,7 +268,7 @@ private void RefreshSyntaxVisualizer() var activeSemanticModel = ThreadHelper.JoinableTaskFactory.Run(() => document.GetSemanticModelAsync()); // Display the SyntaxTree. - if (contentType.IsOfType(VisualBasicContentType) || contentType.IsOfType(CSharpContentType)) + if (( contentType.IsOfType(VisualBasicContentType) || contentType.IsOfType(CSharpContentType) ) && activeSyntaxTree is not null) { syntaxVisualizer.DisplaySyntaxTree(activeSyntaxTree, activeSemanticModel, workspace: document.Project.Solution.Workspace); } @@ -290,11 +290,11 @@ private void NavigateFromSource() } // When user clicks on a particular item in the treeview select the corresponding text in the editor. - private void NavigateToSource(TextSpan span) + private void NavigateToSource(TextSpan? span) { - if (IsVisible && activeWpfTextView != null) + if (IsVisible && activeWpfTextView != null && span is TextSpan nonNullableSpan) { - var snapShotSpan = span.ToSnapshotSpan(activeWpfTextView.TextBuffer.CurrentSnapshot); + var snapShotSpan = nonNullableSpan.ToSnapshotSpan(activeWpfTextView.TextBuffer.CurrentSnapshot); // See SyntaxVisualizerToolWindow_GotFocus and SyntaxVisualizerToolWindow_LostFocus // for some notes about selection opacity and why it needs to be manipulated. @@ -337,7 +337,7 @@ private void HandleTextViewLostFocus(object sender, EventArgs e) private void HandleTypingTimerTimeout(object sender, EventArgs e) { - typingTimer.Stop(); + typingTimer?.Stop(); RefreshSyntaxVisualizer(); } @@ -359,12 +359,18 @@ int IVsRunningDocTableEvents.OnBeforeDocumentWindowShow(uint docCookie, int isFi activeWpfTextView.TextBuffer.Changed += HandleTextBufferChanged; activeWpfTextView.LostAggregateFocus += HandleTextViewLostFocus; - var classificationFormatMapService = GetMefService(); - var editorFormatMapService = GetMefService(); - activeClassificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(activeWpfTextView); - activeClassificationFormatMap.ClassificationFormatMappingChanged += HandleFormatMappingChanged; - activeEditorFormatMap = editorFormatMapService.GetEditorFormatMap(activeWpfTextView); - activeEditorFormatMap.FormatMappingChanged += HandleFormatMappingChanged; + var classificationFormatMapService = GetRequiredMefService(); + var editorFormatMapService = GetRequiredMefService(); + activeClassificationFormatMap = classificationFormatMapService?.GetClassificationFormatMap(activeWpfTextView); + if (activeClassificationFormatMap is not null) + { + activeClassificationFormatMap.ClassificationFormatMappingChanged += HandleFormatMappingChanged; + } + activeEditorFormatMap = editorFormatMapService?.GetEditorFormatMap(activeWpfTextView); + if (activeEditorFormatMap is not null) + { + activeEditorFormatMap.FormatMappingChanged += HandleFormatMappingChanged; + } UpdateThemedColors(); RefreshSyntaxVisualizer(); @@ -414,9 +420,9 @@ int IVsRunningDocTableEvents.OnAfterSave(uint docCookie) #endregion #region Event Handlers - Directed Syntax Graph / IVsSolutionEvents Events - private string dgmlFilePath; - private IVsFileChangeEx fileChangeService; - private IVsFileChangeEx FileChangeService + private string? dgmlFilePath; + private IVsFileChangeEx? fileChangeService; + private IVsFileChangeEx? FileChangeService { get { @@ -429,8 +435,8 @@ private IVsFileChangeEx FileChangeService } } - private IVsSolution solutionService; - private IVsSolution SolutionService + private IVsSolution? solutionService; + private IVsSolution? SolutionService { get { @@ -443,7 +449,7 @@ private IVsSolution SolutionService } } - private void DisplayDgml(XElement dgml) + private void DisplayDgml(XElement? dgml) { uint cookie; const int TRUE = -1; @@ -466,8 +472,9 @@ private void DisplayDgml(XElement dgml) #pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread out var docUIHierarchy, out var docItemId, out var docWindowFrame) && docWindowFrame != null) { + if (RunningDocumentTable is not null && #pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread - if (RunningDocumentTable.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, dgmlFilePath, + RunningDocumentTable.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, dgmlFilePath, #pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread out var docHierarchy, out docItemId, out var docDataIUnknownPointer, @@ -490,16 +497,16 @@ private void DisplayDgml(XElement dgml) // The below call ensures that there are no pop-ups from Visual Studio // prompting the user to reload the file each time it is changed. #pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread - FileChangeService.IgnoreFile(0, dgmlFilePath, TRUE); + FileChangeService?.IgnoreFile(0, dgmlFilePath, TRUE); #pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread // Update the file on disk with the new directed syntax graph. - dgml.Save(dgmlFilePath); + dgml?.Save(dgmlFilePath); // The below calls ensure that the file is refreshed inside Visual Studio // so that the latest contents are displayed to the user. #pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread - FileChangeService.SyncFile(dgmlFilePath); + FileChangeService?.SyncFile(dgmlFilePath); persistDocDataService.ReloadDocData((uint)_VSRELOADDOCDATA.RDD_IgnoreNextFileChange); #pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread @@ -519,7 +526,7 @@ private void DisplayDgml(XElement dgml) else { // Update the file on disk with the new directed syntax graph. - dgml.Save(dgmlFilePath); + dgml?.Save(dgmlFilePath); // Open the new directed syntax graph in the 'design' view. VsShellUtilities.OpenDocument( @@ -532,18 +539,18 @@ private void DisplayDgml(XElement dgml) // This ensures that the file won't be persisted in the .suo file and that it therefore won't get re-opened // when the solution is re-opened. #pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread - SolutionService.AdviseSolutionEvents(this, out cookie); + SolutionService?.AdviseSolutionEvents(this, out cookie); #pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread } } - private void DisplaySyntaxNodeDgml(SyntaxNode node) + private void DisplaySyntaxNodeDgml(SyntaxNode? node) { if (activeWpfTextView != null) { var snapshot = activeWpfTextView.TextBuffer.CurrentSnapshot; var contentType = snapshot.ContentType; - XElement dgml = null; + XElement? dgml = null; if (contentType.IsOfType(CSharpContentType) || contentType.IsOfType(VisualBasicContentType)) { @@ -560,7 +567,7 @@ private void DisplaySyntaxTokenDgml(SyntaxToken token) { var snapshot = activeWpfTextView.TextBuffer.CurrentSnapshot; var contentType = snapshot.ContentType; - XElement dgml = null; + XElement? dgml = null; if (contentType.IsOfType(CSharpContentType) || contentType.IsOfType(VisualBasicContentType)) { @@ -577,7 +584,7 @@ private void DisplaySyntaxTriviaDgml(SyntaxTrivia trivia) { var snapshot = activeWpfTextView.TextBuffer.CurrentSnapshot; var contentType = snapshot.ContentType; - XElement dgml = null; + XElement? dgml = null; if (contentType.IsOfType(CSharpContentType) || contentType.IsOfType(VisualBasicContentType)) { diff --git a/tests/VisualStudio.Roslyn.SDK/Directory.Build.props b/tests/VisualStudio.Roslyn.SDK/Directory.Build.props index 2c3ad8c9b..a5c0a7c0a 100644 --- a/tests/VisualStudio.Roslyn.SDK/Directory.Build.props +++ b/tests/VisualStudio.Roslyn.SDK/Directory.Build.props @@ -17,13 +17,13 @@ - 15.5 + 16 - 8 + 9 diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs index da5a38bde..03936d8d7 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs @@ -28,7 +28,7 @@ private async Task GetActiveVsTextViewAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var vsTextManager = await GetGlobalServiceAsync(); + var vsTextManager = await GetRequiredGlobalServiceAsync(); ErrorHandler.ThrowOnFailure(vsTextManager.GetActiveView(fMustHaveFocus: 1, pBuffer: null, ppView: out var vsTextView)); diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs index 21fea7306..63e8cbfb8 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs @@ -27,7 +27,7 @@ public async Task ShowBuildErrorsAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var errorList = await GetGlobalServiceAsync(); + var errorList = await GetRequiredGlobalServiceAsync(); errorList.AreBuildErrorSourceEntriesShown = true; errorList.AreOtherErrorSourceEntriesShown = false; errorList.AreErrorsShown = true; @@ -91,7 +91,7 @@ private async Task> GetErrorItemsAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var errorList = await GetGlobalServiceAsync(); + var errorList = await GetRequiredGlobalServiceAsync(); var args = await errorList.TableControl.ForceUpdateAsync(); return args.AllEntries.ToImmutableArray(); } diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs index f48968462..24f1d7433 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs @@ -7,10 +7,12 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; + using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; + using Task = System.Threading.Tasks.Task; namespace Microsoft.CodeAnalysis.Testing.InProcess @@ -30,25 +32,28 @@ protected async Task ExecuteCommandAsync(string commandName, string args = "") { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var dte = await GetGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(); dte.ExecuteCommand(commandName, args); } - protected async Task GetGlobalServiceAsync() + protected async Task GetRequiredGlobalServiceAsync() where TService : class where TInterface : class { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var serviceProvider = (IAsyncServiceProvider2)await AsyncServiceProvider.GlobalProvider.GetServiceAsync(typeof(SAsyncServiceProvider)); + var serviceProvider = (IAsyncServiceProvider2?)await AsyncServiceProvider.GlobalProvider.GetServiceAsync(typeof(SAsyncServiceProvider)); Assumes.Present(serviceProvider); - return (TInterface)await serviceProvider.GetServiceAsync(typeof(TService)); + + var @interface = (TInterface?)await serviceProvider.GetServiceAsync(typeof(TService)); + Assumes.Present(@interface); + return @interface; } protected async Task GetComponentModelServiceAsync() where TService : class { - var componentModel = await GetGlobalServiceAsync(); + var componentModel = await GetRequiredGlobalServiceAsync(); return componentModel.GetService(); } diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs index 4bbcf6c0a..8e311a9d2 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs @@ -31,7 +31,7 @@ private async Task IsSolutionOpenAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var solution = await GetGlobalServiceAsync(); + var solution = await GetRequiredGlobalServiceAsync(); ErrorHandler.ThrowOnFailure(solution.GetProperty((int)__VSPROPID.VSPROPID_IsSolutionOpen, out var isOpen)); return (bool)isOpen; } @@ -56,7 +56,7 @@ private async Task CloseSolutionAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var solution = await GetGlobalServiceAsync(); + var solution = await GetRequiredGlobalServiceAsync(); if (!await IsSolutionOpenAsync()) { return; @@ -98,7 +98,7 @@ private async Task CreateSolutionAsync(string solutionPath, string solutionName) var solutionFileName = Path.ChangeExtension(solutionName, ".sln"); Directory.CreateDirectory(solutionPath); - var solution = await GetGlobalServiceAsync(); + var solution = await GetRequiredGlobalServiceAsync(); ErrorHandler.ThrowOnFailure(solution.CreateSolution(solutionPath, solutionFileName, (uint)__VSCREATESOLUTIONFLAGS.CSF_SILENT)); ErrorHandler.ThrowOnFailure(solution.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0)); } @@ -112,7 +112,7 @@ public async Task SaveSolutionAsync() throw new InvalidOperationException("Cannot save solution when no solution is open."); } - var solution = await GetGlobalServiceAsync(); + var solution = await GetRequiredGlobalServiceAsync(); // Make sure the directory exists so the Save dialog doesn't appear ErrorHandler.ThrowOnFailure(solution.GetSolutionInfo(out var solutionDirectory, out _, out _)); @@ -135,7 +135,7 @@ private async Task GetDirectoryNameAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var dte = await GetGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(); var solution = (EnvDTE80.Solution2)dte.Solution; var solutionFullName = solution.FullName; var solutionFileFullPath = string.IsNullOrEmpty(solutionFullName) @@ -149,7 +149,7 @@ private async Task> GetCSharpProjectTemplate { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var dte = await GetGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(); var localeID = dte.LocaleID; var builder = ImmutableDictionary.CreateBuilder(); @@ -166,7 +166,7 @@ private async Task> GetVisualBasicProjectTem { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var dte = await GetGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(); var localeID = dte.LocaleID; var builder = ImmutableDictionary.CreateBuilder(); @@ -185,7 +185,7 @@ public async Task AddProjectAsync(string projectName, string projectTemplate, st var projectPath = Path.Combine(await GetDirectoryNameAsync(), projectName); var projectTemplatePath = await GetProjectTemplatePathAsync(projectTemplate, ConvertLanguageName(languageName)); - var solution = await GetGlobalServiceAsync(); + var solution = await GetRequiredGlobalServiceAsync(); ErrorHandler.ThrowOnFailure(solution.AddNewProjectFromTemplate(projectTemplatePath, null, null, projectPath, projectName, null, out _)); } @@ -193,7 +193,7 @@ private async Task GetProjectTemplatePathAsync(string projectTemplate, s { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var dte = await GetGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(); var solution = (EnvDTE80.Solution2)dte.Solution; if (string.Equals(languageName, "csharp", StringComparison.OrdinalIgnoreCase) @@ -215,7 +215,7 @@ public async Task RestoreNuGetPackagesAsync(CancellationToken cancellationToken) { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var dte = await GetGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(); var solution = (EnvDTE80.Solution2)dte.Solution; foreach (var project in solution.Projects.OfType()) { @@ -227,7 +227,7 @@ public async Task RestoreNuGetPackagesAsync(string projectName, CancellationToke { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var operationProgressStatus = await GetGlobalServiceAsync(); + var operationProgressStatus = await GetRequiredGlobalServiceAsync(); var stageStatus = operationProgressStatus.GetStageStatus(CommonOperationProgressStageIds.Intellisense); await stageStatus.WaitForCompletionAsync(); @@ -281,7 +281,7 @@ public async Task GetBuildOutputWindowPaneAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var outputWindow = await GetGlobalServiceAsync(); + var outputWindow = await GetRequiredGlobalServiceAsync(); ErrorHandler.ThrowOnFailure(outputWindow.GetPane(VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid, out var pane)); return pane; } @@ -290,7 +290,7 @@ private async Task WaitForBuildToFinishAsync(IVsOutputWindowPane buildOu { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var buildManager = await GetGlobalServiceAsync(); + var buildManager = await GetRequiredGlobalServiceAsync(); using var semaphore = new SemaphoreSlim(1); using var solutionEvents = new UpdateSolutionEvents(buildManager); @@ -330,7 +330,7 @@ private string CreateTemporaryPath() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - var dte = await GetGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(); var solution = (EnvDTE80.Solution2)dte.Solution; return solution.Projects.OfType().First( project => diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj index d8d0265eb..0c66af099 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj @@ -19,11 +19,22 @@ + + + + + + + + + + +