From 76a8c385ef6b949f46f86c853816768f8cfb401e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 9 Dec 2025 13:00:08 +0100 Subject: [PATCH 1/5] Remove unnecessary lightup code --- .../Analyzers/DeclarePublicApiAnalyzer.Impl.cs | 2 +- .../Analyzers/ITypeParameterSymbolExtensions.cs | 14 -------------- .../Core/Analyzers/ITypeSymbolExtensions.cs | 14 -------------- 3 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeParameterSymbolExtensions.cs delete mode 100644 src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeSymbolExtensions.cs diff --git a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs index 7324bc17a418c..1871f994f9f74 100644 --- a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs +++ b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs @@ -1039,7 +1039,7 @@ public static bool VisitNamedTypeDeclaration(INamedTypeSymbol symbol) private static bool CheckTypeParameterConstraints(ITypeParameterSymbol symbol) { - if (symbol.HasReferenceTypeConstraint() && + if (symbol.HasReferenceTypeConstraint && symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.None) { // where T : class~ diff --git a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeParameterSymbolExtensions.cs b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeParameterSymbolExtensions.cs deleted file mode 100644 index 1027223a1475d..0000000000000 --- a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeParameterSymbolExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.CodeAnalysis; - -namespace Analyzer.Utilities.Lightup -{ - internal static class ITypeParameterSymbolExtensions - { - public static bool HasReferenceTypeConstraint(this ITypeParameterSymbol typeParameterSymbol) - => typeParameterSymbol.HasReferenceTypeConstraint; - } -} diff --git a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeSymbolExtensions.cs b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeSymbolExtensions.cs deleted file mode 100644 index 7b0a93978b441..0000000000000 --- a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/ITypeSymbolExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.CodeAnalysis; - -namespace Analyzer.Utilities.Lightup -{ - internal static class ITypeSymbolExtensions - { - public static NullableAnnotation NullableAnnotation(this ITypeSymbol typeSymbol) - => typeSymbol.NullableAnnotation; - } -} From 10537606478adc2743626ae5bffe02aa1f39bf97 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 9 Dec 2025 13:03:15 +0100 Subject: [PATCH 2/5] Remove unnecessary lightup code --- .../CSharpWorkspaceExtensions.projitems | 1 - .../Extensions/ITypeSymbolExtensions.cs | 9 +++-- .../Lightup/NullableSyntaxAnnotationEx.cs | 33 ------------------- 3 files changed, 4 insertions(+), 39 deletions(-) delete mode 100644 src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Lightup/NullableSyntaxAnnotationEx.cs diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CSharpWorkspaceExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CSharpWorkspaceExtensions.projitems index 57b34ba5239ef..7a1dd6da4ebee 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CSharpWorkspaceExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CSharpWorkspaceExtensions.projitems @@ -88,7 +88,6 @@ - diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs index 7875d6cdcb1a6..0c822864bee16 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs @@ -8,12 +8,11 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Shared.Lightup; +using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Extensions; @@ -55,9 +54,9 @@ private static TypeSyntax GenerateTypeSyntax( { var additionalAnnotation = type.NullableAnnotation switch { - NullableAnnotation.None => NullableSyntaxAnnotationEx.Oblivious, - NullableAnnotation.Annotated => NullableSyntaxAnnotationEx.AnnotatedOrNotAnnotated, - NullableAnnotation.NotAnnotated => NullableSyntaxAnnotationEx.AnnotatedOrNotAnnotated, + NullableAnnotation.None => NullableSyntaxAnnotation.Oblivious, + NullableAnnotation.Annotated => NullableSyntaxAnnotation.AnnotatedOrNotAnnotated, + NullableAnnotation.NotAnnotated => NullableSyntaxAnnotation.AnnotatedOrNotAnnotated, _ => throw ExceptionUtilities.UnexpectedValue(type.NullableAnnotation), }; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Lightup/NullableSyntaxAnnotationEx.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Lightup/NullableSyntaxAnnotationEx.cs deleted file mode 100644 index 598089159b49d..0000000000000 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Lightup/NullableSyntaxAnnotationEx.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Reflection; - -#if !CODE_STYLE -using Microsoft.CodeAnalysis.CodeGeneration; -using Roslyn.Utilities; -#endif - -namespace Microsoft.CodeAnalysis.CSharp.Shared.Lightup; - -internal static class NullableSyntaxAnnotationEx -{ - public static SyntaxAnnotation? Oblivious { get; } - public static SyntaxAnnotation? AnnotatedOrNotAnnotated { get; } - - static NullableSyntaxAnnotationEx() - { - var nullableSyntaxAnnotation = typeof(Workspace).Assembly.GetType("Microsoft.CodeAnalysis.CodeGeneration.NullableSyntaxAnnotation", throwOnError: false); - if (nullableSyntaxAnnotation is object) - { - Oblivious = (SyntaxAnnotation?)nullableSyntaxAnnotation.GetField(nameof(Oblivious), BindingFlags.Static | BindingFlags.Public)?.GetValue(null); - AnnotatedOrNotAnnotated = (SyntaxAnnotation?)nullableSyntaxAnnotation.GetField(nameof(AnnotatedOrNotAnnotated), BindingFlags.Static | BindingFlags.Public)?.GetValue(null); - } - -#if !CODE_STYLE - Contract.ThrowIfFalse(ReferenceEquals(Oblivious, NullableSyntaxAnnotation.Oblivious)); - Contract.ThrowIfFalse(ReferenceEquals(AnnotatedOrNotAnnotated, NullableSyntaxAnnotation.AnnotatedOrNotAnnotated)); -#endif - } -} From 9b9647af116a761afe58fce1f53e6d5fd25cd6b8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 9 Dec 2025 13:05:49 +0100 Subject: [PATCH 3/5] Remove unnecessary lightup code --- .../Core/ExplicitAllocationAnalyzer.cs | 2 - .../Core/AbstractDoNotCopyValue.cs | 1 - .../Lightup/LightupHelpersTests.cs | 163 ------------ .../Compiler/Analyzer.Utilities.projitems | 1 - .../ComputationalComplexityMetrics.cs | 1 - .../Compiler/CodeMetrics/MetricsHelper.cs | 1 - .../Extensions/INamedTypeSymbolExtensions.cs | 2 - .../Extensions/IOperationExtensions.cs | 1 - .../Utilities/Compiler/Lightup/.editorconfig | 4 - .../Compiler/Lightup/LightupHelpers.cs | 232 ------------------ .../Extensions/ControlFlowGraphExtensions.cs | 3 - 11 files changed, 411 deletions(-) delete mode 100644 src/RoslynAnalyzers/Utilities.UnitTests/Lightup/LightupHelpersTests.cs delete mode 100644 src/RoslynAnalyzers/Utilities/Compiler/Lightup/.editorconfig delete mode 100644 src/RoslynAnalyzers/Utilities/Compiler/Lightup/LightupHelpers.cs diff --git a/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/ExplicitAllocationAnalyzer.cs b/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/ExplicitAllocationAnalyzer.cs index 2b2bc0b83769d..48d8338d6566c 100644 --- a/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/ExplicitAllocationAnalyzer.cs +++ b/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/ExplicitAllocationAnalyzer.cs @@ -4,9 +4,7 @@ using System; using System.Collections.Immutable; -using Analyzer.Utilities; using Analyzer.Utilities.Extensions; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; diff --git a/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractDoNotCopyValue.cs b/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractDoNotCopyValue.cs index 61cff0c849701..3a83f55ddf297 100644 --- a/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractDoNotCopyValue.cs +++ b/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractDoNotCopyValue.cs @@ -12,7 +12,6 @@ using System.Linq; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FlowAnalysis; diff --git a/src/RoslynAnalyzers/Utilities.UnitTests/Lightup/LightupHelpersTests.cs b/src/RoslynAnalyzers/Utilities.UnitTests/Lightup/LightupHelpersTests.cs deleted file mode 100644 index b3ccb2276251f..0000000000000 --- a/src/RoslynAnalyzers/Utilities.UnitTests/Lightup/LightupHelpersTests.cs +++ /dev/null @@ -1,163 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#nullable enable - -using System; -using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Threading; -using Analyzer.Utilities.Lightup; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Xunit; - -namespace Analyzer.Utilities.UnitTests.Lightup -{ - public class LightupHelpersTests - { - [Theory] - [InlineData(null)] - [InlineData(typeof(SyntaxNode))] - public void TestCanAccessNonExistentSyntaxProperty(Type? type) - { - var fallbackResult = new object(); - - var propertyAccessor = LightupHelpers.CreateSyntaxPropertyAccessor(type, "NonExistentProperty", fallbackResult); - Assert.NotNull(propertyAccessor); - Assert.Same(fallbackResult, propertyAccessor(SyntaxFactory.AccessorList())); - Assert.Throws(() => propertyAccessor(null!)); - - var withPropertyAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor(type, "NonExistentProperty", fallbackResult); - Assert.NotNull(withPropertyAccessor); - Assert.NotNull(withPropertyAccessor(SyntaxFactory.AccessorList(), fallbackResult)); - Assert.ThrowsAny(() => withPropertyAccessor(SyntaxFactory.AccessorList(), new object())); - Assert.Throws(() => withPropertyAccessor(null!, new object())); - } - - [Theory] - [InlineData(null)] - [InlineData(typeof(EmptySymbol))] - public void TestCanAccessNonExistentSymbolProperty(Type? type) - { - var fallbackResult = new object(); - - var propertyAccessor = LightupHelpers.CreateSymbolPropertyAccessor(type, "NonExistentProperty", fallbackResult); - Assert.NotNull(propertyAccessor); - Assert.Same(fallbackResult, propertyAccessor(new EmptySymbol())); - Assert.Throws(() => propertyAccessor(null!)); - - var withPropertyAccessor = LightupHelpers.CreateSymbolWithPropertyAccessor(type, "NonExistentProperty", fallbackResult); - Assert.NotNull(withPropertyAccessor); - Assert.NotNull(withPropertyAccessor(new EmptySymbol(), fallbackResult)); - Assert.ThrowsAny(() => withPropertyAccessor(new EmptySymbol(), new object())); - Assert.Throws(() => withPropertyAccessor(null!, new object())); - } - - [Theory] - [InlineData(null)] - [InlineData(typeof(SyntaxNode))] - public void TestCanAccessNonExistentMethodWithArgument(Type? type) - { - var fallbackResult = new object(); - - var accessor = LightupHelpers.CreateAccessorWithArgument(type, "parameterName", typeof(int), "argumentName", "NonExistentMethod", fallbackResult); - Assert.NotNull(accessor); - Assert.Same(fallbackResult, accessor(SyntaxFactory.AccessorList(), 0)); - Assert.Throws(() => accessor(null!, 0)); - } - - [Fact] - public void TestCreateSyntaxPropertyAccessor() - { - // The call *should* have been made with the first generic argument set to `BaseMethodDeclarationSyntax` - // instead of `MethodDeclarationSyntax`. - Assert.ThrowsAny(() => LightupHelpers.CreateSyntaxPropertyAccessor(typeof(BaseMethodDeclarationSyntax), nameof(BaseMethodDeclarationSyntax.Body), fallbackResult: null)); - - // The call *should* have been made with the second generic argument set to `ArrowExpressionClauseSyntax` - // instead of `BlockSyntax`. - Assert.ThrowsAny(() => LightupHelpers.CreateSyntaxPropertyAccessor(typeof(MethodDeclarationSyntax), nameof(MethodDeclarationSyntax.ExpressionBody), fallbackResult: null)); - } - - [Fact] - public void TestCreateSyntaxWithPropertyAccessor() - { - // The call *should* have been made with the first generic argument set to `BaseMethodDeclarationSyntax` - // instead of `MethodDeclarationSyntax`. - Assert.ThrowsAny(() => LightupHelpers.CreateSyntaxWithPropertyAccessor(typeof(BaseMethodDeclarationSyntax), nameof(BaseMethodDeclarationSyntax.Body), fallbackResult: null)); - - // The call *should* have been made with the second generic argument set to `ArrowExpressionClauseSyntax` - // instead of `BlockSyntax`. - Assert.ThrowsAny(() => LightupHelpers.CreateSyntaxWithPropertyAccessor(typeof(MethodDeclarationSyntax), nameof(MethodDeclarationSyntax.ExpressionBody), fallbackResult: null)); - } - - [SuppressMessage("MicrosoftCodeAnalysisCompatibility", "RS1009:Only internal implementations of this interface are allowed.", Justification = "Stub for testing.")] - private sealed class EmptySymbol : ISymbol - { - SymbolKind ISymbol.Kind => throw new NotImplementedException(); - string ISymbol.Language => throw new NotImplementedException(); - string ISymbol.Name => throw new NotImplementedException(); - string ISymbol.MetadataName => throw new NotImplementedException(); - ISymbol ISymbol.ContainingSymbol => throw new NotImplementedException(); - IAssemblySymbol ISymbol.ContainingAssembly => throw new NotImplementedException(); - IModuleSymbol ISymbol.ContainingModule => throw new NotImplementedException(); - INamedTypeSymbol ISymbol.ContainingType => throw new NotImplementedException(); - INamespaceSymbol ISymbol.ContainingNamespace => throw new NotImplementedException(); - bool ISymbol.IsDefinition => throw new NotImplementedException(); - bool ISymbol.IsStatic => throw new NotImplementedException(); - bool ISymbol.IsVirtual => throw new NotImplementedException(); - bool ISymbol.IsOverride => throw new NotImplementedException(); - bool ISymbol.IsAbstract => throw new NotImplementedException(); - bool ISymbol.IsSealed => throw new NotImplementedException(); - bool ISymbol.IsExtern => throw new NotImplementedException(); - bool ISymbol.IsImplicitlyDeclared => throw new NotImplementedException(); - bool ISymbol.CanBeReferencedByName => throw new NotImplementedException(); - ImmutableArray ISymbol.Locations => throw new NotImplementedException(); - ImmutableArray ISymbol.DeclaringSyntaxReferences => throw new NotImplementedException(); - Accessibility ISymbol.DeclaredAccessibility => throw new NotImplementedException(); - ISymbol ISymbol.OriginalDefinition => throw new NotImplementedException(); - bool ISymbol.HasUnsupportedMetadata => throw new NotImplementedException(); - - int ISymbol.MetadataToken => throw new NotImplementedException(); - - void ISymbol.Accept(SymbolVisitor visitor) - => throw new NotImplementedException(); - - TResult ISymbol.Accept(SymbolVisitor visitor) - => throw new NotImplementedException(); - - TResult ISymbol.Accept(SymbolVisitor visitor, TArgument argument) - => throw new NotImplementedException(); - - public bool Equals(ISymbol? other) - => throw new NotImplementedException(); - - ImmutableArray ISymbol.GetAttributes() - => throw new NotImplementedException(); - - string ISymbol.GetDocumentationCommentId() - => throw new NotImplementedException(); - - string ISymbol.GetDocumentationCommentXml(CultureInfo? preferredCulture, bool expandIncludes, CancellationToken cancellationToken) - => throw new NotImplementedException(); - - ImmutableArray ISymbol.ToDisplayParts(SymbolDisplayFormat? format) - => throw new NotImplementedException(); - - string ISymbol.ToDisplayString(SymbolDisplayFormat? format) - => throw new NotImplementedException(); - - ImmutableArray ISymbol.ToMinimalDisplayParts(SemanticModel semanticModel, int position, SymbolDisplayFormat? format) - => throw new NotImplementedException(); - - string ISymbol.ToMinimalDisplayString(SemanticModel semanticModel, int position, SymbolDisplayFormat? format) - => throw new NotImplementedException(); - - public bool Equals(ISymbol? other, SymbolEqualityComparer equalityComparer) - => throw new NotImplementedException(); - } - } -} diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Analyzer.Utilities.projitems b/src/RoslynAnalyzers/Utilities/Compiler/Analyzer.Utilities.projitems index d622e91de0928..12cc948722cd4 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/Analyzer.Utilities.projitems +++ b/src/RoslynAnalyzers/Utilities/Compiler/Analyzer.Utilities.projitems @@ -57,7 +57,6 @@ - diff --git a/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/ComputationalComplexityMetrics.cs b/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/ComputationalComplexityMetrics.cs index d96cb88b127cb..2e9c12ca7e7c2 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/ComputationalComplexityMetrics.cs +++ b/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/ComputationalComplexityMetrics.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Immutable; using System.Linq; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Operations; diff --git a/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/MetricsHelper.cs b/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/MetricsHelper.cs index 6c14b540e76d6..40083ae3be3a1 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/MetricsHelper.cs +++ b/src/RoslynAnalyzers/Utilities/Compiler/CodeMetrics/MetricsHelper.cs @@ -10,7 +10,6 @@ using System.Diagnostics; using System.Linq; using Analyzer.Utilities; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.PooledObjects; diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Extensions/INamedTypeSymbolExtensions.cs b/src/RoslynAnalyzers/Utilities/Compiler/Extensions/INamedTypeSymbolExtensions.cs index 7dc9e8a1753df..e94364e3f7984 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/Extensions/INamedTypeSymbolExtensions.cs +++ b/src/RoslynAnalyzers/Utilities/Compiler/Extensions/INamedTypeSymbolExtensions.cs @@ -7,9 +7,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis; namespace Analyzer.Utilities.Extensions diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Extensions/IOperationExtensions.cs b/src/RoslynAnalyzers/Utilities/Compiler/Extensions/IOperationExtensions.cs index d6a5cfe452507..8ba072e7eba4b 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/Extensions/IOperationExtensions.cs +++ b/src/RoslynAnalyzers/Utilities/Compiler/Extensions/IOperationExtensions.cs @@ -10,7 +10,6 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.FlowAnalysis; using Microsoft.CodeAnalysis.Operations; diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Lightup/.editorconfig b/src/RoslynAnalyzers/Utilities/Compiler/Lightup/.editorconfig deleted file mode 100644 index 17082ebd7e1c2..0000000000000 --- a/src/RoslynAnalyzers/Utilities/Compiler/Lightup/.editorconfig +++ /dev/null @@ -1,4 +0,0 @@ -[*.cs] - -# CA2201: Do not raise reserved exception types -dotnet_diagnostic.CA2201.severity = none \ No newline at end of file diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Lightup/LightupHelpers.cs b/src/RoslynAnalyzers/Utilities/Compiler/Lightup/LightupHelpers.cs deleted file mode 100644 index a103857a87f60..0000000000000 --- a/src/RoslynAnalyzers/Utilities/Compiler/Lightup/LightupHelpers.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using Microsoft.CodeAnalysis; - -namespace Analyzer.Utilities.Lightup -{ - internal static class LightupHelpers - { - private static readonly ConcurrentDictionary> s_supportedOperationWrappers = new(); - - internal static Func CreateOperationPropertyAccessor(Type? type, string propertyName, TProperty fallbackResult) - where TOperation : IOperation - => CreatePropertyAccessor(type, "operation", propertyName, fallbackResult); - - internal static Func CreateSyntaxPropertyAccessor(Type? type, string propertyName, TProperty fallbackResult) - where TSyntax : SyntaxNode - => CreatePropertyAccessor(type, "syntax", propertyName, fallbackResult); - - internal static Func CreateSymbolPropertyAccessor(Type? type, string propertyName, TProperty fallbackResult) - where TSymbol : ISymbol - => CreatePropertyAccessor(type, "symbol", propertyName, fallbackResult); - - private static Func CreatePropertyAccessor(Type? type, string parameterName, string propertyName, TProperty fallbackResult) - { - if (!TryGetProperty(type, propertyName, out var property)) - { - return instance => FallbackAccessor(instance, fallbackResult); - } - - var parameter = Expression.Parameter(typeof(T), parameterName); - Expression instance = - type.GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()) - ? parameter - : Expression.Convert(parameter, type); - - Expression result = Expression.Call(instance, property.GetMethod!); - if (!typeof(TProperty).GetTypeInfo().IsAssignableFrom(property.PropertyType.GetTypeInfo())) - { - result = Expression.Convert(result, typeof(TProperty)); - } - - Expression> expression = Expression.Lambda>(result, parameter); - return expression.Compile(); - - // Local function - static TProperty FallbackAccessor(T instance, TProperty fallbackResult) - { - if (instance is null) - { - // Unlike an extension method which would throw ArgumentNullException here, the light-up - // behavior needs to match behavior of the underlying property. - throw new NullReferenceException(); - } - - return fallbackResult; - } - } - - internal static Func CreateSyntaxWithPropertyAccessor(Type? type, string propertyName, TProperty fallbackResult) - where TSyntax : SyntaxNode - => CreateWithPropertyAccessor(type, "syntax", propertyName, fallbackResult); - - internal static Func CreateSymbolWithPropertyAccessor(Type? type, string propertyName, TProperty fallbackResult) - where TSymbol : ISymbol - => CreateWithPropertyAccessor(type, "symbol", propertyName, fallbackResult); - - private static Func CreateWithPropertyAccessor(Type? type, string parameterName, string propertyName, TProperty fallbackResult) - { - if (!TryGetProperty(type, propertyName, out var property)) - { - return (instance, value) => FallbackAccessor(instance, value, fallbackResult); - } - - var methodInfo = type.GetTypeInfo().GetDeclaredMethods("With" + propertyName) - .SingleOrDefault(m => !m.IsStatic && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType.Equals(property.PropertyType)); - if (methodInfo is null) - { - return (instance, value) => FallbackAccessor(instance, value, fallbackResult); - } - - var parameter = Expression.Parameter(typeof(T), parameterName); - var valueParameter = Expression.Parameter(typeof(TProperty), methodInfo.GetParameters()[0].Name); - Expression instance = - type.GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()) - ? parameter - : Expression.Convert(parameter, type); - Expression value = - property.PropertyType.GetTypeInfo().IsAssignableFrom(typeof(TProperty).GetTypeInfo()) - ? valueParameter - : Expression.Convert(valueParameter, property.PropertyType); - - Expression> expression = - Expression.Lambda>( - Expression.Call(instance, methodInfo, value), - parameter, - valueParameter); - return expression.Compile(); - - // Local function - static T FallbackAccessor(T instance, TProperty newValue, TProperty fallbackResult) - { - if (instance is null) - { - // Unlike an extension method which would throw ArgumentNullException here, the light-up - // behavior needs to match behavior of the underlying property. - throw new NullReferenceException(); - } - - if (Equals(newValue, fallbackResult)) - { - return instance; - } - - throw new NotSupportedException(); - } - } - - internal static Func CreateAccessorWithArgument(Type? type, string parameterName, Type argumentType, string argumentName, string methodName, TValue fallbackResult) - { - if (!TryGetMethod(type, methodName, out var method)) - { - return (instance, _) => FallbackAccessor(instance, fallbackResult); - } - - var parameter = Expression.Parameter(typeof(T), parameterName); - var argument = Expression.Parameter(typeof(TArg), argumentName); - Expression instance = - type.GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()) - ? parameter - : Expression.Convert(parameter, type); - Expression convertedArgument = - argumentType.GetTypeInfo().IsAssignableFrom(typeof(TArg).GetTypeInfo()) - ? argument - : Expression.Convert(argument, type); - - Expression result = Expression.Call(instance, method, convertedArgument); - if (!typeof(TValue).GetTypeInfo().IsAssignableFrom(method.ReturnType.GetTypeInfo())) - { - result = Expression.Convert(result, typeof(TValue)); - } - - Expression> expression = Expression.Lambda>(result, parameter, argument); - return expression.Compile(); - - // Local function - static TValue FallbackAccessor(T instance, TValue fallbackResult) - { - if (instance is null) - { - // Unlike an extension method which would throw ArgumentNullException here, the light-up - // behavior needs to match behavior of the underlying property. - throw new NullReferenceException(); - } - - return fallbackResult; - } - } - - private static void VerifyTypeArgument(Type type) - { - if (!typeof(T).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) - { - throw new InvalidOperationException(); - } - } - - private static void VerifyResultTypeCompatibility(Type resultType) - { - if (!typeof(TValue).GetTypeInfo().IsAssignableFrom(resultType.GetTypeInfo())) - { - if (resultType.GetTypeInfo().IsEnum - && typeof(TValue).GetTypeInfo().IsEnum - && Enum.GetUnderlyingType(typeof(TValue)).GetTypeInfo().IsAssignableFrom(Enum.GetUnderlyingType(resultType).GetTypeInfo())) - { - // Allow this - } - else - { - throw new InvalidOperationException(); - } - } - } - - private static bool TryGetProperty([NotNullWhen(true)] Type? type, string propertyName, [NotNullWhen(true)] out PropertyInfo? propertyInfo) - { - if (type is null) - { - propertyInfo = null; - return false; - } - - VerifyTypeArgument(type); - - propertyInfo = type.GetTypeInfo().GetDeclaredProperty(propertyName); - if (propertyInfo is null) - { - return false; - } - - VerifyResultTypeCompatibility(propertyInfo.PropertyType); - return true; - } - - private static bool TryGetMethod([NotNullWhen(true)] Type? type, string methodName, [NotNullWhen(true)] out MethodInfo? methodInfo) - { - if (type is null) - { - methodInfo = null; - return false; - } - - VerifyTypeArgument(type); - - methodInfo = type.GetTypeInfo().GetDeclaredMethod(methodName); - if (methodInfo is null) - { - return false; - } - - VerifyResultTypeCompatibility(methodInfo.ReturnType); - return true; - } - } -} diff --git a/src/RoslynAnalyzers/Utilities/FlowAnalysis/Extensions/ControlFlowGraphExtensions.cs b/src/RoslynAnalyzers/Utilities/FlowAnalysis/Extensions/ControlFlowGraphExtensions.cs index d79a7ab9b6d29..8b46e80eae596 100644 --- a/src/RoslynAnalyzers/Utilities/FlowAnalysis/Extensions/ControlFlowGraphExtensions.cs +++ b/src/RoslynAnalyzers/Utilities/FlowAnalysis/Extensions/ControlFlowGraphExtensions.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections.Generic; using System.Linq; -using Analyzer.Utilities.Extensions; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis.Operations; namespace Microsoft.CodeAnalysis.FlowAnalysis From fe5ec9091460d5195bc9c988c51d0fb6dac9bfd4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 9 Dec 2025 13:07:30 +0100 Subject: [PATCH 4/5] Remove unnecessary lightup code --- .../Analyzer.CSharp.Utilities.projitems | 1 - .../Compiler.CSharp/Lightup/SyntaxKindEx.cs | 14 -------------- 2 files changed, 15 deletions(-) delete mode 100644 src/RoslynAnalyzers/Utilities/Compiler.CSharp/Lightup/SyntaxKindEx.cs diff --git a/src/RoslynAnalyzers/Utilities/Compiler.CSharp/Analyzer.CSharp.Utilities.projitems b/src/RoslynAnalyzers/Utilities/Compiler.CSharp/Analyzer.CSharp.Utilities.projitems index a60042f946168..efd3b3e0e51cd 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler.CSharp/Analyzer.CSharp.Utilities.projitems +++ b/src/RoslynAnalyzers/Utilities/Compiler.CSharp/Analyzer.CSharp.Utilities.projitems @@ -10,6 +10,5 @@ - \ No newline at end of file diff --git a/src/RoslynAnalyzers/Utilities/Compiler.CSharp/Lightup/SyntaxKindEx.cs b/src/RoslynAnalyzers/Utilities/Compiler.CSharp/Lightup/SyntaxKindEx.cs deleted file mode 100644 index fbe93dcdcc15a..0000000000000 --- a/src/RoslynAnalyzers/Utilities/Compiler.CSharp/Lightup/SyntaxKindEx.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. - -using Microsoft.CodeAnalysis.CSharp; - -namespace Analyzer.Utilities.Lightup -{ - internal static class SyntaxKindEx - { - // https://github.com/dotnet/roslyn/blob/main/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs - public const SyntaxKind Utf8StringLiteralToken = (SyntaxKind)8520; - public const SyntaxKind Utf8StringLiteralExpression = (SyntaxKind)8756; - public const SyntaxKind CollectionExpression = (SyntaxKind)9076; - } -} From a63ea8ca8d9935b4d3838db2085e0880ba399c65 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 9 Dec 2025 13:13:23 +0100 Subject: [PATCH 5/5] Remove unnecessary lightup code --- .../DeclarePublicApiAnalyzer.Impl.cs | 1 - .../Core/Analyzers/NullableContext.cs | 75 ------------------- .../Analyzers/NullableContextExtensions.cs | 36 --------- 3 files changed, 112 deletions(-) delete mode 100644 src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContext.cs delete mode 100644 src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContextExtensions.cs diff --git a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs index 1871f994f9f74..a491bae5f2327 100644 --- a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs +++ b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs @@ -12,7 +12,6 @@ using System.Threading; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; -using Analyzer.Utilities.Lightup; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.PooledObjects; diff --git a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContext.cs b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContext.cs deleted file mode 100644 index aa96d9a6524cc..0000000000000 --- a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContext.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Diagnostics.CodeAnalysis; - -namespace Analyzer.Utilities.Lightup -{ - /// - /// Represents the state of the nullable analysis at a specific point in a file. Bits one and - /// two correspond to whether the nullable feature is enabled. Bits three and four correspond - /// to whether the context was inherited from the global context. - /// - [Flags] - [SuppressMessage("Naming", "CA1714:Flags enums should have plural names", Justification = "Intentionally uses the name from Roslyn.")] - internal enum NullableContext - { - /// - /// Nullable warnings and annotations are explicitly turned off at this location. - /// -#pragma warning disable CA1008 // Enums should have zero value - Rename zero valued field to 'None' - Disabled = 0, -#pragma warning restore CA1008 // Enums should have zero value - - /// - /// Nullable warnings are enabled and will be reported at this file location. - /// - WarningsEnabled = 1, - - /// - /// Nullable annotations are enabled and will be shown when APIs defined at - /// this location are used in other contexts. - /// - AnnotationsEnabled = 1 << 1, - - /// - /// The nullable feature is fully enabled. - /// - Enabled = WarningsEnabled | AnnotationsEnabled, - - /// - /// The nullable warning state is inherited from the project default. - /// - /// - /// The project default can change depending on the file type. Generated - /// files have nullable off by default, regardless of the project-level - /// default setting. - /// - WarningsContextInherited = 1 << 2, - - /// - /// The nullable annotation state is inherited from the project default. - /// - /// - /// The project default can change depending on the file type. Generated - /// files have nullable off by default, regardless of the project-level - /// default setting. - /// - AnnotationsContextInherited = 1 << 3, - - /// - /// The current state of both warnings and annotations are inherited from - /// the project default. - /// - /// - /// This flag is set by default at the start of all files. - /// - /// The project default can change depending on the file type. Generated - /// files have nullable off by default, regardless of the project-level - /// default setting. - /// - ContextInherited = WarningsContextInherited | AnnotationsContextInherited - } -} diff --git a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContextExtensions.cs b/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContextExtensions.cs deleted file mode 100644 index f725f798b3720..0000000000000 --- a/src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/NullableContextExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Analyzer.Utilities.Lightup -{ - internal static class NullableContextExtensions - { - private static bool IsFlagSet(NullableContext context, NullableContext flag) => - (context & flag) == flag; - - /// - /// Returns whether nullable warnings are enabled for this context. - /// - public static bool WarningsEnabled(this NullableContext context) => - IsFlagSet(context, NullableContext.WarningsEnabled); - - /// - /// Returns whether nullable annotations are enabled for this context. - /// - public static bool AnnotationsEnabled(this NullableContext context) => - IsFlagSet(context, NullableContext.AnnotationsEnabled); - - /// - /// Returns whether the nullable warning state was inherited from the project default for this file type. - /// - public static bool WarningsInherited(this NullableContext context) => - IsFlagSet(context, NullableContext.WarningsContextInherited); - - /// - /// Returns whether the nullable annotation state was inherited from the project default for this file type. - /// - public static bool AnnotationsInherited(this NullableContext context) => - IsFlagSet(context, NullableContext.AnnotationsContextInherited); - } -}