diff --git a/Directory.Build.props b/Directory.Build.props
index 24c0e06..16361d7 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -44,6 +44,7 @@
$(BaseIntermediateOutputPath)$(MSBuildProjectName).xml
portable
true
+ Readme.md
@@ -56,6 +57,7 @@
+
diff --git a/Durian.sln b/Durian.sln
index 73ef784..9b84887 100644
--- a/Durian.sln
+++ b/Durian.sln
@@ -190,6 +190,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Durian.Samples.CopyFrom", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Durian.GlobalScope", "src\Durian.GlobalScope\Durian.GlobalScope.csproj", "{643FFE0C-B641-4504-8F6A-0EA694F3DEF7}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GlobalScope", "GlobalScope", "{A04BF577-5DEB-477A-A22C-3557852AC25B}"
+ ProjectSection(SolutionItems) = preProject
+ docs\GlobalScope\DUR0501.md = docs\GlobalScope\DUR0501.md
+ docs\GlobalScope\DUR0502.md = docs\GlobalScope\DUR0502.md
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -485,6 +491,7 @@ Global
{072AEE81-1199-4446-B2D5-54384D23DAE0} = {BA3DE2E2-7B32-4612-8219-24FBCF850813}
{9C383ACD-8C9E-4C24-B2EA-4326C7553866} = {D98DD137-AADE-4474-86EF-9F0874607687}
{643FFE0C-B641-4504-8F6A-0EA694F3DEF7} = {74D7ECF9-D1F6-46FA-B8D8-D34F86F713EA}
+ {A04BF577-5DEB-477A-A22C-3557852AC25B} = {BA3DE2E2-7B32-4612-8219-24FBCF850813}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {09524C45-0D6D-4456-B89D-9673853B9FA0}
diff --git a/docs/GlobalScope/DUR0501.md b/docs/GlobalScope/DUR0501.md
new file mode 100644
index 0000000..becdb3a
--- /dev/null
+++ b/docs/GlobalScope/DUR0501.md
@@ -0,0 +1,22 @@
+# DUR0501 - Error
+### Type marked with the GlobalScopeAttribute must be static.
+
+## Example 1
+
+### Code with diagnostic:
+```csharp
+using Durian;
+
+// DUR0501
+[GlobalScope]
+public class Test
+{
+ public static void DoStuff()
+ {
+ }
+}
+
+```
+##
+
+*\(Written by Piotr Stenke\)*
\ No newline at end of file
diff --git a/docs/GlobalScope/DUR0502.md b/docs/GlobalScope/DUR0502.md
new file mode 100644
index 0000000..1428557
--- /dev/null
+++ b/docs/GlobalScope/DUR0502.md
@@ -0,0 +1,22 @@
+# DUR0502 - Error
+### Type marked with the GlobalScopeAttribute cannot be a nested type.
+
+## Example 1
+
+### Code with diagnostic:
+```csharp
+using Durian;
+
+public static class Test
+{
+ // DUR0502
+ [GlobalScope]
+ public static class Inner
+ {
+ }
+}
+
+```
+##
+
+*\(Written by Piotr Stenke\)*
\ No newline at end of file
diff --git a/durian.json b/durian.json
index f89d241..b8468d4 100644
--- a/durian.json
+++ b/durian.json
@@ -1,159 +1,181 @@
{
"modules": [
- {
- "name": "Core",
- "packages": [
- {
- "name": "Main",
- "version": "3.0.0",
- "type": [
- "Unspecified"
- ]
- },
- {
- "name": "Core",
- "version": "3.0.0",
- "type": [
- "Library"
- ]
- },
- {
- "name": "CoreAnalyzer",
- "version": "3.0.0",
- "type": [
- "Analyzer"
- ]
- }
- ],
- "diagnosticIdPrefix": "00",
- "diagnosticFiles": [
- "src/Durian.Core.Analyzer/DurianDiagnostics.cs"
- ],
- "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/Core",
- "includedTypes": [
- "Durian.Generator.EnableModuleAttribute",
- "Durian.Generator.DurianGeneratedAttribute",
- "Durian.PartialNameAttribute",
- "Durian.UsingsAttribute"
- ]
- },
- {
- "name": "Development",
- "packages": [
- {
- "name": "AnalysisServices",
- "version": "3.0.0",
- "type": [
- "Library"
- ]
- },
- {
- "name": "TestServices",
- "version": "3.0.0",
- "type": [
- "Library"
- ]
- }
- ]
- },
- {
- "name": "DefaultParam",
- "packages": [
- {
- "name": "DefaultParam",
- "version": "3.0.0",
- "type": [
- "Analyzer",
- "CodeFixLibrary",
- "StaticGenerator",
- "SyntaxBasedGenerator"
- ]
- }
- ],
- "includedTypes": [
- "Durian.DefaultParamAttribute",
- "Durian.Configuration.DefaultParamConfigurationAttribute",
- "Durian.Configuration.DefaultParamScopedConfigurationAttribute",
- "Durian.Configuration.DPMethodConvention",
- "Durian.Configuration.DPTypeConvention"
- ],
- "diagnosticIdPrefix": "01",
- "diagnosticFiles": [
- "src/Durian.DefaultParam/DefaultParamDiagnostics.cs"
- ],
- "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/DefaultParam"
- },
- {
- "name": "FriendClass",
- "packages": [
- {
- "name": "FriendClass",
- "version": "2.0.0",
- "type": [
- "Analyzer",
- "CodeFixLibrary",
- "StaticGenerator"
- ]
- }
- ],
- "includedTypes": [
- "Durian.FriendClassAttribute",
- "Durian.Configuration.FriendClassConfigurationAttribute"
- ],
- "diagnosticIdPrefix": "03",
- "diagnosticFiles": [
- "src/Durian.FriendClass/FriendClassDiagnostics.cs"
- ],
- "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/FriendClass"
- },
- {
- "name": "InterfaceTargets",
- "packages": [
- {
- "name": "InterfaceTargets",
- "version": "2.0.0",
- "type": [
- "Analyzer",
- "StaticGenerator"
- ]
- }
- ],
- "includedTypes": [
- "Durian.InterfaceTargets",
- "Durian.InterfaceTargetsAttribute"
- ],
- "diagnosticIdPrefix": "04",
- "diagnosticFiles": [
- "src/Durian.InterfaceTargets/InterfaceTargetsDiagnostics.cs"
- ],
- "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/InterfaceTargets"
- },
- {
- "name": "CopyFrom",
- "packages": [
- {
- "name": "CopyFrom",
- "version": "1.0.0",
- "type": [
- "Analyzer",
- "StaticGenerator",
- "SyntaxBasedGenerator",
- "CodeFixLibrary"
- ]
- }
- ],
- "includedTypes": [
- "Durian.CopyFromTypeAttribute",
- "Durian.CopyFromMethodAttribute",
- "Durian.Configuration.CopyFromAdditionalNodes",
- "Durian.PatternAttribute",
- "Durian.PartialNameAttribute"
- ],
- "diagnosticIdPrefix": "02",
- "diagnosticFiles": [
- "src/Durian.CopyFrom/CopyFromDiagnostics.cs"
- ],
- "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/CopyFrom"
- }
+ {
+ "name": "Core",
+ "packages": [
+ {
+ "name": "Main",
+ "version": "3.0.0",
+ "type": [
+ "Unspecified"
+ ]
+ },
+ {
+ "name": "Core",
+ "version": "3.0.0",
+ "type": [
+ "Library"
+ ]
+ },
+ {
+ "name": "CoreAnalyzer",
+ "version": "3.0.0",
+ "type": [
+ "Analyzer"
+ ]
+ }
+ ],
+ "diagnosticIdPrefix": "00",
+ "diagnosticFiles": [
+ "src/Durian.Core.Analyzer/DurianDiagnostics.cs"
+ ],
+ "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/Core",
+ "includedTypes": [
+ "Durian.Generator.EnableModuleAttribute",
+ "Durian.Generator.DurianGeneratedAttribute",
+ "Durian.PartialNameAttribute",
+ "Durian.UsingsAttribute"
+ ]
+ },
+ {
+ "name": "Development",
+ "packages": [
+ {
+ "name": "AnalysisServices",
+ "version": "3.0.0",
+ "type": [
+ "Library"
+ ]
+ },
+ {
+ "name": "TestServices",
+ "version": "3.0.0",
+ "type": [
+ "Library"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DefaultParam",
+ "packages": [
+ {
+ "name": "DefaultParam",
+ "version": "3.0.0",
+ "type": [
+ "Analyzer",
+ "CodeFixLibrary",
+ "StaticGenerator",
+ "SyntaxBasedGenerator"
+ ]
+ }
+ ],
+ "includedTypes": [
+ "Durian.DefaultParamAttribute",
+ "Durian.Configuration.DefaultParamConfigurationAttribute",
+ "Durian.Configuration.DefaultParamScopedConfigurationAttribute",
+ "Durian.Configuration.DPMethodConvention",
+ "Durian.Configuration.DPTypeConvention"
+ ],
+ "diagnosticIdPrefix": "01",
+ "diagnosticFiles": [
+ "src/Durian.DefaultParam/DefaultParamDiagnostics.cs"
+ ],
+ "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/DefaultParam"
+ },
+ {
+ "name": "FriendClass",
+ "packages": [
+ {
+ "name": "FriendClass",
+ "version": "2.0.0",
+ "type": [
+ "Analyzer",
+ "CodeFixLibrary",
+ "StaticGenerator"
+ ]
+ }
+ ],
+ "includedTypes": [
+ "Durian.FriendClassAttribute",
+ "Durian.Configuration.FriendClassConfigurationAttribute"
+ ],
+ "diagnosticIdPrefix": "03",
+ "diagnosticFiles": [
+ "src/Durian.FriendClass/FriendClassDiagnostics.cs"
+ ],
+ "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/FriendClass"
+ },
+ {
+ "name": "InterfaceTargets",
+ "packages": [
+ {
+ "name": "InterfaceTargets",
+ "version": "2.0.0",
+ "type": [
+ "Analyzer",
+ "StaticGenerator"
+ ]
+ }
+ ],
+ "includedTypes": [
+ "Durian.InterfaceTargets",
+ "Durian.InterfaceTargetsAttribute"
+ ],
+ "diagnosticIdPrefix": "04",
+ "diagnosticFiles": [
+ "src/Durian.InterfaceTargets/InterfaceTargetsDiagnostics.cs"
+ ],
+ "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/InterfaceTargets"
+ },
+ {
+ "name": "CopyFrom",
+ "packages": [
+ {
+ "name": "CopyFrom",
+ "version": "1.0.0",
+ "type": [
+ "Analyzer",
+ "StaticGenerator",
+ "SyntaxBasedGenerator",
+ "CodeFixLibrary"
+ ]
+ }
+ ],
+ "includedTypes": [
+ "Durian.CopyFromTypeAttribute",
+ "Durian.CopyFromMethodAttribute",
+ "Durian.Configuration.CopyFromAdditionalNodes",
+ "Durian.PatternAttribute",
+ "Durian.PartialNameAttribute"
+ ],
+ "diagnosticIdPrefix": "02",
+ "diagnosticFiles": [
+ "src/Durian.CopyFrom/CopyFromDiagnostics.cs"
+ ],
+ "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/CopyFrom"
+ },
+ {
+ "name": "GlobalScope",
+ "packages": [
+ {
+ "name": "GlobalScope",
+ "version": "1.0.0",
+ "type": [
+ "Analyzer",
+ "StaticGenerator",
+ "SyntaxBasedGenerator"
+ ]
+ }
+ ],
+ "includedTypes": [
+ "Durian.GlobalScopeAttribute"
+ ],
+ "diagnosticIdPrefix": "05",
+ "diagnosticFiles": [
+ "src/Durian.GlobalScope/GlobalScopeDiagnostics.cs"
+ ],
+ "documentation": "https://github.com/piotrstenke/Durian/tree/master/docs/GlobalScope"
+ }
]
}
\ No newline at end of file
diff --git a/internal/GenerateModuleRepository/Program.cs b/internal/GenerateModuleRepository/Program.cs
index a118806..66923e4 100644
--- a/internal/GenerateModuleRepository/Program.cs
+++ b/internal/GenerateModuleRepository/Program.cs
@@ -288,7 +288,8 @@ public static PackageIdentity {package.Name}
builder.Append(
@" }
-}");
+}
+");
}
@@ -359,7 +360,8 @@ public static TypeIdentity {type.Name}
builder.Append(
@" }
-}");
+}
+");
}
private static void WriteModuleRepository(StringBuilder builder, List configurations)
@@ -389,7 +391,8 @@ public static class ModuleRepository
builder.AppendLine(
$@" }}
-}}");
+}}
+");
}
private static void WriteModuleIdentity(StringBuilder builder, ModuleConfiguration config)
diff --git a/src/Durian.AnalysisServices/AnalysisUtilities.cs b/src/Durian.AnalysisServices/AnalysisUtilities.cs
index 742527b..47355c6 100644
--- a/src/Durian.AnalysisServices/AnalysisUtilities.cs
+++ b/src/Durian.AnalysisServices/AnalysisUtilities.cs
@@ -3,7 +3,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
-using Durian.Analysis.Extensions;
using Durian.Info;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
diff --git a/src/Durian.AnalysisServices/Extensions/AttributeDataExtensions.cs b/src/Durian.AnalysisServices/AttributeDataExtensions.cs
similarity index 97%
rename from src/Durian.AnalysisServices/Extensions/AttributeDataExtensions.cs
rename to src/Durian.AnalysisServices/AttributeDataExtensions.cs
index 42fd4e3..33ca171 100644
--- a/src/Durian.AnalysisServices/Extensions/AttributeDataExtensions.cs
+++ b/src/Durian.AnalysisServices/AttributeDataExtensions.cs
@@ -1,673 +1,673 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-namespace Durian.Analysis.Extensions;
-
-///
-/// Contains various extension methods for the class.
-///
-public static class AttributeDataExtensions
-{
- ///
- /// Returns a representing the named argument at the specified .
- ///
- /// to get the from.
- /// Position where the target argument is to be found.
- public static TypedConstant GetConstructorArgument(this AttributeData attribute, int position)
- {
- attribute.TryGetConstructorArgument(position, out TypedConstant value);
- return value;
- }
-
- ///
- /// Returns an of s representing the value of the constructor argument at the specified .
- ///
- /// to get the values from.
- /// Position where the target argument is to be found.
- public static ImmutableArray GetConstructorArgumentArrayValue(this AttributeData attribute, int position)
- {
- attribute.TryGetConstructorArgumentArrayValue(position, out ImmutableArray array);
- return array;
- }
-
- ///
- /// Returns an of s representing the value of the constructor argument at the specified .
- ///
- /// Type of array's elements.
- /// to get the values from.
- /// Position where the target argument is to be found.
- public static ImmutableArray GetConstructorArgumentArrayValue(this AttributeData attribute, int position)
- {
- attribute.TryGetConstructorArgumentArrayValue(position, out ImmutableArray array);
- return array;
- }
-
- ///
- /// Returns the enum value of the constructor argument at the specified .
- ///
- /// Type of enum value to return.
- /// to get the value from.
- /// Position where the target argument is to be found.
- /// Type size mismatch.
- public static TEnum GetConstructorArgumentEnumValue(this AttributeData attribute, int position) where TEnum : unmanaged, Enum
- {
- attribute.TryGetConstructorArgumentEnumValue(position, out TEnum value);
- return value;
- }
-
- ///
- /// Returns the enum value of the constructor argument at the specified .
- ///
- /// Type of enum value to return.
- /// Type the type extends.
- /// to get the value from.
- /// Position where the target argument is to be found.
- /// Type size mismatch.
- public static TEnum GetConstructorArgumentEnumValue(this AttributeData attribute, int position)
- where TEnum : unmanaged, Enum
- where TType : unmanaged
- {
- attribute.TryGetConstructorArgumentEnumValue(position, out TEnum value);
- return value;
- }
-
- ///
- /// Returns location of attribute argument at the specified
- /// or location of the is no appropriate argument was found.
- /// If for some reason source syntax of the is not accessible, is returned instead.
- ///
- /// to get the location of argument of.
- /// Position of argument to get.
- public static Location? GetConstructorArgumentLocation(this AttributeData attribute, int position)
- {
- if (attribute.ApplicationSyntaxReference is null)
- {
- return null;
- }
-
- SyntaxNode node = attribute.ApplicationSyntaxReference.GetSyntax();
-
- if (node is not AttributeSyntax attr)
- {
- return node.GetLocation();
- }
-
- return attr.GetArgumentLocation(position);
- }
-
- ///
- /// Returns a representing the value of the constructor argument at the specified .
- ///
- /// Type of to return.
- /// to get the value from.
- /// Position where the target argument is to be found.
- public static T? GetConstructorArgumentTypeValue(this AttributeData attribute, int position) where T : ITypeSymbol
- {
- attribute.TryGetConstructorArgumentTypeValue(position, out T? symbol);
- return symbol;
- }
-
- ///
- /// Returns the value of the constructor argument at the specified .
- ///
- /// Type of value to return.
- /// to get the value from.
- /// Position where the target argument is to be found.
- public static T? GetConstructorArgumentValue(this AttributeData attribute, int position)
- {
- attribute.TryGetConstructorArgumentValue(position, out T? value);
- return value;
- }
-
- ///
- /// Returns the of the specified .
- ///
- public static Location? GetLocation(this AttributeData attribute)
- {
- if (attribute.ApplicationSyntaxReference is null)
- {
- return null;
- }
-
- return Location.Create(attribute.ApplicationSyntaxReference.SyntaxTree, attribute.ApplicationSyntaxReference.Span);
- }
-
- ///
- /// Returns a representing the named argument with the specified .
- ///
- /// to get the from.
- /// Name of the argument to get the of.
- public static TypedConstant GetNamedArgument(this AttributeData attribute, string argumentName)
- {
- attribute.TryGetNamedArgument(argumentName, out TypedConstant value);
- return value;
- }
-
- ///
- /// Returns an of s representing the value of the named argument with the specified .
- ///
- /// to get the values from.
- /// Name of the argument to get the values of.
- public static ImmutableArray GetNamedArgumentArrayValue(this AttributeData attribute, string argumentName)
- {
- attribute.TryGetNamedArgumentArrayValue(argumentName, out ImmutableArray array);
- return array;
- }
-
- ///
- /// Returns an of s representing the value of the named argument with the specified .
- ///
- /// Type of array's elements.
- /// to get the values from.
- /// Name of the argument to get the values of.
- public static ImmutableArray GetNamedArgumentArrayValue(this AttributeData attribute, string argumentName)
- {
- attribute.TryGetNamedArgumentArrayValue(argumentName, out ImmutableArray array);
- return array;
- }
-
- ///
- /// Returns the enum value of the named argument with the specified .
- ///
- /// Type of enum value to return.
- /// to get the value from.
- /// Name of the argument to get the values of.
- /// Type size mismatch.
- public static TEnum GetNamedArgumentEnumValue(this AttributeData attribute, string argumentName) where TEnum : unmanaged, Enum
- {
- attribute.TryGetNamedArgumentEnumValue(argumentName, out TEnum value);
- return value;
- }
-
- ///
- /// Returns the enum value of the named argument with the specified .
- ///
- /// Type of enum value to return.
- /// Type the type extends.
- /// to get the value from.
- /// Name of the argument to get the values of.
- /// Type size mismatch.
- public static TEnum GetNamedArgumentEnumValue(this AttributeData attribute, string argumentName)
- where TEnum : unmanaged, Enum
- where TType : unmanaged
- {
- attribute.TryGetNamedArgumentEnumValue(argumentName, out TEnum value);
- return value;
- }
-
- ///
- /// Returns location of attribute argument with the specified
- /// or location of the if no argument with the was found.
- /// If for some reason source syntax of the is not accessible, is returned instead.
- ///
- /// to get the location of argument of.
- /// Name of argument to get the location of.
- public static Location? GetNamedArgumentLocation(this AttributeData attribute, string argumentName)
- {
- if (attribute.ApplicationSyntaxReference is null)
- {
- return null;
- }
-
- SyntaxNode node = attribute.ApplicationSyntaxReference.GetSyntax();
-
- if (node is not AttributeSyntax attr)
- {
- return node.GetLocation();
- }
-
- return attr.GetArgumentLocation(argumentName);
- }
-
- ///
- /// Returns a representing the value of the named argument with the specified .
- ///
- /// Type of to return.
- /// to get the value from.
- /// Name of the argument to get the value of.
- public static T? GetNamedArgumentTypeValue(this AttributeData attribute, string argumentName) where T : ITypeSymbol
- {
- attribute.TryGetNamedArgumentTypeValue(argumentName, out T? symbol);
- return symbol;
- }
-
- ///
- /// Returns the value of the named argument with the specified .
- ///
- /// Type of value to return.
- /// to get the value from.
- /// Name of the argument to get the value of.
- public static T? GetNamedArgumentValue(this AttributeData attribute, string argumentName)
- {
- attribute.TryGetNamedArgumentValue(argumentName, out T? value);
- return value;
- }
-
- ///
- /// Returns the kind of this represents.
- ///
- /// to get the kind of.
- public static NullableAnnotationAttribute GetNullableAnnotationAttributeKind(this AttributeData attribute)
- {
- return attribute.AttributeClass?.GetNullableAnnotationAttributeKind() ?? default;
- }
-
- ///
- /// Returns the kind of this represents.
- ///
- /// to get the kind of.
- public static SpecialAttribute GetSpecialAttributeKind(this AttributeData attribute)
- {
- return attribute.AttributeClass?.GetSpecialAttributeKind() ?? default;
- }
-
- ///
- /// Returns target of the specified .
- ///
- /// to get the target of.
- public static AttributeTarget GetTarget(this AttributeData attribute)
- {
- if (attribute.ApplicationSyntaxReference?.GetSyntax() is not AttributeSyntax node || node.Parent is not AttributeListSyntax list || list.Target is not AttributeTargetSpecifierSyntax target)
- {
- return AttributeTarget.None;
- }
-
- return target.Identifier.ValueText switch
- {
- "assembly" => AttributeTarget.Assembly,
- "return" => AttributeTarget.Return,
- "field" => AttributeTarget.Field,
- "event" => AttributeTarget.Event,
- "method" => AttributeTarget.Method,
- "type" => AttributeTarget.Type,
- "property" => AttributeTarget.Property,
- "param" => AttributeTarget.Param,
- "module" => AttributeTarget.Module,
- "typevar" => AttributeTarget.TypeVar,
- _ => AttributeTarget.None
- };
- }
-
- ///
- /// Checks if the target has a constructor argument at the specified . If so, also returns a that represents that argument.
- ///
- /// to get the from.
- /// Position where the target argument is to be found.
- /// Returned that represents the argument with at the specified .
- public static bool TryGetConstructorArgument(this AttributeData attribute, int position, out TypedConstant value)
- {
- ImmutableArray arguments = attribute.ConstructorArguments;
-
- if (arguments.Length == 0 || arguments.Length <= position)
- {
- value = default;
- return false;
- }
-
- value = arguments[position];
- return true;
- }
-
- ///
- /// Checks if the target defines a constructor argument at the specified . If so, also returns the of contained within the argument's array value.
- ///
- /// to get the values from.
- /// Position where the target argument is to be found.
- /// Values contained within array value of the argument.
- public static bool TryGetConstructorArgumentArrayValue(this AttributeData attribute, int position, out ImmutableArray values)
- {
- if (attribute.TryGetConstructorArgument(position, out TypedConstant constant))
- {
- if (constant.Values.IsDefault)
- {
- values = ImmutableArray.Create();
- }
- else
- {
- values = constant.Values;
- }
-
- return true;
- }
-
- values = ImmutableArray.Create();
- return false;
- }
-
- ///
- /// Checks if the target defines a constructor argument at the specified . If so, also returns the of contained within the argument's array value.
- ///
- /// Type of array's elements.
- /// to get the values from.
- /// Position where the target argument is to be found.
- /// Values contained within array value of the argument.
- public static bool TryGetConstructorArgumentArrayValue(this AttributeData attribute, int position, out ImmutableArray values)
- {
- if (!attribute.TryGetConstructorArgumentArrayValue(position, out ImmutableArray constants))
- {
- values = ImmutableArray.Create();
- return false;
- }
-
- int length = constants.Length;
-
- if (length == 0)
- {
- values = ImmutableArray.Create();
- return true;
- }
-
- T[] array = new T[length];
-
- for (int i = 0; i < length; i++)
- {
- if (constants[i].Value is T t)
- {
- array[i] = t;
- }
- else
- {
- array[i] = default!;
- }
- }
-
- values = ImmutableArray.Create(array);
- return true;
- }
-
- ///
- /// Checks if the target defines a constructor argument at specified . If so, also returns the enum value of that argument.
- ///
- /// Type of enum value to return.
- /// to get the value from.
- /// Position where the target argument is to be found.
- /// Returned enum value.
- /// Type size mismatch.
- public static bool TryGetConstructorArgumentEnumValue(this AttributeData attribute, int position, out TEnum value) where TEnum : unmanaged, Enum
- {
- return attribute.TryGetConstructorArgumentEnumValue(position, out value);
- }
-
- ///
- /// Checks if the target defines a constructor argument at specified . If so, also returns the enum value of that argument.
- ///
- /// Type of enum value to return.
- /// Type the type extends.
- /// to get the value from.
- /// Position where the target argument is to be found.
- /// Returned enum value.
- /// Type size mismatch.
- public static unsafe bool TryGetConstructorArgumentEnumValue(this AttributeData attribute, int position, out TEnum value)
- where TEnum : unmanaged, Enum
- where TType : unmanaged
- {
- if (sizeof(TType) != sizeof(TEnum))
- {
- throw new InvalidOperationException($"Type size mismatch. TEnum is {sizeof(TEnum)}, while TType is {sizeof(TType)}");
- }
-
- if (attribute.TryGetConstructorArgumentValue(position, out TType n))
- {
- // For some reason this line causes assembly version conflicts.
- //value = Unsafe.As(ref n);
-
- value = (TEnum)(object)n;
- return true;
- }
-
- value = default;
- return false;
- }
-
- ///
- /// Checks if the target defines a constructor argument at specified . If so, also returns the represented by value of that argument.
- ///
- /// Type of to return.
- /// to get the value from.
- /// Position where the target argument is to be found.
- /// Symbol that represents the value of the argument.
- public static bool TryGetConstructorArgumentTypeValue(this AttributeData attribute, int position, out TType? symbol) where TType : ITypeSymbol
- {
- if (attribute.TryGetConstructorArgument(position, out TypedConstant value))
- {
- if (value.Value is TType t)
- {
- symbol = t;
- }
- else
- {
- symbol = default;
- }
-
- return true;
- }
-
- symbol = default;
- return false;
- }
-
- ///
- /// Checks if the target has a constructor argument at the specified . If so, also returns the of that argument.
- ///
- /// Type of value to return.
- /// to get the from.
- /// Position where the target argument is to be found.
- /// Value of the argument.
- public static bool TryGetConstructorArgumentValue(this AttributeData attribute, int position, out T? value)
- {
- if (attribute.TryGetConstructorArgument(position, out TypedConstant arg))
- {
- if (arg.Value is T t)
- {
- value = t;
- }
- else
- {
- value = default;
- }
-
- return true;
- }
-
- value = default;
- return false;
- }
-
- ///
- /// Checks if the target defines a named argument with the specified . If so, also returns a that represents that argument.
- ///
- /// to get the from.
- /// Name of the argument to get the of.
- /// Returned that represents the argument with the specified .
- public static bool TryGetNamedArgument(this AttributeData attribute, string argumentName, out TypedConstant value)
- {
- foreach (KeyValuePair arg in attribute.NamedArguments)
- {
- if (arg.Key == argumentName)
- {
- value = arg.Value;
- return true;
- }
- }
-
- value = default;
- return false;
- }
-
- ///
- /// Checks if the target defines a named argument with the specified . If so, also returns the of contained within the argument's array value.
- ///
- /// to get the values from.
- /// Name of the argument to get the values of.
- /// Values contained within array value of the argument.
- public static bool TryGetNamedArgumentArrayValue(this AttributeData attribute, string argumentName, out ImmutableArray values)
- {
- foreach (KeyValuePair arg in attribute.NamedArguments)
- {
- if (arg.Key == argumentName)
- {
- if (arg.Value.Values.IsDefault)
- {
- values = ImmutableArray.Create();
- }
- else
- {
- values = arg.Value.Values;
- }
-
- return true;
- }
- }
-
- values = ImmutableArray.Create();
- return false;
- }
-
- ///
- /// Checks if the target defines a named argument with the specified . If so, also returns the of contained within the argument's array value.
- ///
- /// Type of array's elements.
- /// to get the values from.
- /// Name of the argument to get the values of.
- /// Values contained within array value of the argument.
- public static bool TryGetNamedArgumentArrayValue(this AttributeData attribute, string argumentName, out ImmutableArray values)
- {
- if (!attribute.TryGetNamedArgumentArrayValue(argumentName, out ImmutableArray constants))
- {
- values = ImmutableArray.Create();
- return false;
- }
-
- int length = constants.Length;
-
- if (length == 0)
- {
- values = ImmutableArray.Create();
- return true;
- }
-
- T[] array = new T[length];
-
- for (int i = 0; i < length; i++)
- {
- if (constants[i].Value is T t)
- {
- array[i] = t;
- }
- else
- {
- array[i] = default!;
- }
- }
-
- values = ImmutableArray.Create(array);
- return true;
- }
-
- ///
- /// Checks if the target defines a named argument with the specified . If so, also returns the enum of that argument.
- ///
- /// Type of enum value to return.
- /// to get the value from.
- /// Name of the argument to get the of.
- /// Returned enum value.
- /// Type size mismatch.
- public static bool TryGetNamedArgumentEnumValue(this AttributeData attribute, string argumentName, out TEnum value) where TEnum : unmanaged, Enum
- {
- return attribute.TryGetNamedArgumentEnumValue(argumentName, out value);
- }
-
- ///
- /// Checks if the target defines a named argument with the specified . If so, also returns the enum of that argument.
- ///
- /// Type of enum value to return.
- /// Type the type extends.
- /// to get the value from.
- /// Name of the argument to get the of.
- /// Returned enum value.
- /// Type size mismatch.
- public static unsafe bool TryGetNamedArgumentEnumValue(this AttributeData attribute, string argumentName, out TEnum value)
- where TEnum : unmanaged, Enum
- where TType : unmanaged
- {
- if (sizeof(TType) != sizeof(TEnum))
- {
- throw new InvalidOperationException($"Type size mismatch. TEnum is {sizeof(TEnum)}, while TType is {sizeof(TType)}");
- }
-
- if (attribute.TryGetNamedArgumentValue(argumentName, out TType n))
- {
- // For some reason this line causes assembly version conflicts.
- //value = Unsafe.As(ref n);
-
- value = (TEnum)(object)n;
- return true;
- }
-
- value = default;
- return false;
- }
-
- ///
- /// Checks if the target defines a named argument with the specified . If so, also returns the represented by value of that argument.
- ///
- /// Type of to return.
- /// to get the value from.
- /// Name of the argument to get the value of.
- /// Symbol that represents the value of the argument.
- public static bool TryGetNamedArgumentTypeValue(this AttributeData attribute, string argumentName, out T? symbol) where T : ITypeSymbol
- {
- foreach (KeyValuePair arg in attribute.NamedArguments)
- {
- if (arg.Key == argumentName)
- {
- if (arg.Value.Value is T t)
- {
- symbol = t;
- }
- else
- {
- symbol = default;
- }
-
- return true;
- }
- }
-
- symbol = default;
- return false;
- }
-
- ///
- /// Checks if the target defines a named argument with the specified . If so, also returns the of that argument.
- ///
- /// Type of value to return.
- /// to get the from.
- /// Name of the argument to get the of.
- /// Value of the argument.
- public static bool TryGetNamedArgumentValue(this AttributeData attribute, string argumentName, out T? value)
- {
- foreach (KeyValuePair arg in attribute.NamedArguments)
- {
- if (arg.Key == argumentName)
- {
- if (arg.Value.Value is T t)
- {
- value = t;
- }
- else
- {
- value = default!;
- }
-
- return true;
- }
- }
-
- value = default!;
- return false;
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Durian.Analysis;
+
+///
+/// Contains various extension methods for the class.
+///
+public static class AttributeDataExtensions
+{
+ ///
+ /// Returns a representing the named argument at the specified .
+ ///
+ /// to get the from.
+ /// Position where the target argument is to be found.
+ public static TypedConstant GetConstructorArgument(this AttributeData attribute, int position)
+ {
+ attribute.TryGetConstructorArgument(position, out TypedConstant value);
+ return value;
+ }
+
+ ///
+ /// Returns an of s representing the value of the constructor argument at the specified .
+ ///
+ /// to get the values from.
+ /// Position where the target argument is to be found.
+ public static ImmutableArray GetConstructorArgumentArrayValue(this AttributeData attribute, int position)
+ {
+ attribute.TryGetConstructorArgumentArrayValue(position, out ImmutableArray array);
+ return array;
+ }
+
+ ///
+ /// Returns an of s representing the value of the constructor argument at the specified .
+ ///
+ /// Type of array's elements.
+ /// to get the values from.
+ /// Position where the target argument is to be found.
+ public static ImmutableArray GetConstructorArgumentArrayValue(this AttributeData attribute, int position)
+ {
+ attribute.TryGetConstructorArgumentArrayValue(position, out ImmutableArray array);
+ return array;
+ }
+
+ ///
+ /// Returns the enum value of the constructor argument at the specified .
+ ///
+ /// Type of enum value to return.
+ /// to get the value from.
+ /// Position where the target argument is to be found.
+ /// Type size mismatch.
+ public static TEnum GetConstructorArgumentEnumValue(this AttributeData attribute, int position) where TEnum : unmanaged, Enum
+ {
+ attribute.TryGetConstructorArgumentEnumValue(position, out TEnum value);
+ return value;
+ }
+
+ ///
+ /// Returns the enum value of the constructor argument at the specified .
+ ///
+ /// Type of enum value to return.
+ /// Type the type extends.
+ /// to get the value from.
+ /// Position where the target argument is to be found.
+ /// Type size mismatch.
+ public static TEnum GetConstructorArgumentEnumValue(this AttributeData attribute, int position)
+ where TEnum : unmanaged, Enum
+ where TType : unmanaged
+ {
+ attribute.TryGetConstructorArgumentEnumValue(position, out TEnum value);
+ return value;
+ }
+
+ ///
+ /// Returns location of attribute argument at the specified
+ /// or location of the is no appropriate argument was found.
+ /// If for some reason source syntax of the is not accessible, is returned instead.
+ ///
+ /// to get the location of argument of.
+ /// Position of argument to get.
+ public static Location? GetConstructorArgumentLocation(this AttributeData attribute, int position)
+ {
+ if (attribute.ApplicationSyntaxReference is null)
+ {
+ return null;
+ }
+
+ SyntaxNode node = attribute.ApplicationSyntaxReference.GetSyntax();
+
+ if (node is not AttributeSyntax attr)
+ {
+ return node.GetLocation();
+ }
+
+ return attr.GetArgumentLocation(position);
+ }
+
+ ///
+ /// Returns a representing the value of the constructor argument at the specified .
+ ///
+ /// Type of to return.
+ /// to get the value from.
+ /// Position where the target argument is to be found.
+ public static T? GetConstructorArgumentTypeValue(this AttributeData attribute, int position) where T : ITypeSymbol
+ {
+ attribute.TryGetConstructorArgumentTypeValue(position, out T? symbol);
+ return symbol;
+ }
+
+ ///
+ /// Returns the value of the constructor argument at the specified .
+ ///
+ /// Type of value to return.
+ /// to get the value from.
+ /// Position where the target argument is to be found.
+ public static T? GetConstructorArgumentValue(this AttributeData attribute, int position)
+ {
+ attribute.TryGetConstructorArgumentValue(position, out T? value);
+ return value;
+ }
+
+ ///
+ /// Returns the of the specified .
+ ///
+ public static Location? GetLocation(this AttributeData attribute)
+ {
+ if (attribute.ApplicationSyntaxReference is null)
+ {
+ return null;
+ }
+
+ return Location.Create(attribute.ApplicationSyntaxReference.SyntaxTree, attribute.ApplicationSyntaxReference.Span);
+ }
+
+ ///
+ /// Returns a representing the named argument with the specified .
+ ///
+ /// to get the from.
+ /// Name of the argument to get the of.
+ public static TypedConstant GetNamedArgument(this AttributeData attribute, string argumentName)
+ {
+ attribute.TryGetNamedArgument(argumentName, out TypedConstant value);
+ return value;
+ }
+
+ ///
+ /// Returns an of s representing the value of the named argument with the specified .
+ ///
+ /// to get the values from.
+ /// Name of the argument to get the values of.
+ public static ImmutableArray GetNamedArgumentArrayValue(this AttributeData attribute, string argumentName)
+ {
+ attribute.TryGetNamedArgumentArrayValue(argumentName, out ImmutableArray array);
+ return array;
+ }
+
+ ///
+ /// Returns an of s representing the value of the named argument with the specified .
+ ///
+ /// Type of array's elements.
+ /// to get the values from.
+ /// Name of the argument to get the values of.
+ public static ImmutableArray GetNamedArgumentArrayValue(this AttributeData attribute, string argumentName)
+ {
+ attribute.TryGetNamedArgumentArrayValue(argumentName, out ImmutableArray array);
+ return array;
+ }
+
+ ///
+ /// Returns the enum value of the named argument with the specified .
+ ///
+ /// Type of enum value to return.
+ /// to get the value from.
+ /// Name of the argument to get the values of.
+ /// Type size mismatch.
+ public static TEnum GetNamedArgumentEnumValue(this AttributeData attribute, string argumentName) where TEnum : unmanaged, Enum
+ {
+ attribute.TryGetNamedArgumentEnumValue(argumentName, out TEnum value);
+ return value;
+ }
+
+ ///
+ /// Returns the enum value of the named argument with the specified .
+ ///
+ /// Type of enum value to return.
+ /// Type the type extends.
+ /// to get the value from.
+ /// Name of the argument to get the values of.
+ /// Type size mismatch.
+ public static TEnum GetNamedArgumentEnumValue(this AttributeData attribute, string argumentName)
+ where TEnum : unmanaged, Enum
+ where TType : unmanaged
+ {
+ attribute.TryGetNamedArgumentEnumValue(argumentName, out TEnum value);
+ return value;
+ }
+
+ ///
+ /// Returns location of attribute argument with the specified
+ /// or location of the if no argument with the was found.
+ /// If for some reason source syntax of the is not accessible, is returned instead.
+ ///
+ /// to get the location of argument of.
+ /// Name of argument to get the location of.
+ public static Location? GetNamedArgumentLocation(this AttributeData attribute, string argumentName)
+ {
+ if (attribute.ApplicationSyntaxReference is null)
+ {
+ return null;
+ }
+
+ SyntaxNode node = attribute.ApplicationSyntaxReference.GetSyntax();
+
+ if (node is not AttributeSyntax attr)
+ {
+ return node.GetLocation();
+ }
+
+ return attr.GetArgumentLocation(argumentName);
+ }
+
+ ///
+ /// Returns a representing the value of the named argument with the specified .
+ ///
+ /// Type of to return.
+ /// to get the value from.
+ /// Name of the argument to get the value of.
+ public static T? GetNamedArgumentTypeValue(this AttributeData attribute, string argumentName) where T : ITypeSymbol
+ {
+ attribute.TryGetNamedArgumentTypeValue(argumentName, out T? symbol);
+ return symbol;
+ }
+
+ ///
+ /// Returns the value of the named argument with the specified .
+ ///
+ /// Type of value to return.
+ /// to get the value from.
+ /// Name of the argument to get the value of.
+ public static T? GetNamedArgumentValue(this AttributeData attribute, string argumentName)
+ {
+ attribute.TryGetNamedArgumentValue(argumentName, out T? value);
+ return value;
+ }
+
+ ///
+ /// Returns the kind of this represents.
+ ///
+ /// to get the kind of.
+ public static NullableAnnotationAttribute GetNullableAnnotationAttributeKind(this AttributeData attribute)
+ {
+ return attribute.AttributeClass?.GetNullableAnnotationAttributeKind() ?? default;
+ }
+
+ ///
+ /// Returns the kind of this represents.
+ ///
+ /// to get the kind of.
+ public static SpecialAttribute GetSpecialAttributeKind(this AttributeData attribute)
+ {
+ return attribute.AttributeClass?.GetSpecialAttributeKind() ?? default;
+ }
+
+ ///
+ /// Returns target of the specified .
+ ///
+ /// to get the target of.
+ public static AttributeTarget GetTarget(this AttributeData attribute)
+ {
+ if (attribute.ApplicationSyntaxReference?.GetSyntax() is not AttributeSyntax node || node.Parent is not AttributeListSyntax list || list.Target is not AttributeTargetSpecifierSyntax target)
+ {
+ return AttributeTarget.None;
+ }
+
+ return target.Identifier.ValueText switch
+ {
+ "assembly" => AttributeTarget.Assembly,
+ "return" => AttributeTarget.Return,
+ "field" => AttributeTarget.Field,
+ "event" => AttributeTarget.Event,
+ "method" => AttributeTarget.Method,
+ "type" => AttributeTarget.Type,
+ "property" => AttributeTarget.Property,
+ "param" => AttributeTarget.Param,
+ "module" => AttributeTarget.Module,
+ "typevar" => AttributeTarget.TypeVar,
+ _ => AttributeTarget.None
+ };
+ }
+
+ ///
+ /// Checks if the target has a constructor argument at the specified . If so, also returns a that represents that argument.
+ ///
+ /// to get the from.
+ /// Position where the target argument is to be found.
+ /// Returned that represents the argument with at the specified .
+ public static bool TryGetConstructorArgument(this AttributeData attribute, int position, out TypedConstant value)
+ {
+ ImmutableArray arguments = attribute.ConstructorArguments;
+
+ if (arguments.Length == 0 || arguments.Length <= position)
+ {
+ value = default;
+ return false;
+ }
+
+ value = arguments[position];
+ return true;
+ }
+
+ ///
+ /// Checks if the target defines a constructor argument at the specified . If so, also returns the of contained within the argument's array value.
+ ///
+ /// to get the values from.
+ /// Position where the target argument is to be found.
+ /// Values contained within array value of the argument.
+ public static bool TryGetConstructorArgumentArrayValue(this AttributeData attribute, int position, out ImmutableArray values)
+ {
+ if (attribute.TryGetConstructorArgument(position, out TypedConstant constant))
+ {
+ if (constant.Values.IsDefault)
+ {
+ values = ImmutableArray.Create();
+ }
+ else
+ {
+ values = constant.Values;
+ }
+
+ return true;
+ }
+
+ values = ImmutableArray.Create();
+ return false;
+ }
+
+ ///
+ /// Checks if the target defines a constructor argument at the specified . If so, also returns the of contained within the argument's array value.
+ ///
+ /// Type of array's elements.
+ /// to get the values from.
+ /// Position where the target argument is to be found.
+ /// Values contained within array value of the argument.
+ public static bool TryGetConstructorArgumentArrayValue(this AttributeData attribute, int position, out ImmutableArray values)
+ {
+ if (!attribute.TryGetConstructorArgumentArrayValue(position, out ImmutableArray constants))
+ {
+ values = ImmutableArray.Create();
+ return false;
+ }
+
+ int length = constants.Length;
+
+ if (length == 0)
+ {
+ values = ImmutableArray.Create();
+ return true;
+ }
+
+ T[] array = new T[length];
+
+ for (int i = 0; i < length; i++)
+ {
+ if (constants[i].Value is T t)
+ {
+ array[i] = t;
+ }
+ else
+ {
+ array[i] = default!;
+ }
+ }
+
+ values = ImmutableArray.Create(array);
+ return true;
+ }
+
+ ///
+ /// Checks if the target defines a constructor argument at specified . If so, also returns the enum value of that argument.
+ ///
+ /// Type of enum value to return.
+ /// to get the value from.
+ /// Position where the target argument is to be found.
+ /// Returned enum value.
+ /// Type size mismatch.
+ public static bool TryGetConstructorArgumentEnumValue(this AttributeData attribute, int position, out TEnum value) where TEnum : unmanaged, Enum
+ {
+ return attribute.TryGetConstructorArgumentEnumValue(position, out value);
+ }
+
+ ///
+ /// Checks if the target defines a constructor argument at specified . If so, also returns the enum value of that argument.
+ ///
+ /// Type of enum value to return.
+ /// Type the type extends.
+ /// to get the value from.
+ /// Position where the target argument is to be found.
+ /// Returned enum value.
+ /// Type size mismatch.
+ public static unsafe bool TryGetConstructorArgumentEnumValue(this AttributeData attribute, int position, out TEnum value)
+ where TEnum : unmanaged, Enum
+ where TType : unmanaged
+ {
+ if (sizeof(TType) != sizeof(TEnum))
+ {
+ throw new InvalidOperationException($"Type size mismatch. TEnum is {sizeof(TEnum)}, while TType is {sizeof(TType)}");
+ }
+
+ if (attribute.TryGetConstructorArgumentValue(position, out TType n))
+ {
+ // For some reason this line causes assembly version conflicts.
+ //value = Unsafe.As(ref n);
+
+ value = (TEnum)(object)n;
+ return true;
+ }
+
+ value = default;
+ return false;
+ }
+
+ ///
+ /// Checks if the target defines a constructor argument at specified . If so, also returns the represented by value of that argument.
+ ///
+ /// Type of to return.
+ /// to get the value from.
+ /// Position where the target argument is to be found.
+ /// Symbol that represents the value of the argument.
+ public static bool TryGetConstructorArgumentTypeValue(this AttributeData attribute, int position, out TType? symbol) where TType : ITypeSymbol
+ {
+ if (attribute.TryGetConstructorArgument(position, out TypedConstant value))
+ {
+ if (value.Value is TType t)
+ {
+ symbol = t;
+ }
+ else
+ {
+ symbol = default;
+ }
+
+ return true;
+ }
+
+ symbol = default;
+ return false;
+ }
+
+ ///
+ /// Checks if the target has a constructor argument at the specified . If so, also returns the of that argument.
+ ///
+ /// Type of value to return.
+ /// to get the from.
+ /// Position where the target argument is to be found.
+ /// Value of the argument.
+ public static bool TryGetConstructorArgumentValue(this AttributeData attribute, int position, out T? value)
+ {
+ if (attribute.TryGetConstructorArgument(position, out TypedConstant arg))
+ {
+ if (arg.Value is T t)
+ {
+ value = t;
+ }
+ else
+ {
+ value = default;
+ }
+
+ return true;
+ }
+
+ value = default;
+ return false;
+ }
+
+ ///
+ /// Checks if the target defines a named argument with the specified . If so, also returns a that represents that argument.
+ ///
+ /// to get the from.
+ /// Name of the argument to get the of.
+ /// Returned that represents the argument with the specified .
+ public static bool TryGetNamedArgument(this AttributeData attribute, string argumentName, out TypedConstant value)
+ {
+ foreach (KeyValuePair arg in attribute.NamedArguments)
+ {
+ if (arg.Key == argumentName)
+ {
+ value = arg.Value;
+ return true;
+ }
+ }
+
+ value = default;
+ return false;
+ }
+
+ ///
+ /// Checks if the target defines a named argument with the specified . If so, also returns the of contained within the argument's array value.
+ ///
+ /// to get the values from.
+ /// Name of the argument to get the values of.
+ /// Values contained within array value of the argument.
+ public static bool TryGetNamedArgumentArrayValue(this AttributeData attribute, string argumentName, out ImmutableArray values)
+ {
+ foreach (KeyValuePair arg in attribute.NamedArguments)
+ {
+ if (arg.Key == argumentName)
+ {
+ if (arg.Value.Values.IsDefault)
+ {
+ values = ImmutableArray.Create();
+ }
+ else
+ {
+ values = arg.Value.Values;
+ }
+
+ return true;
+ }
+ }
+
+ values = ImmutableArray.Create();
+ return false;
+ }
+
+ ///
+ /// Checks if the target defines a named argument with the specified . If so, also returns the of contained within the argument's array value.
+ ///
+ /// Type of array's elements.
+ /// to get the values from.
+ /// Name of the argument to get the values of.
+ /// Values contained within array value of the argument.
+ public static bool TryGetNamedArgumentArrayValue(this AttributeData attribute, string argumentName, out ImmutableArray values)
+ {
+ if (!attribute.TryGetNamedArgumentArrayValue(argumentName, out ImmutableArray constants))
+ {
+ values = ImmutableArray.Create();
+ return false;
+ }
+
+ int length = constants.Length;
+
+ if (length == 0)
+ {
+ values = ImmutableArray.Create();
+ return true;
+ }
+
+ T[] array = new T[length];
+
+ for (int i = 0; i < length; i++)
+ {
+ if (constants[i].Value is T t)
+ {
+ array[i] = t;
+ }
+ else
+ {
+ array[i] = default!;
+ }
+ }
+
+ values = ImmutableArray.Create(array);
+ return true;
+ }
+
+ ///
+ /// Checks if the target defines a named argument with the specified . If so, also returns the enum of that argument.
+ ///
+ /// Type of enum value to return.
+ /// to get the value from.
+ /// Name of the argument to get the of.
+ /// Returned enum value.
+ /// Type size mismatch.
+ public static bool TryGetNamedArgumentEnumValue(this AttributeData attribute, string argumentName, out TEnum value) where TEnum : unmanaged, Enum
+ {
+ return attribute.TryGetNamedArgumentEnumValue(argumentName, out value);
+ }
+
+ ///
+ /// Checks if the target defines a named argument with the specified . If so, also returns the enum of that argument.
+ ///
+ /// Type of enum value to return.
+ /// Type the type extends.
+ /// to get the value from.
+ /// Name of the argument to get the of.
+ /// Returned enum value.
+ /// Type size mismatch.
+ public static unsafe bool TryGetNamedArgumentEnumValue(this AttributeData attribute, string argumentName, out TEnum value)
+ where TEnum : unmanaged, Enum
+ where TType : unmanaged
+ {
+ if (sizeof(TType) != sizeof(TEnum))
+ {
+ throw new InvalidOperationException($"Type size mismatch. TEnum is {sizeof(TEnum)}, while TType is {sizeof(TType)}");
+ }
+
+ if (attribute.TryGetNamedArgumentValue(argumentName, out TType n))
+ {
+ // For some reason this line causes assembly version conflicts.
+ //value = Unsafe.As(ref n);
+
+ value = (TEnum)(object)n;
+ return true;
+ }
+
+ value = default;
+ return false;
+ }
+
+ ///
+ /// Checks if the target defines a named argument with the specified . If so, also returns the represented by value of that argument.
+ ///
+ /// Type of to return.
+ /// to get the value from.
+ /// Name of the argument to get the value of.
+ /// Symbol that represents the value of the argument.
+ public static bool TryGetNamedArgumentTypeValue(this AttributeData attribute, string argumentName, out T? symbol) where T : ITypeSymbol
+ {
+ foreach (KeyValuePair arg in attribute.NamedArguments)
+ {
+ if (arg.Key == argumentName)
+ {
+ if (arg.Value.Value is T t)
+ {
+ symbol = t;
+ }
+ else
+ {
+ symbol = default;
+ }
+
+ return true;
+ }
+ }
+
+ symbol = default;
+ return false;
+ }
+
+ ///
+ /// Checks if the target defines a named argument with the specified . If so, also returns the of that argument.
+ ///
+ /// Type of value to return.
+ /// to get the from.
+ /// Name of the argument to get the of.
+ /// Value of the argument.
+ public static bool TryGetNamedArgumentValue(this AttributeData attribute, string argumentName, out T? value)
+ {
+ foreach (KeyValuePair arg in attribute.NamedArguments)
+ {
+ if (arg.Key == argumentName)
+ {
+ if (arg.Value.Value is T t)
+ {
+ value = t;
+ }
+ else
+ {
+ value = default!;
+ }
+
+ return true;
+ }
+ }
+
+ value = default!;
+ return false;
+ }
+}
diff --git a/src/Durian.AnalysisServices/Cache/CachedAnalyzer`1.cs b/src/Durian.AnalysisServices/Cache/CachedAnalyzer`1.cs
index 59bdefc..874a892 100644
--- a/src/Durian.AnalysisServices/Cache/CachedAnalyzer`1.cs
+++ b/src/Durian.AnalysisServices/Cache/CachedAnalyzer`1.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
+using System.ComponentModel;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -18,20 +19,21 @@ protected CachedAnalyzer()
{
}
+ ///
+ public abstract void Register(IDurianAnalysisContext context, ConcurrentDictionary cached);
+
///
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
[Obsolete("This method shouldn't be used directly - use Register(IDurianAnalysisContext, ConcurrentDictionary) instead.")]
- public sealed override void Register(IDurianAnalysisContext context)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected sealed override void Register(IDurianAnalysisContext context)
#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member
{
ConcurrentDictionary dict = new();
Register(context, dict);
}
- ///
- public abstract void Register(IDurianAnalysisContext context, ConcurrentDictionary cached);
-
void ICachedAnalyzer.Register(IDurianAnalysisContext context, CSharpCompilation compilation, ConcurrentDictionary cached)
{
Register(context, cached);
diff --git a/src/Durian.AnalysisServices/Cache/CachedAnalyzer`2.cs b/src/Durian.AnalysisServices/Cache/CachedAnalyzer`2.cs
index d0d6b18..c636e70 100644
--- a/src/Durian.AnalysisServices/Cache/CachedAnalyzer`2.cs
+++ b/src/Durian.AnalysisServices/Cache/CachedAnalyzer`2.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
+using System.ComponentModel;
using Durian.Analysis.Data;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -22,25 +23,26 @@ protected CachedAnalyzer()
{
}
+ ///
+ /// Registers actions to be performed by the analyzer and caches the result of analysis.
+ ///
+ /// used to register the actions to be performed.
+ /// Compilation to be used during the analysis.
+ /// A that contains the cached values.
+ public abstract void Register(IDurianAnalysisContext context, TCompilation compilation, ConcurrentDictionary cached);
+
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
///
[Obsolete("This method shouldn't be used directly - use Register(IDurianAnalysisContext, TCompilation, ConcurrentDictionary) instead.")]
- public sealed override void Register(IDurianAnalysisContext context, TCompilation compilation)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected sealed override void Register(IDurianAnalysisContext context, TCompilation compilation)
#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member
{
ConcurrentDictionary dict = new();
Register(context, compilation, dict);
}
- ///
- /// Registers actions to be performed by the analyzer and caches the result of analysis.
- ///
- /// used to register the actions to be performed.
- /// Compilation to be used during the analysis.
- /// A that contains the cached values.
- public abstract void Register(IDurianAnalysisContext context, TCompilation compilation, ConcurrentDictionary cached);
-
void ICachedAnalyzer.Register(IDurianAnalysisContext context, CSharpCompilation compilation, ConcurrentDictionary cached)
{
TCompilation c = CreateCompilation(compilation, _diagnosticReceiver);
diff --git a/src/Durian.AnalysisServices/CodeBuilder.cs b/src/Durian.AnalysisServices/CodeBuilder.cs
index 3888c4d..9aff8f3 100644
--- a/src/Durian.AnalysisServices/CodeBuilder.cs
+++ b/src/Durian.AnalysisServices/CodeBuilder.cs
@@ -3,7 +3,6 @@
using System.Runtime.CompilerServices;
using System.Text;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis;
diff --git a/src/Durian.AnalysisServices/CodeBuilder.symbols.cs b/src/Durian.AnalysisServices/CodeBuilder.symbols.cs
index 3005a52..0dd6c3e 100644
--- a/src/Durian.AnalysisServices/CodeBuilder.symbols.cs
+++ b/src/Durian.AnalysisServices/CodeBuilder.symbols.cs
@@ -4,9 +4,7 @@
using System.Globalization;
using System.Reflection.Metadata;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Durian.Analysis;
diff --git a/src/Durian.AnalysisServices/CodeFixes/CodeFixUtility.cs b/src/Durian.AnalysisServices/CodeFixes/CodeFixUtility.cs
index 5f23d2c..19566d3 100644
--- a/src/Durian.AnalysisServices/CodeFixes/CodeFixUtility.cs
+++ b/src/Durian.AnalysisServices/CodeFixes/CodeFixUtility.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`1.cs b/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`1.cs
index 3dadbde..ce8088b 100644
--- a/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`1.cs
+++ b/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`1.cs
@@ -1,5 +1,4 @@
using System.Threading.Tasks;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`2.cs b/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`2.cs
index 00c75b5..962dd02 100644
--- a/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`2.cs
+++ b/src/Durian.AnalysisServices/CodeFixes/ReplaceNodeCodeFix`2.cs
@@ -1,5 +1,4 @@
using System.Threading.Tasks;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/CodeGeneration/LiteralWriter.cs b/src/Durian.AnalysisServices/CodeGeneration/LiteralWriter.cs
index a56c742..70a6f10 100644
--- a/src/Durian.AnalysisServices/CodeGeneration/LiteralWriter.cs
+++ b/src/Durian.AnalysisServices/CodeGeneration/LiteralWriter.cs
@@ -1,7 +1,6 @@
using System;
using System.Globalization;
using System.Text;
-using Durian.Analysis.Extensions;
namespace Durian.Analysis.CodeGeneration;
diff --git a/src/Durian.AnalysisServices/Extensions/CompilationExtensions.cs b/src/Durian.AnalysisServices/CompilationExtensions.cs
similarity index 99%
rename from src/Durian.AnalysisServices/Extensions/CompilationExtensions.cs
rename to src/Durian.AnalysisServices/CompilationExtensions.cs
index 343f2d4..b8c677a 100644
--- a/src/Durian.AnalysisServices/Extensions/CompilationExtensions.cs
+++ b/src/Durian.AnalysisServices/CompilationExtensions.cs
@@ -6,7 +6,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains various extension methods for the class.
diff --git a/src/Durian.AnalysisServices/Data/CompilationWithImportedTypes.cs b/src/Durian.AnalysisServices/Data/CompilationWithImportedTypes.cs
index 3650471..d8e3750 100644
--- a/src/Durian.AnalysisServices/Data/CompilationWithImportedTypes.cs
+++ b/src/Durian.AnalysisServices/Data/CompilationWithImportedTypes.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
-using Durian.Analysis.Extensions;
using Durian.Generator;
using Durian.Info;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/DataHelpers.cs b/src/Durian.AnalysisServices/Data/DataHelpers.cs
index 6e1dafa..b83bc00 100644
--- a/src/Durian.AnalysisServices/Data/DataHelpers.cs
+++ b/src/Durian.AnalysisServices/Data/DataHelpers.cs
@@ -1,7 +1,6 @@
using System;
using System.Runtime.CompilerServices;
using Durian.Analysis.Data.FromSource;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/AccessorData.cs b/src/Durian.AnalysisServices/Data/FromSource/AccessorData.cs
index 80a9ff7..33591e9 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/AccessorData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/AccessorData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/ConstructorData.cs b/src/Durian.AnalysisServices/Data/FromSource/ConstructorData.cs
index a643fa9..906e250 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/ConstructorData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/ConstructorData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/ConversionOperatorData.cs b/src/Durian.AnalysisServices/Data/FromSource/ConversionOperatorData.cs
index 847ac9f..1006c4c 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/ConversionOperatorData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/ConversionOperatorData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/DestructorData.cs b/src/Durian.AnalysisServices/Data/FromSource/DestructorData.cs
index 292e5a3..349ed09 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/DestructorData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/DestructorData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/EnumData.cs b/src/Durian.AnalysisServices/Data/FromSource/EnumData.cs
index 044c1f9..f82ddb1 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/EnumData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/EnumData.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Immutable;
using System.ComponentModel;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/EventData.cs b/src/Durian.AnalysisServices/Data/FromSource/EventData.cs
index 46cdd9b..7664890 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/EventData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/EventData.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/FieldData.cs b/src/Durian.AnalysisServices/Data/FromSource/FieldData.cs
index a6d0954..97987e2 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/FieldData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/FieldData.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/IndexerData.cs b/src/Durian.AnalysisServices/Data/FromSource/IndexerData.cs
index 7a8ef27..792d075 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/IndexerData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/IndexerData.cs
@@ -2,7 +2,6 @@
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/InterfaceData.cs b/src/Durian.AnalysisServices/Data/FromSource/InterfaceData.cs
index 8f151aa..745ac0e 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/InterfaceData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/InterfaceData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using System.Linq;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/LambdaData.cs b/src/Durian.AnalysisServices/Data/FromSource/LambdaData.cs
index 55e6deb..4ed3730 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/LambdaData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/LambdaData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/LocalFunctionData.cs b/src/Durian.AnalysisServices/Data/FromSource/LocalFunctionData.cs
index 1c20eae..ffe6ccd 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/LocalFunctionData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/LocalFunctionData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/MemberData.cs b/src/Durian.AnalysisServices/Data/FromSource/MemberData.cs
index 3129183..c3b242f 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/MemberData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/MemberData.cs
@@ -4,7 +4,6 @@
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/MethodData.cs b/src/Durian.AnalysisServices/Data/FromSource/MethodData.cs
index 6e32da5..a286c13 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/MethodData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/MethodData.cs
@@ -2,7 +2,6 @@
using System.ComponentModel;
using System.Linq;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/NamespaceData.cs b/src/Durian.AnalysisServices/Data/FromSource/NamespaceData.cs
index 42f8f5d..8c14ee6 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/NamespaceData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/NamespaceData.cs
@@ -4,7 +4,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/NamespaceOrTypeData.cs b/src/Durian.AnalysisServices/Data/FromSource/NamespaceOrTypeData.cs
index 2123e40..4980a7f 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/NamespaceOrTypeData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/NamespaceOrTypeData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using System.Linq;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/OperatorData.cs b/src/Durian.AnalysisServices/Data/FromSource/OperatorData.cs
index d269969..cfb2206 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/OperatorData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/OperatorData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/PropertyData.cs b/src/Durian.AnalysisServices/Data/FromSource/PropertyData.cs
index 36f9bb3..2adec7d 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/PropertyData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/PropertyData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using System.Linq;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/RecordData.cs b/src/Durian.AnalysisServices/Data/FromSource/RecordData.cs
index e2ec816..b3edafe 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/RecordData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/RecordData.cs
@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using System.Linq;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/TypeData.cs b/src/Durian.AnalysisServices/Data/FromSource/TypeData.cs
index b90ba6d..447d518 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/TypeData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/TypeData.cs
@@ -4,7 +4,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Data/FromSource/TypeParameterData.cs b/src/Durian.AnalysisServices/Data/FromSource/TypeParameterData.cs
index 8b6e429..749fed6 100644
--- a/src/Durian.AnalysisServices/Data/FromSource/TypeParameterData.cs
+++ b/src/Durian.AnalysisServices/Data/FromSource/TypeParameterData.cs
@@ -1,6 +1,5 @@
using System;
using System.ComponentModel;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
diff --git a/src/Durian.AnalysisServices/Data/SymbolOrMemberWrapper.cs b/src/Durian.AnalysisServices/Data/SymbolOrMemberWrapper.cs
index ea33841..efdef3c 100644
--- a/src/Durian.AnalysisServices/Data/SymbolOrMemberWrapper.cs
+++ b/src/Durian.AnalysisServices/Data/SymbolOrMemberWrapper.cs
@@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.Data;
diff --git a/src/Durian.AnalysisServices/Extensions/DiagnosticReceiverExtensions.cs b/src/Durian.AnalysisServices/DiagnosticReceiverExtensions.cs
similarity index 98%
rename from src/Durian.AnalysisServices/Extensions/DiagnosticReceiverExtensions.cs
rename to src/Durian.AnalysisServices/DiagnosticReceiverExtensions.cs
index 687a7c4..4be239f 100644
--- a/src/Durian.AnalysisServices/Extensions/DiagnosticReceiverExtensions.cs
+++ b/src/Durian.AnalysisServices/DiagnosticReceiverExtensions.cs
@@ -2,7 +2,7 @@
using System.Linq;
using Microsoft.CodeAnalysis;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains extension methods for the interface.
diff --git a/src/Durian.AnalysisServices/DurianAnalyzer.cs b/src/Durian.AnalysisServices/DurianAnalyzer.cs
index 1619598..c37e08f 100644
--- a/src/Durian.AnalysisServices/DurianAnalyzer.cs
+++ b/src/Durian.AnalysisServices/DurianAnalyzer.cs
@@ -46,9 +46,6 @@ public override void Initialize(AnalysisContext context)
Register(c);
}
- ///
- public abstract void Register(IDurianAnalysisContext context);
-
IEnumerable IDurianAnalyzer.GetSupportedDiagnostics()
{
return SupportedDiagnostics;
@@ -59,6 +56,10 @@ void IDurianAnalyzer.Register(IDurianAnalysisContext context, CSharpCompilation
Register(context, compilation);
}
+
+ ///
+ protected abstract void Register(IDurianAnalysisContext context);
+
///
protected virtual void Register(IDurianAnalysisContext context, CSharpCompilation compilation)
{
diff --git a/src/Durian.AnalysisServices/DurianAnalyzer`1.cs b/src/Durian.AnalysisServices/DurianAnalyzer`1.cs
index 226f500..63ce964 100644
--- a/src/Durian.AnalysisServices/DurianAnalyzer`1.cs
+++ b/src/Durian.AnalysisServices/DurianAnalyzer`1.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using Durian.Analysis.Data;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -53,7 +54,8 @@ public sealed override void Initialize(AnalysisContext context)
///
[Obsolete("Implementation of this method was removed - use Register(IDurianAnalysisContext, TCompilation) instead.")]
- public sealed override void Register(IDurianAnalysisContext context)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected sealed override void Register(IDurianAnalysisContext context)
#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member
{
// Do nothing
@@ -64,14 +66,7 @@ public sealed override void Register(IDurianAnalysisContext context)
///
/// to register the actions to.
/// to be used during the analysis.
- public abstract void Register(IDurianAnalysisContext context, TCompilation compilation);
-
- ///
- /// Creates a new based on the specified .
- ///
- /// to create the from.
- /// to report diagnostics to.
- protected abstract TCompilation CreateCompilation(CSharpCompilation compilation, IDiagnosticReceiver diagnosticReceiver);
+ protected abstract void Register(IDurianAnalysisContext context, TCompilation compilation);
///
protected sealed override void Register(IDurianAnalysisContext context, CSharpCompilation compilation)
@@ -87,6 +82,13 @@ protected sealed override void Register(IDurianAnalysisContext context, CSharpCo
ReportInitializationDiagnostics(context, diagnosticReceiver);
}
+ ///
+ /// Creates a new based on the specified .
+ ///
+ /// to create the from.
+ /// to report diagnostics to.
+ protected abstract TCompilation CreateCompilation(CSharpCompilation compilation, IDiagnosticReceiver diagnosticReceiver);
+
private static void ReportInitializationDiagnostics(IDurianAnalysisContext context, DiagnosticBag diagnosticReceiver)
{
if (diagnosticReceiver.Count > 0)
diff --git a/src/Durian.AnalysisServices/DurianGeneratorBase.cs b/src/Durian.AnalysisServices/DurianGeneratorBase.cs
index 48278a8..111d94a 100644
--- a/src/Durian.AnalysisServices/DurianGeneratorBase.cs
+++ b/src/Durian.AnalysisServices/DurianGeneratorBase.cs
@@ -6,7 +6,6 @@
using System.Text;
using System.Threading;
using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Extensions;
using Durian.Analysis.Logging;
using Durian.Info;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/DurianGeneratorWithBuilder.cs b/src/Durian.AnalysisServices/DurianGeneratorWithBuilder.cs
index e30d073..f08988f 100644
--- a/src/Durian.AnalysisServices/DurianGeneratorWithBuilder.cs
+++ b/src/Durian.AnalysisServices/DurianGeneratorWithBuilder.cs
@@ -3,7 +3,6 @@
using System.Text;
using Durian.Analysis.CodeGeneration;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Durian.Analysis.Logging;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
diff --git a/src/Durian.AnalysisServices/DurianIncrementalGenerator.cs b/src/Durian.AnalysisServices/DurianIncrementalGenerator.cs
index a310870..0fb75f1 100644
--- a/src/Durian.AnalysisServices/DurianIncrementalGenerator.cs
+++ b/src/Durian.AnalysisServices/DurianIncrementalGenerator.cs
@@ -1,5 +1,6 @@
-using System.Text;
-using System.Threading;
+using System;
+using System.Text;
+using Durian.Analysis.Logging;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
@@ -11,6 +12,38 @@ namespace Durian.Analysis;
///
public abstract class DurianIncrementalGenerator : DurianGeneratorBase, IIncrementalGenerator
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected DurianIncrementalGenerator()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Service that handles log files for this generator.
+ /// is .
+ protected DurianIncrementalGenerator(IGeneratorLogHandler logHandler) : base(logHandler)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Configures how this generator is initialized.
+ protected DurianIncrementalGenerator(in GeneratorLogCreationContext context) : base(in context)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Determines how the source generator should behave when logging information.
+ protected DurianIncrementalGenerator(LoggingConfiguration? loggingConfiguration) : base(loggingConfiguration)
+ {
+ }
+
///
public void Initialize(IncrementalGeneratorInitializationContext context)
{
@@ -24,14 +57,15 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
return compilation;
}, context.ReportDiagnostic));
- Register(context);
+ Register(compilation, context);
}
///
/// Adds generator-specific logic to the .
///
+ /// Current compilation.
/// The to register callbacks on
- protected abstract void Register(IncrementalGeneratorInitializationContext context);
+ protected abstract void Register(IncrementalValueProvider compilation, IncrementalGeneratorInitializationContext context);
///
/// Adds the specified to the .
diff --git a/src/Durian.AnalysisServices/Extensions/EnumExtensions.cs b/src/Durian.AnalysisServices/EnumExtensions.cs
similarity index 99%
rename from src/Durian.AnalysisServices/Extensions/EnumExtensions.cs
rename to src/Durian.AnalysisServices/EnumExtensions.cs
index 03b937a..38e772f 100644
--- a/src/Durian.AnalysisServices/Extensions/EnumExtensions.cs
+++ b/src/Durian.AnalysisServices/EnumExtensions.cs
@@ -6,7 +6,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains extension methods for various enum types.
diff --git a/src/Durian.AnalysisServices/Extensions/GeneratorExtensions.cs b/src/Durian.AnalysisServices/GeneratorExtensions.cs
similarity index 98%
rename from src/Durian.AnalysisServices/Extensions/GeneratorExtensions.cs
rename to src/Durian.AnalysisServices/GeneratorExtensions.cs
index 9db6f25..5d877c7 100644
--- a/src/Durian.AnalysisServices/Extensions/GeneratorExtensions.cs
+++ b/src/Durian.AnalysisServices/GeneratorExtensions.cs
@@ -1,7 +1,7 @@
using Durian.Analysis.Logging;
using Microsoft.CodeAnalysis;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains various extension methods for s.
diff --git a/src/Durian.AnalysisServices/GeneratorPassContext.cs b/src/Durian.AnalysisServices/GeneratorPassContext.cs
index 4b36333..efe9fef 100644
--- a/src/Durian.AnalysisServices/GeneratorPassContext.cs
+++ b/src/Durian.AnalysisServices/GeneratorPassContext.cs
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Threading;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Durian.Analysis.Logging;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Logging/GeneratorLogCreationContext.cs b/src/Durian.AnalysisServices/Logging/GeneratorLogCreationContext.cs
index 8c6627c..d91b94c 100644
--- a/src/Durian.AnalysisServices/Logging/GeneratorLogCreationContext.cs
+++ b/src/Durian.AnalysisServices/Logging/GeneratorLogCreationContext.cs
@@ -30,7 +30,7 @@ namespace Durian.Analysis.Logging;
public static GeneratorLogCreationContext Runtime => new();
///
- /// Determines whether to try to create a based on one of the .
+ /// Determines whether to try to create a based on one of the .
///
public bool CheckForConfigurationAttribute { get; }
diff --git a/src/Durian.AnalysisServices/Extensions/MemberDataExtensions.cs b/src/Durian.AnalysisServices/MemberDataExtensions.cs
similarity index 99%
rename from src/Durian.AnalysisServices/Extensions/MemberDataExtensions.cs
rename to src/Durian.AnalysisServices/MemberDataExtensions.cs
index 4957adf..f0001eb 100644
--- a/src/Durian.AnalysisServices/Extensions/MemberDataExtensions.cs
+++ b/src/Durian.AnalysisServices/MemberDataExtensions.cs
@@ -6,7 +6,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains various extension methods for the interface.
diff --git a/src/Durian.AnalysisServices/Extensions/ModuleUtilities.cs b/src/Durian.AnalysisServices/ModuleUtilities.cs
similarity index 99%
rename from src/Durian.AnalysisServices/Extensions/ModuleUtilities.cs
rename to src/Durian.AnalysisServices/ModuleUtilities.cs
index 49ea22d..d94567d 100644
--- a/src/Durian.AnalysisServices/Extensions/ModuleUtilities.cs
+++ b/src/Durian.AnalysisServices/ModuleUtilities.cs
@@ -7,7 +7,7 @@
using Durian.Info;
using Microsoft.CodeAnalysis;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains various -related extension methods for the class and interface.
diff --git a/src/Durian.AnalysisServices/Extensions/PackageUtilities.cs b/src/Durian.AnalysisServices/PackageUtilities.cs
similarity index 99%
rename from src/Durian.AnalysisServices/Extensions/PackageUtilities.cs
rename to src/Durian.AnalysisServices/PackageUtilities.cs
index 7e72805..d939ac4 100644
--- a/src/Durian.AnalysisServices/Extensions/PackageUtilities.cs
+++ b/src/Durian.AnalysisServices/PackageUtilities.cs
@@ -4,7 +4,7 @@
using Microsoft.CodeAnalysis;
using static Durian.Info.PackageIdentity;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains various -related extension methods for the class.
diff --git a/src/Durian.AnalysisServices/Extensions/SemanticModelExtensions.cs b/src/Durian.AnalysisServices/SemanticModelExtensions.cs
similarity index 99%
rename from src/Durian.AnalysisServices/Extensions/SemanticModelExtensions.cs
rename to src/Durian.AnalysisServices/SemanticModelExtensions.cs
index d223cf2..a24c757 100644
--- a/src/Durian.AnalysisServices/Extensions/SemanticModelExtensions.cs
+++ b/src/Durian.AnalysisServices/SemanticModelExtensions.cs
@@ -9,7 +9,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-namespace Durian.Analysis.Extensions;
+namespace Durian.Analysis;
///
/// Contains various extension methods for the class.
diff --git a/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.InnerContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.InnerContainer.cs
index 9f08282..b4c58d3 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.InnerContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.InnerContainer.cs
@@ -4,7 +4,6 @@
using System.Collections.Immutable;
using System.Linq;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.cs
index 6996b31..f0afdd2 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/LeveledSymbolContainer.cs
@@ -5,7 +5,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/ReturnOrderEnumerable.cs b/src/Durian.AnalysisServices/SymbolContainers/ReturnOrderEnumerable.cs
index 6d7fded..033fdd7 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/ReturnOrderEnumerable.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/ReturnOrderEnumerable.cs
@@ -2,7 +2,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
-using Durian.Analysis.Extensions;
namespace Durian.Analysis.SymbolContainers;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerMemberContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerMemberContainer.cs
index 501cf6f..802bbd4 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerMemberContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerMemberContainer.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers.Specialized;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerTypeContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerTypeContainer.cs
index 2bb98c0..cb7812a 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerTypeContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/Specialized/InnerTypeContainer.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers.Specialized;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/Specialized/LocalFunctionContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/Specialized/LocalFunctionContainer.cs
index 1e06371..70e6e1d 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/Specialized/LocalFunctionContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/Specialized/LocalFunctionContainer.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers.Specialized;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/Specialized/MethodOverloadContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/Specialized/MethodOverloadContainer.cs
index babbb35..14e0045 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/Specialized/MethodOverloadContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/Specialized/MethodOverloadContainer.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers.Specialized;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/Specialized/NamespaceOrTypeContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/Specialized/NamespaceOrTypeContainer.cs
index 25327e2..c8d1c90 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/Specialized/NamespaceOrTypeContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/Specialized/NamespaceOrTypeContainer.cs
@@ -3,7 +3,6 @@
using System.Linq;
using System.Runtime.CompilerServices;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers.Specialized;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/Specialized/SubNamespaceContainer.cs b/src/Durian.AnalysisServices/SymbolContainers/Specialized/SubNamespaceContainer.cs
index fb2b8f5..a5e6b5f 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/Specialized/SubNamespaceContainer.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/Specialized/SubNamespaceContainer.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers.Specialized;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerBase.cs b/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerBase.cs
index 7b82295..777471c 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerBase.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerBase.cs
@@ -6,7 +6,6 @@
using System.Linq;
using System.Runtime.CompilerServices;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Microsoft.CodeAnalysis;
namespace Durian.Analysis.SymbolContainers;
diff --git a/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerFactory.cs b/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerFactory.cs
index 0b4ed2c..5a7bf30 100644
--- a/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerFactory.cs
+++ b/src/Durian.AnalysisServices/SymbolContainers/SymbolContainerFactory.cs
@@ -6,7 +6,6 @@
using System.Runtime.CompilerServices;
using System.Text;
using Durian.Analysis.Data;
-using Durian.Analysis.Extensions;
using Durian.Analysis.SymbolContainers.Specialized;
using Microsoft.CodeAnalysis;
diff --git a/src/Durian.AnalysisServices/Extensions/SymbolExtensions.cs b/src/Durian.AnalysisServices/SymbolExtensions.cs
similarity index 97%
rename from src/Durian.AnalysisServices/Extensions/SymbolExtensions.cs
rename to src/Durian.AnalysisServices/SymbolExtensions.cs
index 3c207a7..cd7ba39 100644
--- a/src/Durian.AnalysisServices/Extensions/SymbolExtensions.cs
+++ b/src/Durian.AnalysisServices/SymbolExtensions.cs
@@ -1,3709 +1,3709 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Reflection.Metadata;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-using Durian.Analysis.CodeGeneration;
-using Durian.Analysis.Data;
-using Durian.Analysis.Data.FromSource;
-using Durian.Analysis.SymbolContainers;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-namespace Durian.Analysis.Extensions;
-
-///
-/// Contains various extension methods for the -derived interfaces.
-///
-public static class SymbolExtensions
-{
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this INamedTypeSymbol type)
- {
- TypeSyntax syntax;
-
- if (type.IsGenericType)
- {
- List arguments = new(type.TypeArguments.Length);
-
- foreach (ITypeSymbol t in type.TypeArguments)
- {
- arguments.Add(t.CreateTypeSyntax());
- }
-
- syntax = SyntaxFactory.GenericName(
- SyntaxFactory.Identifier(type.GetVerbatimName()),
- SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(arguments)));
- }
- else if (type.GetPredefineTypeSyntax() is PredefinedTypeSyntax predefined)
- {
- syntax = predefined;
- }
- else
- {
- syntax = SyntaxFactory.IdentifierName(type.GetVerbatimName());
- }
-
- return ApplyAnnotation(syntax, NullableAnnotation.Annotated);
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this IArrayTypeSymbol type)
- {
- ITypeSymbol[] elementTypes = type.GetElementTypes().ToArray();
- TypeSyntax elementSyntax = elementTypes[0].CreateTypeSyntax();
-
- List ranks = new(elementTypes.Length - 1);
-
- for (int i = 1; i < elementTypes.Length; i++)
- {
- IArrayTypeSymbol array = (IArrayTypeSymbol)elementTypes[i];
- ranks.Add(GetArrayRank(array));
-
- if (array.NullableAnnotation == NullableAnnotation.Annotated)
- {
- elementSyntax = SyntaxFactory.NullableType(SyntaxFactory.ArrayType(elementSyntax, SyntaxFactory.List(ranks)));
- ranks.Clear();
- }
- }
-
- ranks.Add(GetArrayRank(type));
-
- return ApplyAnnotation(SyntaxFactory.ArrayType(elementSyntax, SyntaxFactory.List(ranks)), type.NullableAnnotation);
-
- static ArrayRankSpecifierSyntax GetArrayRank(IArrayTypeSymbol array)
- {
- return SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.SeparatedList(
- array.Sizes.Select(s => SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(s)))));
- }
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this IFunctionPointerTypeSymbol functionPointer)
- {
- IMethodSymbol signature = functionPointer.Signature;
-
- FunctionPointerCallingConventionSyntax? callingConvention;
-
- if (signature.CallingConvention == SignatureCallingConvention.Unmanaged)
- {
- FunctionPointerUnmanagedCallingConventionListSyntax? list = signature.UnmanagedCallingConventionTypes.Length > 0 ?
- SyntaxFactory.FunctionPointerUnmanagedCallingConventionList(SyntaxFactory.SeparatedList(signature.UnmanagedCallingConventionTypes.Select(u =>
- SyntaxFactory.FunctionPointerUnmanagedCallingConvention(SyntaxFactory.Identifier(u.Name)))))
- : default;
-
- callingConvention = SyntaxFactory.FunctionPointerCallingConvention(SyntaxFactory.Token(SyntaxKind.UnmanagedKeyword), list);
- }
- else
- {
- callingConvention = default;
- }
-
- List parameters = new(signature.Parameters.Length + 1);
-
- foreach (IParameterSymbol parameter in signature.Parameters)
- {
- TypeSyntax parameterType = parameter.Type.CreateTypeSyntax();
- parameters.Add(GetParameterSyntax(parameterType, parameter.RefKind, false));
- }
-
- parameters.Add(GetParameterSyntax(signature.ReturnType.CreateTypeSyntax(), signature.RefKind, true));
-
- return SyntaxFactory.FunctionPointerType(callingConvention, SyntaxFactory.FunctionPointerParameterList(SyntaxFactory.SeparatedList(parameters)));
-
- static FunctionPointerParameterSyntax GetParameterSyntax(TypeSyntax parameterType, RefKind refKind, bool allowRefReadonly)
- {
- switch (refKind)
- {
- case RefKind.None:
- return SyntaxFactory.FunctionPointerParameter(parameterType);
-
- case RefKind.RefReadOnly:
-
- if (!allowRefReadonly)
- {
- goto default;
- }
-
- return SyntaxFactory.FunctionPointerParameter(default, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.RefKeyword), SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)), parameterType);
-
- default:
- SyntaxKind kind = refKind.GetSyntaxKind();
- return SyntaxFactory.FunctionPointerParameter(default, SyntaxFactory.TokenList(SyntaxFactory.Token(kind)), parameterType);
- }
- }
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this IDynamicTypeSymbol type)
- {
- return ApplyAnnotation(SyntaxFactory.IdentifierName("dynamic"), type.NullableAnnotation);
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this ITypeParameterSymbol typeParameter)
- {
- return ApplyAnnotation(SyntaxFactory.IdentifierName(typeParameter.GetVerbatimName()), typeParameter.NullableAnnotation);
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this IPointerTypeSymbol pointer)
- {
- return SyntaxFactory.PointerType(pointer.PointedAtType.CreateTypeSyntax());
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this ITypeSymbol type)
- {
- return type switch
- {
- INamedTypeSymbol named => named.CreateTypeSyntax(),
- IDynamicTypeSymbol dynamic => dynamic.CreateTypeSyntax(),
- IArrayTypeSymbol array => array.CreateTypeSyntax(),
- ITypeParameterSymbol typeParameter => typeParameter.CreateTypeSyntax(),
- IPointerTypeSymbol pointer => pointer.CreateTypeSyntax(),
- IFunctionPointerTypeSymbol functionPointer => functionPointer.CreateTypeSyntax(),
- _ => ApplyAnnotation(SyntaxFactory.IdentifierName(type.GetVerbatimName()), type.NullableAnnotation),
- };
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this ISymbol symbol)
- {
- if (symbol is ITypeSymbol type)
- {
- return type.CreateTypeSyntax();
- }
-
- if (symbol is IMethodSymbol method)
- {
- return method.CreateTypeSyntax();
- }
-
- return SyntaxFactory.IdentifierName(symbol.GetVerbatimName());
- }
-
- ///
- /// Creates a representing the specified .
- ///
- /// to get the for.
- public static TypeSyntax CreateTypeSyntax(this IMethodSymbol method)
- {
- if (!method.IsGenericMethod)
- {
- return SyntaxFactory.IdentifierName(method.GetVerbatimName());
- }
-
- List arguments = new(method.TypeArguments.Length);
-
- foreach (ITypeSymbol type in method.TypeArguments)
- {
- arguments.Add(type.CreateTypeSyntax());
- }
-
- return SyntaxFactory.GenericName(
- SyntaxFactory.Identifier(method.GetVerbatimName()),
- SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(arguments)));
- }
-
- ///
- /// Returns the kind of accessor the specified represents.
- ///
- /// to get the accessor kind of.
- public static AccessorKind GetAccessorKind(this IMethodSymbol method)
- {
- return method.MethodKind.GetAccessorKind();
- }
-
- ///
- /// Returns a collection of all inner types of the specified .
- ///
- /// to get the inner types of.
- /// Determines whether to include the in the returned collection if its a .
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetAllInnerTypes(this INamespaceOrTypeSymbol type, bool includeSelf = false, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return Yield().OrderBy(order, ReturnOrder.ChildToParent);
-
- IEnumerable Yield()
- {
- const int CAPACITY = 32;
-
- if (includeSelf && type is INamedTypeSymbol named)
- {
- yield return named;
- }
-
- ImmutableArray array = type.GetTypeMembers();
-
- if (array.Length == 0)
- {
- yield break;
- }
-
- Stack innerTypes = new(array.Length > CAPACITY ? array.Length : CAPACITY);
-
- PushReverse(ref array, innerTypes);
-
- while (innerTypes.Count > 0)
- {
- INamedTypeSymbol t = innerTypes.Pop();
- yield return t;
-
- array = t.GetTypeMembers();
-
- if (array.Length == 0)
- {
- continue;
- }
-
- PushReverse(ref array, innerTypes);
- }
- }
- }
-
- ///
- public static IReturnOrderEnumerable GetAllMembers(this INamedTypeSymbol type, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return GetBaseTypes_Internal(type, true).SelectMany(t => t.GetMembers()).OrderBy(order, ReturnOrder.ChildToParent);
- }
-
- ///
- /// Returns all members of the specified including the members that are declared in base types of this .
- ///
- /// to get the members of.
- /// Name of the members to find.
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetAllMembers(this INamedTypeSymbol type, string name, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return GetBaseTypes_Internal(type, true).SelectMany(t => t.GetMembers(name)).OrderBy(order, ReturnOrder.ChildToParent);
- }
-
- ///
- /// Returns an associated with the and defined on the specified .
- ///
- /// Target .
- /// Type of attribute to look for.
- /// The associated with the and defined on the specified . -or- if no such found.
- public static AttributeData? GetAttribute(this ISymbol symbol, INamedTypeSymbol attrSymbol)
- {
- return symbol.GetAttributes()
- .FirstOrDefault(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, attrSymbol));
- }
-
- ///
- /// Returns an associated with the defined on the specified .
- ///
- /// Target .
- /// to get the data of.
- /// The associated with the . -or- if no such found.
- public static AttributeData? GetAttribute(this ISymbol symbol, AttributeSyntax syntax)
- {
- foreach (AttributeData attr in symbol.GetAttributes())
- {
- SyntaxReference? reference = attr.ApplicationSyntaxReference;
-
- if (reference is null)
- {
- continue;
- }
-
- if (reference.Span == syntax.Span)
- {
- return attr;
- }
- }
-
- return null;
- }
-
- ///
- /// Returns a collection of s associated with the and defined on the specified .
- ///
- /// Target .
- /// Type of attributes to look for.
- public static IEnumerable GetAttributes(this ISymbol symbol, INamedTypeSymbol attrSymbol)
- {
- foreach (AttributeData attr in symbol.GetAttributes())
- {
- if (SymbolEqualityComparer.Default.Equals(attr.AttributeClass, attrSymbol))
- {
- yield return attr;
- }
- }
- }
-
- ///
- /// Returns the that is accessed by using the specified in the context of the given .
- ///
- /// to get the attribute target symbol of.
- /// Kind of attribute target.
- /// Note: In actual code the target applied to an event refers to both the and accessors. In such case, this method returns the event itself.
- public static ISymbol? GetAttributeTarget(this ISymbol symbol, AttributeTarget target)
- {
- switch (target)
- {
- case AttributeTarget.Assembly:
- return symbol as IAssemblySymbol;
-
- case AttributeTarget.Return:
- {
- if (symbol is IMethodSymbol method)
- {
- if (!method.IsConstructor() && method.MethodKind != MethodKind.Destructor)
- {
- return method.ReturnType;
- }
- }
- else if (symbol is INamedTypeSymbol type)
- {
- if (type.DelegateInvokeMethod is not null)
- {
- return type.DelegateInvokeMethod.ReturnType;
- }
- }
-
- return default;
- }
-
- case AttributeTarget.Field:
- {
- if (symbol is IPropertySymbol property)
- {
- if (property.GetBackingField() is IFieldSymbol backingField)
- {
- return backingField;
- }
- }
- else if (symbol is IEventSymbol @event)
- {
- if (@event.GetBackingField() is IFieldSymbol backingField)
- {
- return backingField;
- }
- }
-
- return symbol as IFieldSymbol;
- }
-
- case AttributeTarget.Method:
- return symbol is IMethodSymbol or IEventSymbol ? symbol : default;
-
- case AttributeTarget.Property:
- return symbol as IPropertySymbol;
-
- case AttributeTarget.Event:
- return symbol as IEventSymbol;
-
- case AttributeTarget.Type:
- return symbol as INamedTypeSymbol;
-
- case AttributeTarget.Param:
- {
- if (symbol is IMethodSymbol method && method.MethodKind is MethodKind.PropertySet or MethodKind.EventAdd or MethodKind.EventRemove)
- {
- return method.Parameters[0];
- }
-
- return symbol as IParameterSymbol;
- }
-
- case AttributeTarget.Module:
- return symbol as IModuleSymbol;
-
- case AttributeTarget.TypeVar:
- return symbol as ITypeParameterSymbol;
-
- default:
- return default;
- }
- }
-
- ///
- /// Returns the that is accessed by using an attribute target if the specified in the context of the given .
- ///
- /// to get the attribute target symbol of.
- /// Kind of attribute target.
- /// Note: In actual code the target applied to an event refers to both the and accessors. In such case, this method returns the event itself.
- public static ISymbol? GetAttributeTarget(this ISymbol symbol, AttributeTargetKind kind)
- {
- return symbol switch
- {
- IAssemblySymbol => ThisOrDefault(),
- IFieldSymbol => ThisOrDefault(),
- IMethodSymbol method => kind switch
- {
- AttributeTargetKind.This => method.SupportsAttributeTargets() ? method : default,
- AttributeTargetKind.Value => method.SupportsAlternativeAttributeTargets() ? method.ReturnType : default,
- AttributeTargetKind.Handler when method.MethodKind == MethodKind.PropertySet || method.IsEventAccessor() => method.Parameters[0],
- _ => default
- },
- IPropertySymbol property => kind switch
- {
- AttributeTargetKind.This => property,
- AttributeTargetKind.Value => property.GetBackingField(),
- _ => default
- },
- IEventSymbol @event => kind switch
- {
- AttributeTargetKind.This => @event,
- AttributeTargetKind.Value => @event.GetBackingField(),
- AttributeTargetKind.Handler when @event.IsFieldEvent() => @event,
- _ => default
- },
- INamedTypeSymbol type => kind switch
- {
- AttributeTargetKind.This => type,
- AttributeTargetKind.Value when type.DelegateInvokeMethod is IMethodSymbol method => method.ReturnType,
- _ => default
- },
- IParameterSymbol => ThisOrDefault(),
- ITypeParameterSymbol => ThisOrDefault(),
- IModuleSymbol => ThisOrDefault(),
- _ => default
- };
-
- ISymbol? ThisOrDefault()
- {
- return kind == AttributeTargetKind.This ? symbol : default;
- }
- }
-
- ///
- /// Determines the kind of the specified attribute used in context of the given .
- ///
- /// to get the kind of attribute target of.
- /// Attribute target to get the kind of.
- public static AttributeTargetKind GetAttributeTargetKind(this ISymbol symbol, AttributeTarget target)
- {
- return target switch
- {
- AttributeTarget.Assembly => symbol is IAssemblySymbol ? AttributeTargetKind.This : default,
- AttributeTarget.Field => symbol switch
- {
- IFieldSymbol => AttributeTargetKind.This,
- IPropertySymbol property => property.IsAutoProperty() ? AttributeTargetKind.Value : default,
- IEventSymbol @event when @event.IsFieldEvent() => AttributeTargetKind.Value,
- _ => default
- },
- AttributeTarget.Return => symbol switch
- {
- IMethodSymbol method => method.SupportsAlternativeAttributeTargets() ? AttributeTargetKind.Value : default,
- INamedTypeSymbol type when type.SupportsAlternativeAttributeTargets() => AttributeTargetKind.Value,
- _ => default
- },
- AttributeTarget.Method => symbol switch
- {
- IMethodSymbol => AttributeTargetKind.This,
- IEventSymbol @event when @event.IsFieldEvent() => AttributeTargetKind.Handler,
- _ => default
- },
- AttributeTarget.Property => symbol is IPropertySymbol ? AttributeTargetKind.This : default,
- AttributeTarget.Event => symbol is IEventSymbol ? AttributeTargetKind.This : default,
- AttributeTarget.Type => symbol is INamedTypeSymbol ? AttributeTargetKind.This : default,
- AttributeTarget.Param => symbol switch
- {
- IParameterSymbol => AttributeTargetKind.This,
- IMethodSymbol method when method.MethodKind == MethodKind.PropertySet || method.IsEventAccessor() => AttributeTargetKind.Handler,
- _ => default
- },
- AttributeTarget.TypeVar => symbol is ITypeParameterSymbol ? AttributeTargetKind.This : default,
- AttributeTarget.Module => symbol is IModuleSymbol ? AttributeTargetKind.This : default,
- _ => default
- };
- }
-
- ///
- /// Returns an attribute target keyword used to refer to the specified inside an attribute list.
- ///
- /// to get the associated attribute target keyword of.
- /// Determines which keyword to return when there is more than one option (e.g '' and '' for methods).
- public static AttributeTarget GetAttributeTargetKind(this ISymbol symbol, AttributeTargetKind kind = AttributeTargetKind.This)
- {
- return symbol switch
- {
- IAssemblySymbol => ThisOrDefault(AttributeTarget.Assembly),
- IFieldSymbol => ThisOrDefault(AttributeTarget.Field),
- IMethodSymbol method => kind switch
- {
- AttributeTargetKind.This => method.SupportsAttributeTargets() ? AttributeTarget.Method : default,
- AttributeTargetKind.Value => method.SupportsAlternativeAttributeTargets() && method.MethodKind != MethodKind.PropertySet ? AttributeTarget.Return : default,
- AttributeTargetKind.Handler when method.MethodKind == MethodKind.PropertySet || method.IsEventAccessor() => AttributeTarget.Param,
- _ => default
- },
- IPropertySymbol property => kind switch
- {
- AttributeTargetKind.This => AttributeTarget.Property,
- AttributeTargetKind.Value when property.IsAutoProperty() => AttributeTarget.Field,
- _ => default
- },
- IEventSymbol @event => kind switch
- {
- AttributeTargetKind.This => AttributeTarget.Event,
- AttributeTargetKind.Value => @event.IsFieldEvent() ? AttributeTarget.Field : default,
- AttributeTargetKind.Handler when @event.IsFieldEvent() => AttributeTarget.Method,
- _ => default
- },
- INamedTypeSymbol type => kind switch
- {
- AttributeTargetKind.This => AttributeTarget.Type,
- AttributeTargetKind.Value when type.SupportsAlternativeAttributeTargets() => AttributeTarget.Return,
- _ => default
- },
- IParameterSymbol => ThisOrDefault(AttributeTarget.Param),
- ITypeParameterSymbol => ThisOrDefault(AttributeTarget.TypeVar),
- IModuleSymbol => ThisOrDefault(AttributeTarget.Module),
- _ => default,
- };
-
- AttributeTarget ThisOrDefault(AttributeTarget @this)
- {
- return kind == AttributeTargetKind.This ? @this : default;
- }
- }
-
- ///
- /// Returns the of the specified .
- ///
- /// to get the of.
- /// Determines whether to return even if the is or .
- public static AutoPropertyKind GetAutoPropertyKind(this IPropertySymbol property, bool includeAbstract = false)
- {
- if (includeAbstract)
- {
- if (property.GetMethod is null)
- {
- if (property.SetMethod is not null)
- {
- if (property.SetMethod.IsInitOnly)
- {
- return AutoPropertyKind.InitOnly;
- }
-
- return AutoPropertyKind.SetOnly;
- }
-
- return default;
- }
- }
- else if (property.IsAbstract || property.IsExtern || !property.IsAutoProperty() || property.GetMethod is null)
- {
- return default;
- }
-
- if (property.SetMethod is null)
- {
- return AutoPropertyKind.GetOnly;
- }
-
- if (property.SetMethod.IsInitOnly)
- {
- return AutoPropertyKind.GetInit;
- }
-
- return AutoPropertyKind.GetSet;
- }
-
- ///
- /// Returns the type of result of awaiting on the specified .
- ///
- /// to get the type of result of awaiting on.
- public static ITypeSymbol? GetAwaitResult(this INamedTypeSymbol type)
- {
- bool hasIsCompleted = false;
- bool hasGetResult = false;
-
- ITypeSymbol? resultType = default;
-
- if (!type.IsINotifyCompletion())
- {
- foreach (IMethodSymbol method in type.GetAllMembers().OfType())
- {
- if (method.IsGetAwaiterRaw(out INamedTypeSymbol? returnType) && HandleAwaiterType(type))
- {
- return resultType;
- }
- }
-
- return default;
- }
-
- List awaiters = new();
-
- foreach (ISymbol symbol in type.GetAllMembers())
- {
- bool? handleResultType = HandleResultType(symbol);
-
- if (handleResultType.HasValue)
- {
- if (handleResultType.Value)
- {
- return resultType;
- }
- }
- else if (symbol is IMethodSymbol method && method.IsGetAwaiterRaw(out INamedTypeSymbol? awaiter))
- {
- awaiters.Add(awaiter);
- }
- }
-
- foreach (INamedTypeSymbol awaiter in awaiters)
- {
- if (HandleAwaiterType(awaiter))
- {
- return resultType;
- }
- }
-
- return default;
-
- bool HandleAwaiterType(INamedTypeSymbol type)
- {
- if (!type.IsINotifyCompletion())
- {
- return false;
- }
-
- resultType = default;
-
- hasIsCompleted = false;
- hasGetResult = false;
-
- foreach (ISymbol symbol in type.GetAllMembers())
- {
- bool? handleResultType = HandleResultType(symbol);
-
- if (handleResultType == true)
- {
- return true;
- }
- }
-
- return false;
- }
-
- bool? HandleResultType(ISymbol symbol)
- {
- if (!hasIsCompleted && symbol.IsSpecialMember(SpecialMember.IsCompleted))
- {
- if (hasGetResult)
- {
- return true;
- }
-
- hasIsCompleted = true;
-
- return false;
- }
- else if (!hasGetResult && symbol.IsSpecialMember(SpecialMember.GetResult))
- {
- IMethodSymbol method = (symbol as IMethodSymbol)!;
- resultType = method.ReturnsVoid ? default : method.ReturnType;
-
- if (hasIsCompleted)
- {
- return true;
- }
-
- hasGetResult = true;
-
- return false;
- }
-
- return default;
- }
- }
-
- ///
- /// Returns the backing field of the specified or if the is not auto-implemented.
- ///
- /// to get the backing field of.
- public static IFieldSymbol? GetBackingField(this IPropertySymbol property)
- {
- if (property.IsIndexer || property.IsAbstract || property.IsExtern)
- {
- return default;
- }
-
- return property.ContainingType?
- .GetMembers()
- .OfType()
- .FirstOrDefault(f => SymbolEqualityComparer.Default.Equals(f.AssociatedSymbol, property));
- }
-
- ///
- /// Returns the backing field of the specified or if the is not a field-like event.
- ///
- /// to get the backing field of.
- public static IFieldSymbol? GetBackingField(this IEventSymbol @event)
- {
- return @event.ContainingType?
- .GetMembers()
- .OfType()
- .FirstOrDefault(f => SymbolEqualityComparer.Default.Equals(f.AssociatedSymbol, @event));
- }
-
- ///
- /// Returns the kind of the of the specified .
- ///
- /// to get the of.
- public static BackingFieldKind GetBackingFieldKind(this IFieldSymbol field)
- {
- return field.AssociatedSymbol switch
- {
- IPropertySymbol => BackingFieldKind.Property,
- IEventSymbol => BackingFieldKind.Event,
- _ => default
- };
- }
-
- ///
- /// Returns the kind of the backing field of the specified .
- ///
- /// to get the kind of the backing field of.
- public static BackingFieldKind GetBackingFieldKind(this ISymbol symbol)
- {
- return symbol switch
- {
- IFieldSymbol field => field.GetBackingFieldKind(),
- IPropertySymbol => BackingFieldKind.Property,
- IEventSymbol => BackingFieldKind.Event,
- _ => default
- };
- }
-
- ///
- /// Returns all types the specified inherits from.
- ///
- /// to get the base types of.
- /// Determines whether to include the in the returned collection.
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetBaseTypes(this INamedTypeSymbol type, bool includeSelf = false, ReturnOrder order = ReturnOrder.ChildToParent)
- {
- return GetBaseTypes_Internal(type, includeSelf).OrderBy(order, ReturnOrder.ParentToChild);
- }
-
- ///
- /// Returns the compiler condition applied to the through the .
- ///
- /// to get the compiler condition of.
- public static string? GetCompilerCondition(this IMethodSymbol method)
- {
- AttributeData? attribute = method.GetSpecialAttribute(SpecialAttribute.Conditional);
- return attribute?.GetConstructorArgumentValue(0);
- }
-
- ///
- /// Returns the compiler condition applied to the through the .
- ///
- /// to get the compiler condition of.
- public static string? GetCompilerCondition(this INamedTypeSymbol type)
- {
- AttributeData? attribute = type.GetSpecialAttribute(SpecialAttribute.Conditional);
- return attribute?.GetConstructorArgumentValue(0);
- }
-
- ///
- /// Returns generic constraints applied to type parameters of the specified .
- ///
- /// to get the generic constraints of.
- ///
- /// If a is constrained to another ,
- /// determines whether to also include constraints of that 's base parameter.
- ///
- public static GenericConstraint[] GetConstraints(this IMethodSymbol method, bool includeParentParameters = false)
- {
- if (!method.IsGenericMethod)
- {
- return Array.Empty();
- }
-
- return method.TypeParameters.Select(p => p.GetConstraints(includeParentParameters)).ToArray();
- }
-
- ///
- /// Returns generic constraints applied to type parameters of the specified .
- ///
- /// to get the generic constraints of.
- ///
- /// If a is constrained to another ,
- /// determines whether to also include constraints of that 's base parameter.
- ///
- public static GenericConstraint[] GetConstraints(this INamedTypeSymbol type, bool includeParentParameters = false)
- {
- if (!type.IsGenericType)
- {
- return Array.Empty();
- }
-
- return type.TypeParameters.Select(p => p.GetConstraints(includeParentParameters)).ToArray();
- }
-
- ///
- /// Returns generic constraints applied to the specified .
- ///
- /// to get the generic constraint of.
- ///
- /// If the is constrained to another ,
- /// determines whether to also include constraints of the 's base parameter.
- ///
- public static GenericConstraint GetConstraints(this ITypeParameterSymbol parameter, bool includeParentParameter = false)
- {
- GenericConstraint constraint = default;
-
- if (parameter.HasReferenceTypeConstraint)
- {
- constraint |= GenericConstraint.Class;
- }
-
- if (parameter.HasValueTypeConstraint)
- {
- constraint |= GenericConstraint.Struct;
- }
-
- if (parameter.HasUnmanagedTypeConstraint)
- {
- constraint |= GenericConstraint.Unmanaged;
- }
-
- if (parameter.HasConstructorConstraint)
- {
- constraint |= GenericConstraint.New;
- }
-
- if (parameter.HasNotNullConstraint)
- {
- constraint |= GenericConstraint.NotNull;
- }
-
- if (parameter.ConstraintTypes.Length > 0)
- {
- constraint |= GenericConstraint.Type;
-
- if (includeParentParameter && parameter.ConstraintTypes.FirstOrDefault(p => p.TypeKind == TypeKind.TypeParameter) is ITypeParameterSymbol baseParameter)
- {
- constraint |= baseParameter.GetConstraints(true);
- }
- }
-
- return constraint;
- }
-
- ///
- /// Returns value representing special kind of the specified .
- ///
- /// to get the special constructor kind of.
- public static SpecialConstructor GetConstructorKind(this IMethodSymbol method)
- {
- if (method.MethodKind == MethodKind.StaticConstructor)
- {
- return SpecialConstructor.Static;
- }
-
- if (method.IsVararg)
- {
- return default;
- }
-
- if (method.Parameters.Length == 0)
- {
- return method.IsImplicitlyDeclared ? SpecialConstructor.Default : SpecialConstructor.Parameterless;
- }
-
- if (method.Parameters.Length == 1 && method.Parameters[0].RefKind == RefKind.None && SymbolEqualityComparer.Default.Equals(method.Parameters[0].Type, method.ContainingType))
- {
- return SpecialConstructor.Copy;
- }
-
- return default;
- }
-
- ///
- /// Returns all s that contain the target .
- ///
- /// to get the parent namespaces of.
- /// Determines whether to return the global namespace as well.
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetContainingNamespaces(this ISymbol symbol, bool includeGlobal = false, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- IEnumerable namespaces = Yield(symbol);
-
- if (!includeGlobal)
- {
- namespaces = namespaces.Where(n => !n.IsGlobalNamespace);
- }
-
- return namespaces.OrderBy(order, ReturnOrder.ParentToChild);
-
- static IEnumerable Yield(ISymbol symbol)
- {
- INamespaceSymbol parent = symbol.ContainingNamespace;
-
- if (parent is not null)
- {
- yield return parent;
-
- while ((parent = parent!.ContainingNamespace) is not null)
- {
- yield return parent;
- }
- }
- }
- }
-
- ///
- /// Returns all s contain the target in namespace-first order.
- ///
- /// to get the parent types and namespaces of.
- /// Determines whether to return the global namespace as well
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetContainingNamespacesAndTypes(this ISymbol symbol, bool includeGlobal = false, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- IEnumerable first;
- IEnumerable second;
-
- if (order == ReturnOrder.ParentToChild)
- {
- first = symbol.GetContainingNamespaces(includeGlobal, order);
- second = symbol.GetContainingTypes(false, order);
- }
- else
- {
- first = symbol.GetContainingTypes(false, order);
- second = symbol.GetContainingNamespaces(includeGlobal, order);
- }
-
- return first.Concat(second).OrderBy(order, GetNoReverseFlag(order));
- }
-
- ///
- /// Returns all s that contain the target .
- ///
- /// to get the parent types of.
- /// Determines whether to include the in the returned collection if its a .
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetContainingTypes(this ISymbol symbol, bool includeSelf = false, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return Yield(symbol, includeSelf).OrderBy(order, ReturnOrder.ParentToChild);
-
- static IEnumerable Yield(ISymbol symbol, bool includeSelf)
- {
- if (includeSelf && symbol is INamedTypeSymbol t)
- {
- yield return t;
- }
-
- INamedTypeSymbol parent = symbol.ContainingType;
-
- if (parent is not null)
- {
- yield return parent;
-
- while ((parent = parent!.ContainingType) is not null)
- {
- yield return parent;
- }
- }
- }
- }
-
- ///
- /// Returns the custom offset applied to the field through a or -1 if no custom offset applied.
- ///
- /// to get the custom offset of.
- public static int GetCustomOffset(this IFieldSymbol field)
- {
- AttributeData? attribute = field.GetSpecialAttribute(SpecialAttribute.FieldOffset);
-
- if (attribute is null)
- {
- return -1;
- }
-
- return attribute.TryGetConstructorArgumentValue(0, out int value) ? value : -1;
- }
-
- ///
- /// Returns a keyword used to declare the specified (e.g. , ).
- ///
- /// to get the keyword of.
- public static string? GetDeclaredKeyword(this ISymbol symbol)
- {
- return symbol switch
- {
- INamedTypeSymbol type => type.GetDeclaredKeyword(),
- IEventSymbol => "event",
- IMethodSymbol method when method.IsOperator() => "operator",
- _ => default
- };
- }
-
- ///
- /// Returns a keyword used to declare the specified (e.g. , ).
- ///
- /// to get the keyword of.
- /// Determines whether to include the keyword for record classes.
- public static string? GetDeclaredKeyword(this INamedTypeSymbol type, bool includeSecondary = false)
- {
- return type.TypeKind switch
- {
- TypeKind.Class => type.IsRecord ? (includeSecondary ? "record class" : "record") : "class",
- TypeKind.Struct => type.IsRecord ? "record struct" : "struct",
- TypeKind.Interface => "interface",
- TypeKind.Enum => "enum",
- TypeKind.Delegate => "delegate",
- _ => default
- };
- }
-
- ///
- /// Returns the default in the context of the specified , that is:
- ///
- /// - For top-level types: .
- /// - For interface members other than partial methods: .
- /// - For property/event accessors: accessibility of the parent property/event.
- /// - For all other members: .
- ///
- ///
- /// to get the default accessibility of.
- /// Determines whether accessibility of an associated member of the (e.g. parent property of an accessor) should be treated as default.
- public static Accessibility GetDefaultAccessibility(this ISymbol symbol, bool includeAssociated = true)
- {
- if (symbol.IsTopLevel())
- {
- return Accessibility.Internal;
- }
-
- if (symbol.ContainingSymbol is INamedTypeSymbol type && type.TypeKind == TypeKind.Interface)
- {
- if (symbol is IMethodSymbol intfMethod && intfMethod.IsPartial(true))
- {
- return Accessibility.Private;
- }
-
- return Accessibility.Public;
- }
-
- if (includeAssociated && symbol is IMethodSymbol method && method.IsAccessor())
- {
- return method.AssociatedSymbol!.DeclaredAccessibility;
- }
-
- return Accessibility.Private;
- }
-
- ///
- /// Returns all interface members that have default implementations.
- ///
- /// of an interface to get the default implementations of.
- /// Determines whether to also include default implementations from the implemented interfaces.
- public static IEnumerable GetDefaultImplementations(this INamedTypeSymbol type, bool baseInterfaces = false)
- {
- if (type.TypeKind != TypeKind.Interface)
- {
- return Array.Empty();
- }
-
- IEnumerable members = baseInterfaces
- ? type.GetAllMembers()
- : type.GetMembers();
-
- return members.Where(m => m.IsDefaultImplementation());
- }
-
- ///
- /// Returns the effective of the specified .
- ///
- /// to get the effective of.
- public static Accessibility GetEffectiveAccessibility(this ISymbol symbol)
- {
- ISymbol? s = symbol;
- Accessibility lowest = Accessibility.Public;
-
- while (s is not null)
- {
- Accessibility current = s.DeclaredAccessibility;
-
- if (current == Accessibility.Private)
- {
- return current;
- }
-
- if (current != Accessibility.NotApplicable && current < lowest)
- {
- lowest = current;
- }
-
- s = s.ContainingSymbol;
- }
-
- return lowest;
- }
-
- ///
- /// Returns the effective underlaying element type of the specified .
- ///
- /// to get the effective underlaying type of.
- public static ITypeSymbol? GetEffectiveElementType(this ITypeSymbol type)
- {
- return type switch
- {
- IArrayTypeSymbol array => array.GetEffectiveElementType(),
- IPointerTypeSymbol pointer => pointer.GetEffectiveElementType(),
- _ => type.GetNullableUnderlayingType() is ITypeSymbol nullable ? nullable : default,
- };
- }
-
- ///
- /// Returns the effective underlaying element type of the .
- ///
- /// to get the effective underlaying type of.
- public static ITypeSymbol GetEffectiveElementType(this IArrayTypeSymbol array)
- {
- return array.GetEffectiveElementType(out _);
- }
-
- ///
- /// Returns the effective underlaying element type of the .
- ///
- /// to get the effective underlaying type of.
- /// Number of inner s (including the itself).
- public static ITypeSymbol GetEffectiveElementType(this IArrayTypeSymbol array, out int nestingLevel)
- {
- int count = 0;
- ITypeSymbol? a = array;
-
- while (a is IArrayTypeSymbol t)
- {
- a = t.ElementType;
- count++;
- }
-
- nestingLevel = count;
- return a;
- }
-
- ///
- /// Returns the effective underlaying type the .
- ///
- /// to get the effective underlaying type of.
- public static ITypeSymbol GetEffectiveElementType(this IPointerTypeSymbol pointer)
- {
- return pointer.GetEffectiveElementType(out _);
- }
-
- ///
- /// Returns the effective underlaying type the .
- ///
- /// to get the effective underlaying type of.
- /// Number of inner s (including the itself).
- public static ITypeSymbol GetEffectiveElementType(this IPointerTypeSymbol pointer, out int nestingLevel)
- {
- ITypeSymbol? p = pointer;
- int count = 0;
-
- while (p is IPointerTypeSymbol t)
- {
- p = t.PointedAtType;
- count++;
- }
-
- nestingLevel = count;
- return p;
- }
-
- ///
- /// Returns all underlaying element types of the specified .
- ///
- /// to get the element types of.
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetElementTypes(this IArrayTypeSymbol array, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return Yield().OrderBy(order, ReturnOrder.ChildToParent);
-
- IEnumerable Yield()
- {
- ITypeSymbol element = array.ElementType;
-
- yield return element;
-
- while (element is IArrayTypeSymbol array)
- {
- yield return array.ElementType;
- element = array.ElementType;
- }
- }
- }
-
- ///
- /// Returns all underlaying element types of the specified .
- ///
- /// to get the element types of.
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetElementTypes(this IPointerTypeSymbol pointer, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return Yield().OrderBy(order, ReturnOrder.ChildToParent);
-
- IEnumerable Yield()
- {
- ITypeSymbol element = pointer.PointedAtType;
-
- yield return element;
-
- while (element is IPointerTypeSymbol pointer)
- {
- yield return pointer.PointedAtType;
- element = pointer.PointedAtType;
- }
- }
- }
-
- ///
- /// Returns a representing a C# keyword associated with the of the specified .
- ///
- /// to get the keyword associated with.
- public static TypeKeyword GetEnumUnderlayingTypeKeyword(this INamedTypeSymbol type)
- {
- return type.EnumUnderlyingType?.GetTypeKeywordKind() ?? default;
- }
-
- ///
- /// Returns formatted name of the specified .
- ///
- /// to get the formatted name of.
- /// format to apply.
- public static string GetFormattedName(this ISymbol symbol, SymbolName format)
- {
- CodeBuilder builder = new(false);
- builder.Name(symbol, format);
- return builder.ToString();
- }
-
- ///
- /// Returns fully qualified name of the specified .
- ///
- /// to get the fully qualified name of.
- /// Determines format of the returned qualified name.
- public static string GetFullyQualifiedName(this ISymbol symbol, QualifiedName format = default)
- {
- if (format == QualifiedName.Metadata)
- {
- return symbol.ToString();
- }
-
- CodeBuilder builder = new(false);
- builder.QualifiedName(symbol);
- string value = builder.ToString();
-
- if (format == QualifiedName.Xml)
- {
- return AnalysisUtilities.ToXmlCompatible(value);
- }
-
- return value;
- }
-
- ///
- /// Returns a containing generic identifier of the specified or name of the if it is not an or .
- ///
- /// to get the generic name of.
- /// Determines whether to use type arguments instead of type parameters.
- public static string GetGenericName(this ISymbol symbol, bool substituted = false)
- {
- CodeBuilder builder = new(false);
- builder.Name(symbol, substituted ? SymbolName.Substituted : SymbolName.Generic);
- return builder.ToString();
- }
-
- ///
- /// Returns a containing generic identifier of the specified .
- ///
- /// to get the generic name of.
- /// Determines whether to use type arguments instead of type parameters.
- public static string GetGenericName(this IMethodSymbol method, bool substituted = false)
- {
- CodeBuilder builder = new(false);
- builder.Name(method, substituted ? SymbolName.Substituted : SymbolName.Generic);
- return builder.ToString();
- }
-
- ///
- /// Returns a containing generic identifier of the specified .
- ///
- /// to get the generic name of.
- /// Determines whether to use type arguments instead of type parameters.
- public static string GetGenericName(this INamedTypeSymbol type, bool substituted = false)
- {
- CodeBuilder builder = new(false);
- builder.Name(type, substituted ? SymbolName.Substituted : SymbolName.Generic);
- return builder.ToString();
- }
-
- ///
- /// Returns a containing the generic part of an identifier created from the collection of .
- ///
- /// Type parameters.
- /// Determines whether to include variance of the .
- /// Pointers can't be used as generic arguments.
- public static string GetGenericName(this IEnumerable typeParameters, bool includeVariance = false)
- {
- return typeParameters.GetGenericName(null, includeVariance);
- }
-
- ///
- /// Returns a containing generic identifier combined of the specified and the collection of .
- ///
- /// Type parameters.
- /// Actual member identifier.
- /// Determines whether to include variance of the .
- public static string GetGenericName(this IEnumerable typeParameters, string? name, bool includeVariance = false)
- {
- if (includeVariance)
- {
- return AnalysisUtilities.GetGenericName(typeParameters.Select(p =>
- {
- if (p.Variance == VarianceKind.Out || p.Variance == VarianceKind.In)
- {
- return $"{p.Variance.ToString().ToLower()} {p.GetVerbatimName()}";
- }
-
- return p.GetVerbatimName();
- }),
- name);
- }
-
- return AnalysisUtilities.GetGenericName(typeParameters.Select(p => p.GetVerbatimName()), name);
- }
-
- ///
- /// Returns a containing the generic part of an identifier created from the collection of .
- ///
- /// Type arguments.
- public static string GetGenericName(this IEnumerable typeArguments)
- {
- CodeBuilder builder = new(false);
- builder.TypeArgumentList(typeArguments);
- return builder.ToString();
- }
-
- ///
- /// Returns a containing generic identifier combined of the specified and the collection of .
- ///
- /// Type arguments.
- /// Actual member identifier.
- public static string GetGenericName(this IEnumerable typeArguments, string? name)
- {
- CodeBuilder builder = new(false);
-
- if (!string.IsNullOrWhiteSpace(name))
- {
- builder.Write(name!);
- }
-
- builder.TypeArgumentList(typeArguments);
- return builder.ToString();
- }
-
- ///
- /// Returns the hidden by the specified using the keyword.
- ///
- /// to get the symbol hidden by.
- public static ISymbol? GetHiddenSymbol(this ISymbol symbol)
- {
- return symbol switch
- {
- INamedTypeSymbol type => type.GetHiddenSymbol(),
- IMethodSymbol method => method.GetHiddenSymbol(),
- IPropertySymbol property => property.GetHiddenSymbol(),
- IFieldSymbol field => field.GetHiddenSymbol(),
- IEventSymbol @event => @event.GetHiddenSymbol(),
- _ => default
- };
- }
-
- ///
- /// Returns the hidden by the specified using the keyword.
- ///
- /// to get the symbol hidden by.
- public static ISymbol? GetHiddenSymbol(this IMethodSymbol method)
- {
- if (method.MethodKind != MethodKind.Ordinary || method.ContainingType is null)
- {
- return default;
- }
-
- if (method.Arity == 0)
- {
- return method.ContainingType
- .GetAllMembers(method.Name)
- .FirstOrDefault(member => member switch
- {
- INamedTypeSymbol type => type.Arity == 0,
- IMethodSymbol other => method.CanHideSymbol(other),
- IPropertySymbol property => !property.IsIndexer,
- IFieldSymbol or IFieldSymbol => true,
- _ => false
- });
- }
-
- return method.ContainingType
- .GetAllMembers(method.Name)
- .FirstOrDefault(member => member switch
- {
- INamedTypeSymbol type => type.Arity == method.Arity,
- IMethodSymbol other => method.CanHideSymbol(other),
- _ => false
- });
- }
-
- ///
- /// Returns the hidden by the specified using the keyword.
- ///
- /// to get the symbol hidden by.
- public static ISymbol? GetHiddenSymbol(this INamedTypeSymbol type)
- {
- if (type.ContainingType is null || !type.IsDeclarationKind())
- {
- return default;
- }
-
- if (type.Arity == 0)
- {
- return GetHiddenSymbol_Internal(type);
- }
-
- return type.ContainingType
- .GetAllMembers(type.GetVerbatimName())
- .FirstOrDefault(member => member switch
- {
- INamedTypeSymbol other => other.Arity == type.Arity,
- IMethodSymbol method => method.Arity == type.Arity,
- _ => false
- });
- }
-
- ///
- /// Returns the hidden by the specified using the keyword.
- ///
- /// to get the symbol hidden by.
- public static ISymbol? GetHiddenSymbol(this IPropertySymbol property)
- {
- if (property.ContainingType is null)
- {
- return default;
- }
-
- if (property.IsIndexer)
- {
- return property.ContainingType
- .GetAllMembers()
- .OfType()
- .FirstOrDefault(p => p.IsIndexer && SymbolFacts.ParametersAreEquivalent(property.Parameters, p.Parameters));
- }
-
- return GetHiddenSymbol_Internal(property);
- }
-
- ///
- /// Returns the hidden by the specified using the keyword.
- ///
- /// to get the symbol hidden by.
- public static ISymbol? GetHiddenSymbol(this IFieldSymbol field)
- {
- if (field.ContainingType is null)
- {
- return default;
- }
-
- return GetHiddenSymbol_Internal(field);
- }
-
- ///
- /// Returns the hidden by the specified using the keyword.
- ///
- /// to get the symbol hidden by.
- public static ISymbol? GetHiddenSymbol(this IEventSymbol @event)
- {
- if (@event.ContainingType is null)
- {
- return default;
- }
-
- return @event.ContainingType
- .GetAllMembers(@event.GetVerbatimName())
- .FirstOrDefault(member => member switch
- {
- INamedTypeSymbol type => type.Arity == 0,
- IMethodSymbol method => method.Arity == 0,
- IPropertySymbol property => !property.IsIndexer,
- IFieldSymbol or IEventSymbol => true,
- _ => false
- });
- }
-
- ///
- /// Returns a collection of all s implicitly implemented by the specified .
- ///
- /// to get the implicitly implemented s of.
- public static IEnumerable GetImplicitImplementations(this ISymbol symbol)
- {
- return symbol switch
- {
- IMethodSymbol method => method.GetImplicitImplementations(),
- IPropertySymbol property => property.GetImplicitImplementations(),
- IEventSymbol @event => @event.GetImplicitImplementations(),
- INamedTypeSymbol type => type.GetImplicitImplementations(),
- _ => Array.Empty()
- };
- }
-
- ///
- /// Returns a collection of all s implicitly implemented by the specified .
- ///
- /// to get the implicitly implemented s by.
- public static IEnumerable GetImplicitImplementations(this IPropertySymbol property)
- {
- if (property.IsImplementedExplicitly())
- {
- return Array.Empty();
- }
-
- return GetImplicitImplementations_Internal(property);
- }
-
- ///
- /// Returns a collection of all s implicitly implemented by the specified .
- ///
- /// to get the implicitly implemented s by.
- public static IEnumerable GetImplicitImplementations(this IMethodSymbol method)
- {
- if (method.IsImplementedExplicitly())
- {
- return Array.Empty();
- }
-
- return GetImplicitImplementations_Internal(method);
- }
-
- ///
- /// Returns a collection of all s implicitly implemented by the specified .
- ///
- /// to get the implicitly implemented s by.
- public static IEnumerable GetImplicitImplementations(this IEventSymbol @event)
- {
- if (@event.IsImplementedExplicitly())
- {
- return Array.Empty();
- }
-
- return GetImplicitImplementations_Internal(@event);
- }
-
- ///
- /// Returns a collection of all s implicitly implemented by the specified .
- ///
- /// to get the implicitly implemented s by.
- public static IEnumerable GetImplicitImplementations(this INamedTypeSymbol type)
- {
- return type.AllInterfaces
- .SelectMany(m => m.GetMembers())
- .Where(m => type.FindImplementationForInterfaceMember(m) is not null);
- }
-
- ///
- /// Returns a collection of all s of the given implicitly implemented by the specified .
- ///
- /// to get the implicitly implemented s by.
- /// to get the implicitly implemented s of.
- public static IEnumerable GetImplicitImplementations(this INamedTypeSymbol type, INamedTypeSymbol @interface)
- {
- return @interface.GetMembers()
- .Where(m => type.FindImplementationForInterfaceMember(m) is not null);
- }
-
- ///
- /// Creates an <inheritdoc/> tag from the specified .
- ///
- /// to get the <inheritdoc/> tag from.
- /// Determines whether to return the <inheritdoc/> event if it cannot be referenced by other symbols.
- /// A containing the created <inheritdoc/> tag -or- if has no documentation comment.
- public static string? GetInheritdocIfHasDocumentation(this ISymbol symbol, bool forceUnsupported = false)
- {
- if (forceUnsupported)
- {
- if (!symbol.HasDocumentation())
- {
- return default;
- }
- }
- else if (!symbol.HasInheritableDocumentation())
- {
- return default;
- }
-
- CodeBuilder builder = new(false);
-
- foreach (INamedTypeSymbol type in symbol.GetContainingTypes())
- {
- builder.XmlName(type);
- builder.Write('.');
- }
-
- builder.XmlName(symbol);
-
- return AutoGenerated.GetInheritdoc(builder.ToString());
- }
-
- ///
- /// Returns a collection of all local functions of the specified .
- ///
- /// to get the local functions of.
- /// Determines whether to include the itself.
- /// Determines whether to include nested local functions.
- /// Specifies ordering of the returned members.
- public static IEnumerable GetLocalFunctions(this IMethodSymbol method, bool includeSelf = false, bool includeNested = false, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- IEnumerable collection;
-
- if (includeNested)
- {
- collection = GetFuncs(method);
- }
- else
- {
- collection = GetNested();
- }
-
- if (includeSelf)
- {
- collection = new[] { method }.Concat(collection);
- }
-
- return GetNested().OrderBy(order, ReturnOrder.ChildToParent);
-
- IEnumerable GetFuncs(IMethodSymbol method)
- {
- return method.ContainingType
- .GetMembers()
- .OfType()
- .Where(m => m.MethodKind == MethodKind.LocalFunction && SymbolEqualityComparer.Default.Equals(method, m.ContainingSymbol));
- }
-
- IEnumerable GetNested()
- {
- const int CAPACITY = 8;
-
- ImmutableArray array = GetFuncs(method).ToImmutableArray();
-
- if (array.Length == 0)
- {
- yield break;
- }
-
- Stack subs = new(array.Length > CAPACITY ? array.Length : CAPACITY);
-
- PushReverse(ref array, subs);
-
- while (subs.Count > 0)
- {
- IMethodSymbol local = subs.Pop();
- yield return local;
-
- array = GetFuncs(local).ToImmutableArray();
-
- if (array.Length == 0)
- {
- continue;
- }
-
- PushReverse(ref array, subs);
- }
- }
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this ISymbol symbol)
- {
- return symbol switch
- {
- INamedTypeSymbol type => type.GetModifiers(),
- IMethodSymbol method => method.GetModifiers(),
- IPropertySymbol property => property.GetModifiers(),
- IFieldSymbol field => field.GetModifiers(),
- IEventSymbol @event => @event.GetModifiers(),
- _ => Array.Empty()
- };
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this IFieldSymbol field)
- {
- List modifiers = new(4);
-
- AddAccessibilityModifiers(modifiers, field.DeclaredAccessibility);
-
- if (field.IsConst)
- {
- modifiers.Add("const");
- }
- else if (field.IsStatic)
- {
- modifiers.Add("static");
- }
-
- if (field.IsReadOnly)
- {
- modifiers.Add("readonly");
- }
-
- if (field.IsUnsafe())
- {
- modifiers.Add("unsafe");
- }
-
- if (field.IsVolatile)
- {
- modifiers.Add("volatile");
- }
-
- if (field.IsFixedSizeBuffer)
- {
- modifiers.Add("fixed");
- }
-
- return modifiers.ToArray();
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this ILocalSymbol local)
- {
- List modifiers = new(2);
-
- if (local.IsConst)
- {
- modifiers.Add("const");
- }
-
- switch (local.RefKind)
- {
- case RefKind.Ref:
- modifiers.Add("ref");
- break;
-
- case RefKind.RefReadOnly:
- modifiers.Add("ref");
- modifiers.Add("readonly");
- break;
- }
-
- return modifiers.ToArray();
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this IParameterSymbol parameter)
- {
- List modifiers = new(2);
-
- if (parameter.IsThis)
- {
- modifiers.Add("this");
- }
-
- if (parameter.RefKind.GetText() is string refKind)
- {
- modifiers.Add(refKind);
- }
-
- if (parameter.IsParams)
- {
- modifiers.Add("params");
- }
-
- return modifiers.ToArray();
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this IPropertySymbol property)
- {
- List modifiers = new(8);
-
- AddAccessibilityModifiers(modifiers, property.DeclaredAccessibility);
- AddBasicMethodModifiers(modifiers, property);
-
- if (property.IsReadOnly)
- {
- CheckAccessor(property.GetMethod);
- }
- else if (property.IsWriteOnly)
- {
- CheckAccessor(property.SetMethod);
- }
- else if (property.IsReadOnlyContext())
- {
- modifiers.Add("readonly");
- }
-
- if (property.IsUnsafe())
- {
- modifiers.Add("unsafe");
- }
-
- return modifiers.ToArray();
-
- void CheckAccessor(IMethodSymbol? accessor)
- {
- if (accessor is not null && accessor.IsReadOnly)
- {
- modifiers.Add("readonly");
- }
- }
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this IEventSymbol @event)
- {
- List modifiers = new(8);
-
- AddAccessibilityModifiers(modifiers, @event.DeclaredAccessibility);
- AddBasicMethodModifiers(modifiers, @event);
-
- if (@event.IsReadOnlyContext())
- {
- modifiers.Add("readonly");
- }
-
- if (@event.IsUnsafe())
- {
- modifiers.Add("unsafe");
- }
-
- return modifiers.ToArray();
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this IMethodSymbol method)
- {
- List modifiers = new(8);
-
- AddAccessibilityModifiers(modifiers, method.DeclaredAccessibility);
- AddBasicMethodModifiers(modifiers, method);
-
- if (method.IsReadOnly)
- {
- modifiers.Add("readonly");
- }
-
- if (method.IsUnsafe())
- {
- modifiers.Add("unsafe");
- }
-
- if (method.IsAsync)
- {
- modifiers.Add("async");
- }
-
- if (method.IsPartial(true))
- {
- modifiers.Add("partial");
- }
-
- return modifiers.ToArray();
- }
-
- ///
- /// Returns modifiers applied to the target .
- ///
- /// to get the modifiers of.
- public static string[] GetModifiers(this INamedTypeSymbol type)
- {
- List modifiers = new(8);
-
- AddAccessibilityModifiers(modifiers, type.DeclaredAccessibility);
-
- if (type.IsStatic)
- {
- modifiers.Add("static");
- }
-
- if (type.IsNew())
- {
- modifiers.Add("new");
- }
-
- if (type.IsAbstract)
- {
- modifiers.Add("abstract");
- }
- else if (type.IsRefLikeType)
- {
- modifiers.Add("ref");
- }
- else if (type.IsSealed)
- {
- modifiers.Add("sealed");
- }
-
- if (type.IsReadOnly)
- {
- modifiers.Add("readonly");
- }
-
- if (type.IsUnsafe())
- {
- modifiers.Add("unsafe");
- }
-
- if (type.IsPartial())
- {
- modifiers.Add("partial");
- }
-
- return modifiers.ToArray();
- }
-
- ///
- /// Returns the defined on the specified that is of the given .
- ///
- /// to get the of.
- /// to check for.
- public static AttributeData? GetNullableAnnotationAttribute(this ISymbol symbol, NullableAnnotationAttribute attributeKind)
- {
- string? name = attributeKind.GetAttributeName();
-
- if (name is null)
- {
- return default;
- }
-
- string? @namespace = attributeKind.GetNamespaceName();
-
- if (@namespace is null)
- {
- return default;
- }
-
- return symbol.GetAttributes().FirstOrDefault(attr =>
- attr.AttributeClass is not null &&
- attr.AttributeClass.Name == name &&
- attr.AttributeClass.IsWithinNamespace(@namespace, @namespace != "System")
- );
- }
-
- ///
- /// Returns the kind of this represents.
- ///
- /// to get the kind of.
- public static NullableAnnotationAttribute GetNullableAnnotationAttributeKind(this INamedTypeSymbol type)
- {
- return MapToNullableAnnotationAttribute(type.Name, toReturn => type.IsWithinNamespace("System.Diagnostics.CodeAnalysis", true) ? toReturn : default);
- }
-
- ///
- /// Returns the underlaying of a nullable .
- ///
- /// to get the underlaying of.
- public static ITypeSymbol? GetNullableUnderlayingType(this ITypeSymbol type)
- {
- if (type.NullableAnnotation == NullableAnnotation.Annotated)
- {
- return type;
- }
-
- if (type is not INamedTypeSymbol named || !named.IsValueType || named.ConstructedFrom is null || named.ConstructedFrom.SpecialType != SpecialType.System_Nullable_T)
- {
- return default;
- }
-
- ImmutableArray arguments = named.TypeArguments;
-
- if (arguments.Length != 1)
- {
- return default;
- }
-
- return arguments[0];
- }
-
- ///
- /// Returns kind of operator this overloads.
- ///
- /// to get the kind of the overloaded operator.
- public static OverloadableOperator GetOperatorKind(this IMethodSymbol method)
- {
- if (method.MethodKind != MethodKind.UserDefinedOperator && method.MethodKind != MethodKind.BuiltinOperator)
- {
- return default;
- }
-
- return AnalysisUtilities.GetOperatorType(method.Name);
- }
-
- ///
- /// Returns text of operator this overloads.
- ///
- /// to get the kind of the overloaded operator.
- public static string? GetOperatorToken(this IMethodSymbol method)
- {
- if (method.MethodKind != MethodKind.UserDefinedOperator && method.MethodKind != MethodKind.BuiltinOperator)
- {
- return default;
- }
-
- return AnalysisUtilities.GetOperatorText(method.Name);
- }
-
- ///
- /// Returns collection of overloads of the specified .
- ///
- /// to get the overloads of.
- /// Determines whether to also include inherited overloads.
- /// Determines whether to also include methods with different arity than the .
- public static IEnumerable GetOverloads(this IMethodSymbol method, bool includeInherited = true, bool ignoreArity = false)
- {
- if (method.MethodKind != MethodKind.Ordinary)
- {
- return Array.Empty();
- }
-
- IEnumerable overloads = method.ContainingType
- .GetMembers(method.Name)
- .OfType();
-
- if (ignoreArity)
- {
- overloads = overloads.Where(m => method.Arity == m.Arity);
- }
-
- if (!includeInherited || !method.ContainingType.HasExplicitBaseType())
- {
- return overloads;
- }
-
- IMethodSymbol[] array = overloads.ToArray();
-
- List inheritedMethods = new(array.Length * 4);
- List overrides = new(inheritedMethods.Count);
-
- inheritedMethods.Add(method);
-
- if (method.IsOverride)
- {
- overrides.Add(method);
- }
-
- foreach (INamedTypeSymbol type in method.ContainingType.GetBaseTypes())
- {
- // These two values allow to skip methods that were added to the lists during this loop pass.
-
- int currentOverrideLength = overrides.Count;
- int currentRegistryLength = inheritedMethods.Count;
-
- foreach (IMethodSymbol inheritedMethod in type.GetMembers(method.Name).OfType())
- {
- if (!CheckVirtuality(inheritedMethod, currentOverrideLength, out bool addOverride))
- {
- continue;
- }
-
- if (!CheckNewModifier(inheritedMethod, currentRegistryLength))
- {
- continue;
- }
-
- inheritedMethods.Add(inheritedMethod);
-
- if (addOverride)
- {
- overrides.Add(inheritedMethod);
- }
- }
- }
-
- return overloads.Concat(inheritedMethods);
-
- bool CheckVirtuality(IMethodSymbol inheritedMethod, int length, out bool addOverride)
- {
- Virtuality virtuality = inheritedMethod.GetVirtuality();
-
- switch (virtuality)
- {
- case Virtuality.Sealed:
- addOverride = true;
- break;
-
- case Virtuality.Abstract:
- case Virtuality.Virtual:
-
- for (int i = 0; i < length; i++)
- {
- if (SymbolEqualityComparer.Default.Equals(overrides[i], inheritedMethod))
- {
- addOverride = false;
- return false;
- }
- }
-
- break;
- }
-
- addOverride = false;
- return true;
- }
-
- bool CheckNewModifier(IMethodSymbol inheritedMethod, int length)
- {
- for (int i = 0; i < length; i++)
- {
- IMethodSymbol registered = inheritedMethods[i];
-
- if (registered.CanHideSymbol_Internal(inheritedMethod, ignoreArity))
- {
- return false;
- }
- }
-
- return true;
- }
- }
-
- ///
- /// Returns the overridden by the specified .
- ///
- /// to get the symbol overridden by.
- public static ISymbol? GetOverriddenSymbol(this ISymbol symbol)
- {
- return symbol switch
- {
- IMethodSymbol method => method.OverriddenMethod,
- IPropertySymbol property => property.OverriddenProperty,
- IEventSymbol @event => @event.OverriddenEvent,
- _ => default
- };
- }
-
- ///
- /// Returns all s overridden by the specified .
- ///
- /// to get the methods overridden by.
- public static IEnumerable GetOverriddenSymbols(this IMethodSymbol method)
- {
- IMethodSymbol? m = method;
-
- while ((m = m!.OverriddenMethod) is not null)
- {
- yield return m;
- }
- }
-
- ///
- /// Returns all s overridden by the specified .
- ///
- /// to get the properties overridden by.
- public static IEnumerable GetOverriddenSymbols(this IPropertySymbol property)
- {
- IPropertySymbol? p = property;
-
- while ((p = p!.OverriddenProperty) is not null)
- {
- yield return p;
- }
- }
-
- ///
- /// Returns all s overridden by the specified .
- ///
- /// to get the events overridden by.
- public static IEnumerable GetOverriddenSymbols(this IEventSymbol @event)
- {
- IEventSymbol? e = @event;
-
- while ((e = e!.OverriddenEvent) is not null)
- {
- yield return e;
- }
- }
-
- ///
- /// Returns all s overridden by the specified .
- ///
- /// to get the symbols overridden by.
- public static IEnumerable GetOverriddenSymbols(this ISymbol symbol)
- {
- return symbol switch
- {
- IMethodSymbol method => method.GetOverriddenSymbols(),
- IPropertySymbol property => property.GetOverriddenSymbols(),
- IEventSymbol @event => @event.GetOverriddenSymbols(),
- _ => Array.Empty()
- };
- }
-
- ///
- /// Returns all es of the specified .
- ///
- /// to get the es of.
- /// that specifies if the operation should be canceled.
- public static IEnumerable GetPartialDeclarations(this INamedTypeSymbol type, CancellationToken cancellationToken = default) where T : TypeDeclarationSyntax
- {
- return type.DeclaringSyntaxReferences.Select(e => e.GetSyntax(cancellationToken)).OfType();
- }
-
- ///
- /// Returns a if the specified is a keyword type, otherwise.
- ///
- /// to get the for.
- public static PredefinedTypeSyntax? GetPredefineTypeSyntax(this INamedTypeSymbol type)
- {
- if (type.SpecialType == SpecialType.None)
- {
- return default;
- }
-
- SyntaxKind kind = type.SpecialType.GetSyntaxKind();
-
- if (kind == default)
- {
- return default;
- }
-
- return SyntaxFactory.PredefinedType(SyntaxFactory.Token(kind));
- }
-
- ///
- /// Returns the primary constructor of the specified .
- ///
- /// to get the primary constructor of.
- public static IMethodSymbol? GetPrimaryConstructor(this INamedTypeSymbol type)
- {
- return type.InstanceConstructors.FirstOrDefault(ctor => ctor.IsPrimaryConstructor());
- }
-
- ///
- /// Returns a created from the specified .
- ///
- /// A collection of s to create the from.
- /// A created by combining the . -or- if there were less then 2 provided.
- public static QualifiedNameSyntax? GetQualifiedName(this IEnumerable namespaces)
- {
- return AnalysisUtilities.GetQualifiedName(namespaces.Select(n => n.GetVerbatimName()));
- }
-
- ///
- /// Returns all struct members with the modifier applied.
- ///
- /// to get all members with the modifier applied.
- /// If the is not a , empty collection is returned.
- public static IEnumerable GetReadOnlyMembers(this INamedTypeSymbol type)
- {
- if (type.TypeKind != TypeKind.Struct)
- {
- return Array.Empty();
- }
-
- return type
- .GetMembers()
- .Where(m => m.IsStructReadOnly());
- }
-
- ///
- /// Returns root namespace of the (excluding the global namespace).
- ///
- /// to get the root namespaces of.
- /// The root -or- if root was not found.
- public static INamespaceSymbol? GetRootNamespace(this ISymbol symbol)
- {
- return GetContainingNamespaces(symbol).FirstOrDefault();
- }
-
- ///
- /// Returns the defined on the specified that is of the given .
- ///
- /// to get the of.
- /// to check for.
- public static AttributeData? GetSpecialAttribute(this ISymbol symbol, SpecialAttribute attributeKind)
- {
- string? name = attributeKind.GetAttributeName();
-
- if (name is null)
- {
- return default;
- }
-
- string? @namespace = attributeKind.GetNamespaceName();
-
- if (@namespace is null)
- {
- return default;
- }
-
- return symbol.GetAttributes().FirstOrDefault(attr =>
- attr.AttributeClass is not null &&
- attr.AttributeClass.Name == name &&
- attr.AttributeClass.IsWithinNamespace(@namespace, @namespace != "System")
- );
- }
-
- ///
- /// Returns the kind of this represents.
- ///
- /// to get the kind of.
- public static SpecialAttribute GetSpecialAttributeKind(this INamedTypeSymbol type)
- {
- if (!type.Name.EndsWith("Attribute"))
- {
- return default;
- }
-
- return MapToSpecialAttribute(type.Name, (@namespace, toReturn) => type.IsWithinNamespace(@namespace, @namespace.Length > 6) ? toReturn : default);
- }
-
- ///
- /// Returns an representing the given kind of special constructor available from the specified .
- ///
- /// to get the special member from.
- /// Kind of special constructor to return.
- public static IMethodSymbol? GetSpecialConstructor(this INamedTypeSymbol type, SpecialConstructor kind)
- {
- return kind switch
- {
- SpecialConstructor.Static => type.StaticConstructors.FirstOrDefault(),
- SpecialConstructor.None => default,
- SpecialConstructor.Parameterless => type.InstanceConstructors.FirstOrDefault(ctor => ctor.GetConstructorKind() is SpecialConstructor.Parameterless or SpecialConstructor.Default),
- _ => type.InstanceConstructors.FirstOrDefault(ctor => ctor.GetConstructorKind() == kind),
- };
- }
-
- ///
- /// Returns an representing the given kind of available from the specified .
- ///
- /// to get the special member from.
- /// Kind of special member to return.
- public static ISymbol? GetSpecialMember(this INamedTypeSymbol type, SpecialMember specialMember)
- {
- return type.GetAllMembers().FirstOrDefault(member => member.IsSpecialMember(specialMember));
- }
-
- ///
- /// Returns all sub-namespaces of the specified .
- ///
- /// to get the sub-namespaces of.
- /// Determines whether to include the global namespace in the returned collection.
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetSubNamespaces(this IAssemblySymbol assembly, bool includeGlobal = false, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return assembly.GlobalNamespace.GetSubNamespaces(includeGlobal, order);
- }
-
- ///
- /// Returns all sub-namespaces of the specified .
- ///
- /// to get the sub-namespaces of.
- /// Determines whether to also include the itself in the collection.
- /// Specifies ordering of the returned members.
- public static IReturnOrderEnumerable GetSubNamespaces(this INamespaceSymbol @namespace, bool includeSelf = false, ReturnOrder order = ReturnOrder.ParentToChild)
- {
- return Yield().OrderBy(order, ReturnOrder.ParentToChild);
-
- IEnumerable Yield()
- {
- const int CAPACITY = 32;
-
- if (includeSelf)
- {
- yield return @namespace;
- }
-
- ImmutableArray array = @namespace.GetNamespaceMembers().ToImmutableArray();
-
- if (array.Length == 0)
- {
- yield break;
- }
-
- Stack subs = new(array.Length > CAPACITY ? array.Length : CAPACITY);
-
- PushReverse(ref array, subs);
-
- while (subs.Count > 0)
- {
- INamespaceSymbol t = subs.Pop();
- yield return t;
-
- array = t.GetNamespaceMembers().ToImmutableArray();
-
- if (array.Length == 0)
- {
- continue;
- }
-
- PushReverse(ref array, subs);
- }
- }
- }
-
- ///
- /// Returns a of type associated with the specified .
- ///
- /// Type of to return.
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a syntax node of type .
- public static T GetSyntax(this ISymbol symbol, CancellationToken cancellationToken = default) where T : SyntaxNode
- {
- if (!symbol.TryGetSyntax(out T? declaration, cancellationToken))
- {
- throw Exc_SymbolNotAssociatedWithNode(symbol, typeof(T));
- }
-
- return declaration;
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static BaseMethodDeclarationSyntax GetSyntax(this IMethodSymbol method, CancellationToken cancellationToken = default)
- {
- return method.GetSyntax(cancellationToken);
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static BaseTypeDeclarationSyntax GetSyntax(this INamedTypeSymbol type, CancellationToken cancellationToken = default)
- {
- return type.GetSyntax(cancellationToken);
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static ParameterSyntax GetSyntax(this IParameterSymbol parameter, CancellationToken cancellationToken = default)
- {
- return parameter.GetSyntax(cancellationToken);
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static TypeParameterSyntax GetSyntax(this ITypeParameterSymbol parameter, CancellationToken cancellationToken = default)
- {
- return parameter.GetSyntax(cancellationToken);
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static EventFieldDeclarationSyntax GetSyntax(this IEventSymbol @event, CancellationToken cancellationToken = default)
- {
- if (!@event.TryGetSyntax(out VariableDeclaratorSyntax? syntax, cancellationToken) || syntax.Parent?.Parent is not EventFieldDeclarationSyntax decl)
- {
- throw Exc_SymbolNotAssociatedWithNode(@event, typeof(EventFieldDeclarationSyntax));
- }
-
- return decl;
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static FieldDeclarationSyntax GetSyntax(this IFieldSymbol field, CancellationToken cancellationToken = default)
- {
- if (!field.TryGetSyntax(out VariableDeclaratorSyntax? syntax, cancellationToken) || syntax.Parent?.Parent is not FieldDeclarationSyntax decl)
- {
- throw Exc_SymbolNotAssociatedWithNode(field, typeof(FieldDeclarationSyntax));
- }
-
- return decl;
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static LocalDeclarationStatementSyntax GetSyntax(this ILocalSymbol local, CancellationToken cancellationToken = default)
- {
- if (!local.TryGetSyntax(out VariableDeclaratorSyntax? syntax, cancellationToken) || syntax.Parent?.Parent is not LocalDeclarationStatementSyntax decl)
- {
- throw Exc_SymbolNotAssociatedWithNode(local, typeof(LocalDeclarationStatementSyntax));
- }
-
- return decl;
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static BasePropertyDeclarationSyntax GetSyntax(this IPropertySymbol property, CancellationToken cancellationToken = default)
- {
- return property.GetSyntax(cancellationToken);
- }
-
- ///
- /// Returns a associated with the specified .
- ///
- /// to get the associated with.
- /// that specifies if the operation should be canceled.
- /// is not associated with a .
- public static LabeledStatementSyntax GetSyntax(this ILabelSymbol label, CancellationToken cancellationToken = default)
- {
- return label.GetSyntax(cancellationToken);
- }
-
- ///
- /// Returns a representation of a C# keyword associated with the specified .
- ///
- /// to get the keyword associated with.
- public static string? GetTypeKeyword(this ITypeSymbol type)
- {
- if (type is IDynamicTypeSymbol)
- {
- return "dynamic";
- }
-
- return type.SpecialType.GetKeywordText();
- }
-
- ///
- /// Returns a representing a C# keyword associated with the specified .
- ///
- /// to get the keyword associated with.
- public static TypeKeyword GetTypeKeywordKind(this ITypeSymbol type)
- {
- if (type is IDynamicTypeSymbol)
- {
- return TypeKeyword.Dynamic;
- }
-
- return type.SpecialType.GetKeyword();
- }
-
- ///
- /// Returns a new build for the specified symbol.
- ///
- /// to built the from.
- public static UsingDirectiveSyntax GetUsingDirective(this INamespaceSymbol @namespace)
- {
- NameSyntax name;
-
- if (@namespace.GetContainingNamespaces().GetQualifiedName() is QualifiedNameSyntax q)
- {
- name = q;
- }
- else
- {
- name = SyntaxFactory.IdentifierName(@namespace.GetVerbatimName());
- }
-
- return SyntaxFactory.UsingDirective(name);
- }
-
- ///
- /// Returns a new build for the specified symbol.
- ///
- /// A collection of s to build the from.
- /// cannot be empty.
- public static UsingDirectiveSyntax GetUsingDirective(this IEnumerable namespaces)
- {
- NameSyntax name;
-
- if (namespaces.GetQualifiedName() is QualifiedNameSyntax q)
- {
- name = q;
- }
- else if (namespaces.FirstOrDefault() is INamespaceSymbol first)
- {
- name = SyntaxFactory.IdentifierName(first.GetVerbatimName());
- }
- else
- {
- throw new ArgumentException($"'{nameof(namespaces)}' cannot be empty");
- }
-
- return SyntaxFactory.UsingDirective(name);
- }
-
- ///
- /// Returns name of the with a verbatim identifier '@' token applied if necessary.
- ///
- /// to get the effective name of.
- public static string GetVerbatimName(this ISymbol symbol)
- {
- string value = symbol.Name;
- AnalysisUtilities.ApplyVerbatimIfNecessary(ref value);
- return value;
- }
-
- ///
- /// Returns the of the specified .
- ///
- /// to get the virtuality of.
- public static Virtuality GetVirtuality(this ISymbol symbol)
- {
- if (symbol.IsAbstract)
- {
- return Virtuality.Abstract;
- }
-
- if (symbol.IsOverride)
- {
- if (symbol.IsSealed)
- {
- return Virtuality.Sealed;
- }
-
- return Virtuality.Virtual;
- }
-
- if (symbol.IsVirtual)
- {
- return Virtuality.Virtual;
- }
-
- return default;
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// Invalid type kind.
- /// is . -or- is .
- public static IMemberData ToData(this ITypeSymbol type, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- switch (type)
- {
- case INamedTypeSymbol named:
- return named.ToData(compilation, properties);
-
- case ITypeParameterSymbol typeParameter:
- return typeParameter.ToData(compilation, properties);
-
- default:
-
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- throw new ArgumentException($"Invalid type kind: '{type.TypeKind}'", nameof(type));
- }
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// Invalid type kind.
- /// is . -or- is .
- public static ITypeData ToData(this INamedTypeSymbol type, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- if (type.IsRecord)
- {
- return new RecordData(type, compilation, properties);
- }
-
- return type.TypeKind switch
- {
- TypeKind.Class => new ClassData(type, compilation, properties),
- TypeKind.Struct => new StructData(type, compilation, properties),
- TypeKind.Interface => new InterfaceData(type, compilation, properties),
- TypeKind.Delegate => new DelegateData(type, compilation, properties),
- TypeKind.Enum => new EnumData(type, compilation, properties),
- _ => throw new ArgumentException($"Unknown type kind: '{type.TypeKind}'", nameof(type))
- };
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// Invalid method kind.
- /// is . -or- is .
- public static IMethodData ToData(this IMethodSymbol method, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (method is null)
- {
- throw new ArgumentNullException(nameof(method));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return method.MethodKind switch
- {
- MethodKind.Ordinary => new MethodData(method, compilation, properties),
- MethodKind.UserDefinedOperator => new OperatorData(method, compilation, properties),
- MethodKind.Constructor or MethodKind.StaticConstructor => new ConstructorData(method, compilation, properties),
- MethodKind.Destructor => new DestructorData(method, compilation, properties),
- MethodKind.LocalFunction => new LocalFunctionData(method, compilation, properties),
- MethodKind.Conversion => new ConversionOperatorData(method, compilation, properties),
- MethodKind.AnonymousFunction => new LambdaData(method, compilation, properties),
- _ => method.IsAccessor()
- ? new AccessorData(method, compilation, properties)
- : throw new ArgumentException($"Unknown method kind: '{method.MethodKind}'", nameof(method))
- };
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// is . -or- is .
- public static IFieldData ToData(this IFieldSymbol field, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (field is null)
- {
- throw new ArgumentNullException(nameof(field));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return new FieldData(field, compilation, properties);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// is . -or- is .
- public static IEventData ToData(this IEventSymbol @event, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (@event is null)
- {
- throw new ArgumentNullException(nameof(@event));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return new EventData(@event, compilation, properties);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// is . -or- is .
- public static IPropertyData ToData(this IPropertySymbol property, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (property is null)
- {
- throw new ArgumentNullException(nameof(property));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- if (property.IsIndexer)
- {
- return new IndexerData(property, compilation);
- }
-
- return new PropertyData(property, compilation, properties);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// is . -or- is .
- public static ILocalData ToData(this ILocalSymbol local, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (local is null)
- {
- throw new ArgumentNullException(nameof(local));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return new LocalData(local, compilation, properties);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// is . -or- is .
- public static ITypeParameterData ToData(this ITypeParameterSymbol typeParameter, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (typeParameter is null)
- {
- throw new ArgumentNullException(nameof(typeParameter));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return new TypeParameterData(typeParameter, compilation, properties);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// is . -or- is .
- public static IParameterData ToData(this IParameterSymbol parameter, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (parameter is null)
- {
- throw new ArgumentNullException(nameof(parameter));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return new ParameterData(parameter, compilation, properties);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// Invalid type kind.
- /// is . -or- is .
- public static INamespaceOrTypeData ToData(this INamespaceOrTypeSymbol symbol, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- switch (symbol)
- {
- case INamespaceSymbol @namespace:
- return @namespace.ToData(compilation, properties);
-
- case INamedTypeSymbol type:
- return type.ToData(compilation, properties);
-
- default:
-
- if (symbol is null)
- {
- throw new ArgumentNullException(nameof(symbol));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- if (symbol is not ITypeParameterSymbol)
- {
- throw new ArgumentException("Invalid type kind", nameof(symbol));
- }
-
- return new NamespaceOrTypeData(symbol, compilation, properties);
- }
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// Invalid type kind.
- /// is . -or- is .
- public static IMemberData ToData(this ISymbol symbol, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return symbol switch
- {
- ITypeParameterSymbol typeParameter => typeParameter.ToData(compilation, properties),
- INamedTypeSymbol type => type.ToData(compilation, properties),
- IMethodSymbol method => method.ToData(compilation, properties),
- IPropertySymbol property => property.ToData(compilation, properties),
- IFieldSymbol field => field.ToData(compilation, properties),
- IEventSymbol @event => @event.ToData(compilation, properties),
- IParameterSymbol parameter => parameter.ToData(compilation, properties),
- INamespaceSymbol @namespace => @namespace.ToData(compilation, properties),
- ILocalSymbol local => local.ToData(compilation, properties),
- ITypeSymbol unknownType => throw new ArgumentException($"Invalid type kind: '{unknownType.TypeKind}'", nameof(symbol)),
- INamespaceOrTypeSymbol namespaceOrType => namespaceOrType.ToData(compilation, properties),
- null => throw new ArgumentNullException(nameof(symbol)),
- _ => new MemberData(symbol, compilation, properties)
- };
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// to use for the current instance.
- /// is . -or- is .
- public static INamespaceData ToData(this INamespaceSymbol @namespace, ICompilationData compilation, MemberData.Properties? properties = default)
- {
- if (@namespace is null)
- {
- throw new ArgumentNullException(nameof(@namespace));
- }
-
- if (compilation is null)
- {
- throw new ArgumentNullException(nameof(compilation));
- }
-
- return new NamespaceData(@namespace, compilation, properties);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// Invalid type kind.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this ISymbol symbol, ICompilationData? compilation = default)
- {
- return symbol switch
- {
- ITypeParameterSymbol typeParameter => typeParameter.ToDataOrSymbol(compilation),
- INamedTypeSymbol type => type.ToDataOrSymbol(compilation),
- IMethodSymbol method => method.ToDataOrSymbol(compilation),
- IPropertySymbol property => property.ToDataOrSymbol(compilation),
- IFieldSymbol field => field.ToDataOrSymbol(compilation),
- IEventSymbol @event => @event.ToDataOrSymbol(compilation),
- IParameterSymbol parameter => parameter.ToDataOrSymbol(compilation),
- INamespaceSymbol @namespace => @namespace.ToDataOrSymbol(compilation),
- ILocalSymbol local => local.ToDataOrSymbol(compilation),
- ITypeSymbol unknownType => throw new ArgumentException($"Invalid type kind: '{unknownType.TypeKind}'", nameof(symbol)),
- INamespaceOrTypeSymbol namespaceOrType => namespaceOrType.ToDataOrSymbol(compilation),
- null => throw new ArgumentNullException(nameof(symbol)),
- _ => new SymbolOrMemberWrapper(symbol, compilation)
- };
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this ITypeSymbol type, ICompilationData? compilation = default)
- {
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- return new SymbolOrMemberWrapper(type, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// Type of returned data.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this ITypeSymbol type, ICompilationData? compilation = default) where TData : class, IMemberData
- {
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- return new SymbolOrMemberWrapper(type, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this INamespaceSymbol @namespace, ICompilationData? compilation = default)
- {
- if (@namespace is null)
- {
- throw new ArgumentNullException(nameof(@namespace));
- }
-
- return new SymbolOrMemberWrapper(@namespace, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// Type of returned data.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this INamespaceSymbol @namespace, ICompilationData? compilation = default) where TData : class, INamespaceData
- {
- if (@namespace is null)
- {
- throw new ArgumentNullException(nameof(@namespace));
- }
-
- return new SymbolOrMemberWrapper(@namespace, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this INamedTypeSymbol type, ICompilationData? compilation = default)
- {
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- return new SymbolOrMemberWrapper(type, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// Type of returned data.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this INamedTypeSymbol type, ICompilationData? compilation = default) where TData : class, ITypeData
- {
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- return new SymbolOrMemberWrapper(type, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this INamespaceOrTypeSymbol symbol, ICompilationData? compilation = default)
- {
- if (symbol is null)
- {
- throw new ArgumentNullException(nameof(symbol));
- }
-
- return new SymbolOrMemberWrapper(symbol, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// Type of returned data.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this INamespaceOrTypeSymbol symbol, ICompilationData? compilation = default) where TData : class, INamespaceOrTypeData
- {
- if (symbol is null)
- {
- throw new ArgumentNullException(nameof(symbol));
- }
-
- return new SymbolOrMemberWrapper(symbol, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this IParameterSymbol parameter, ICompilationData? compilation = default)
- {
- if (parameter is null)
- {
- throw new ArgumentNullException(nameof(parameter));
- }
-
- return new SymbolOrMemberWrapper(parameter, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// Type of returned data.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this IParameterSymbol parameter, ICompilationData? compilation = default) where TData : class, IParameterData
- {
- if (parameter is null)
- {
- throw new ArgumentNullException(nameof(parameter));
- }
-
- return new SymbolOrMemberWrapper(parameter, compilation);
- }
-
- ///
- /// Returns new created for the specified .
- ///
- /// to create the for.
- /// to create the from.
- /// is .
- public static ISymbolOrMember ToDataOrSymbol(this IMethodSymbol method, ICompilationData? compilation = default)
- {
- if (method is null)
- {
- throw new ArgumentNullException(nameof(method));
- }
-
- return new SymbolOrMemberWrapper(method, compilation);
- }
-
- ///