From b11b378022c36d1d808cfcc373a3d03c4eb11c0c Mon Sep 17 00:00:00 2001 From: Anton Andryushchenko Date: Mon, 19 Aug 2024 11:44:14 +0300 Subject: [PATCH] [UPD] Build targets [UPD] JetBrains.Annotations --- Directory.Build.props | 4 +- Directory.Packages.props | 4 +- src/Shared/JetBrains.Annotations.cs | 501 +++++++++++++++++++--------- 3 files changed, 345 insertions(+), 164 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 2b6a63a..1c651e9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,9 +1,9 @@  - + - netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0 + netstandard2.0;netstandard2.1;net6.0;net8.0 AInq.Optional Anton Andryushchenko https://github.com/andryushchenko/AInq.Optional diff --git a/Directory.Packages.props b/Directory.Packages.props index 67c646c..398087d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,11 +11,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Shared/JetBrains.Annotations.cs b/src/Shared/JetBrains.Annotations.cs index 2d8cafa..7a9d09a 100644 --- a/src/Shared/JetBrains.Annotations.cs +++ b/src/Shared/JetBrains.Annotations.cs @@ -68,9 +68,9 @@ internal sealed class CanBeNullAttribute : Attribute { } internal sealed class NotNullAttribute : Attribute { } /// - /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task - /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property - /// or of the Lazy.Value property can never be null. + /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task + /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property, + /// or of the Lazy.Value property can never be null. /// /// /// public void Foo([ItemNotNull]List<string> books) @@ -87,9 +87,9 @@ internal sealed class NotNullAttribute : Attribute { } internal sealed class ItemNotNullAttribute : Attribute { } /// - /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task - /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property - /// or of the Lazy.Value property can be null. + /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task + /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property, + /// or of the Lazy.Value property can be null. /// /// /// public void Foo([ItemCanBeNull]List<string> books) @@ -108,8 +108,8 @@ internal sealed class ItemCanBeNullAttribute : Attribute { } /// /// Indicates that the marked method builds a string by the format pattern and (optional) arguments. - /// The parameter, which contains the format string, should be given in the constructor. The format string - /// should be in -like form. + /// The parameter that accepts the format string should be specified in the constructor. The format string + /// should be in the -like form. /// /// /// [StringFormatMethod("message")] @@ -119,6 +119,7 @@ internal sealed class ItemCanBeNullAttribute : Attribute { } /// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string /// } /// + /// [AttributeUsage( AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate)] @@ -136,8 +137,8 @@ public StringFormatMethodAttribute([NotNull] string formatParameterName) } /// - /// Indicates that the marked parameter is a message template where placeholders are to be replaced by the following arguments - /// in the order in which they appear. + /// Indicates that the marked parameter is a message template where placeholders are to be replaced by + /// the following arguments in the order in which they appear. /// /// /// void LogInfo([StructuredMessageTemplate]string message, params object[] args) { /* do something */ } @@ -146,6 +147,7 @@ public StringFormatMethodAttribute([NotNull] string formatParameterName) /// LogInfo("User created: {username}"); // Warning: Non-existing argument in format string /// } /// + /// [AttributeUsage(AttributeTargets.Parameter)] internal sealed class StructuredMessageTemplateAttribute : Attribute {} @@ -191,8 +193,8 @@ public ValueProviderAttribute([NotNull] string name) /// /// Indicates that the integral value falls into the specified interval. - /// It's allowed to specify multiple non-intersecting intervals. - /// Values of interval boundaries are inclusive. + /// It is allowed to specify multiple non-intersecting intervals. + /// Values of interval boundaries are included in the interval. /// /// /// void Foo([ValueRange(0, 100)] int value) { @@ -251,7 +253,7 @@ internal sealed class NonNegativeValueAttribute : Attribute { } /// /// Indicates that the function argument should be a string literal and match /// one of the parameters of the caller function. This annotation is used for parameters - /// like 'string paramName' parameter of the constructor. + /// like string paramName parameter of the constructor. /// /// /// void Foo(string param) { @@ -263,7 +265,7 @@ internal sealed class NonNegativeValueAttribute : Attribute { } internal sealed class InvokerParameterNameAttribute : Attribute { } /// - /// Indicates that the method is contained in a type that implements + /// Indicates that the method is contained in a type that implements the /// System.ComponentModel.INotifyPropertyChanged interface and this method /// is used to notify that some property value changed. /// @@ -313,7 +315,7 @@ public NotifyPropertyChangedInvocatorAttribute([NotNull] string parameterName) } /// - /// Describes dependence between method input and output. + /// Describes dependence between the input and output of a method. /// /// ///

Function Definition Table syntax:

@@ -327,9 +329,9 @@ public NotifyPropertyChangedInvocatorAttribute([NotNull] string parameterName) /// If the method has a single input parameter, its name could be omitted.
/// Using halt (or void/nothing, which is the same) for the method output /// means that the method doesn't return normally (throws or terminates the process).
- /// Value canbenull is only applicable for output parameters.
- /// You can use multiple [ContractAnnotation] for each FDT row, or use single attribute - /// with rows separated by the semicolon. There is no notion of order rows, all rows are checked + /// The canbenull value is only applicable to output parameters.
+ /// You can use multiple [ContractAnnotation] for each FDT row, or use a single attribute + /// with rows separated by the semicolon. The order of rows doesn't matter, all rows are checked /// for applicability and applied per each program state tracked by the analysis engine.
///
/// @@ -397,8 +399,8 @@ public LocalizationRequiredAttribute(bool required) /// /// Indicates that the value of the marked type (or its derivatives) - /// cannot be compared using '==' or '!=' operators and Equals() - /// should be used instead. However, using '==' or '!=' for comparison + /// cannot be compared using == or != operators, and Equals() + /// should be used instead. However, using == or != for comparison /// with null is always permitted. /// /// @@ -418,6 +420,41 @@ public LocalizationRequiredAttribute(bool required) [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)] internal sealed class CannotApplyEqualityOperatorAttribute : Attribute { } + /// + /// Indicates that the method or type uses equality members of the annotated element. + /// + /// + /// When applied to the method's generic parameter, indicates that the equality of the annotated type is used, + /// unless a custom equality comparer is passed when calling this method. The attribute can also be applied + /// directly to the method's parameter or return type to specify equality usage for it. + /// When applied to the type's generic parameter, indicates that type equality usage can happen anywhere + /// inside this type, so the instantiation of this type is treated as equality usage, unless a custom + /// equality comparer is passed to the constructor. + /// + /// + /// struct StructWithDefaultEquality { } + /// + /// class MySet<[DefaultEqualityUsage] T> { } + /// + /// static class Extensions { + /// public static MySet<T> ToMySet<[DefaultEqualityUsage] T>(this IEnumerable<T> items) => new(); + /// } + /// + /// class MyList<T> { public int IndexOf([DefaultEqualityUsage] T item) => 0; } + /// + /// class UsesDefaultEquality { + /// void Test() { + /// var list = new MyList<StructWithDefaultEquality>(); + /// list.IndexOf(new StructWithDefaultEquality()); // Warning: Default equality of struct 'StructWithDefaultEquality' is used + /// + /// var set = new MySet<StructWithDefaultEquality>(); // Warning: Default equality of struct 'StructWithDefaultEquality' is used + /// var set2 = new StructWithDefaultEquality[1].ToMySet(); // Warning: Default equality of struct 'StructWithDefaultEquality' is used + /// } + /// } + /// + [AttributeUsage(AttributeTargets.GenericParameter | AttributeTargets.Parameter | AttributeTargets.ReturnValue)] +internal sealed class DefaultEqualityUsageAttribute : Attribute { } + /// /// When applied to a target attribute, specifies a requirement for any type marked /// with the target attribute to implement or inherit the specific type or types. @@ -442,7 +479,7 @@ public BaseTypeRequiredAttribute([NotNull] Type baseType) } /// - /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), + /// Indicates that the marked symbol is used implicitly (via reflection, in an external library, and so on), /// so this symbol will be ignored by usage-checking inspections.
/// You can use and /// to configure how this attribute is applied. @@ -481,10 +518,12 @@ public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTar public ImplicitUseKindFlags UseKindFlags { get; } public ImplicitUseTargetFlags TargetFlags { get; } + + public string Reason { get; set; } } /// - /// Can be applied to attributes, type parameters, and parameters of a type assignable from . + /// Can be applied to attributes, type parameters, and parameters of a type assignable from . /// When applied to an attribute, the decorated attribute behaves the same as . /// When applied to a type parameter or to a parameter of type , /// indicates that the corresponding type is used implicitly. @@ -526,7 +565,7 @@ internal enum ImplicitUseKindFlags Assign = 2, /// /// Indicates implicit instantiation of a type with fixed constructor signature. - /// That means any unused constructor parameters won't be reported as such. + /// That means any unused constructor parameters will not be reported as such. /// InstantiatedWithFixedConstructorSignature = 4, /// Indicates implicit instantiation of a type. @@ -551,8 +590,8 @@ internal enum ImplicitUseTargetFlags } /// - /// This attribute is intended to mark publicly available APIs, - /// which should not be removed and so is treated as used. + /// This attribute is intended to mark publicly available APIs + /// that should not be removed and therefore should never be reported as unused. /// [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)] [AttributeUsage(AttributeTargets.All, Inherited = false)] @@ -574,21 +613,22 @@ public PublicAPIAttribute([NotNull] string comment) /// (the delegate can be invoked zero or multiple times, but not stored to some field and invoked later, /// when the containing method is no longer on the execution stack). /// If the parameter is an enumerable, indicates that it is enumerated while the method is executed. - /// If is true, the attribute will only take effect if the method invocation is located under the 'await' expression. + /// If is true, the attribute will only take effect + /// if the method invocation is located under the await expression. /// [AttributeUsage(AttributeTargets.Parameter)] internal sealed class InstantHandleAttribute : Attribute { /// - /// Require the method invocation to be used under the 'await' expression for this attribute to take effect on the code analysis engine. - /// Can be used for delegate/enumerable parameters of 'async' methods. + /// Requires the method invocation to be used under the await expression for this attribute to take effect. + /// Can be used for delegate/enumerable parameters of async methods. /// public bool RequireAwait { get; set; } } /// - /// Indicates that a method does not make any observable state changes. - /// The same as System.Diagnostics.Contracts.PureAttribute. + /// Indicates that the method does not make any observable state changes. + /// The same as . /// /// /// [Pure] int Multiply(int x, int y) => x * y; @@ -607,7 +647,7 @@ internal sealed class PureAttribute : Attribute { } /// Methods decorated with this attribute (in contrast to pure methods) might change state, /// but make no sense without using their return value.
/// Similarly to , this attribute - /// will help to detect usages of the method when the return value is not used. + /// will help detect usages of the method when the return value is not used. /// Optionally, you can specify a message to use when showing warnings, e.g. /// [MustUseReturnValue("Use the return value to...")]. /// @@ -625,16 +665,70 @@ public MustUseReturnValueAttribute([NotNull] string justification) } /// - /// This annotation allows to enforce allocation-less usage patterns of delegates for performance-critical APIs. - /// When this annotation is applied to the parameter of delegate type, the IDE checks the input argument of this parameter: + /// Indicates that the resource disposal must be handled at the use site, + /// meaning that the resource ownership is transferred to the caller. + /// This annotation can be used to annotate disposable types or their constructors individually to enable + /// the IDE code analysis for resource disposal in every context where the new instance of this type is created. + /// Factory methods and out parameters can also be annotated to indicate that the return value + /// of the disposable type needs handling. + /// + /// + /// Annotation of input parameters with this attribute is meaningless.
+ /// Constructors inherit this attribute from their type if it is annotated, + /// but not from the base constructors they delegate to (if any).
+ /// Resource disposal is expected via using (resource) statement, + /// using var declaration, explicit Dispose() call, or passing the resource as an argument + /// to a parameter annotated with the attribute. + ///
+ [AttributeUsage( + AttributeTargets.Class | AttributeTargets.Struct | + AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Parameter)] +internal sealed class MustDisposeResourceAttribute : Attribute + { + public MustDisposeResourceAttribute() + { + Value = true; + } + + public MustDisposeResourceAttribute(bool value) + { + Value = value; + } + + /// + /// When set to false, disposing of the resource is not obligatory. + /// The main use-case for explicit [MustDisposeResource(false)] annotation + /// is to loosen the annotation for inheritors. + /// + public bool Value { get; } + } + + /// + /// Indicates that method or class instance acquires resource ownership and will dispose it after use. + /// + /// + /// Annotation of out parameters with this attribute is meaningless.
+ /// When an instance method is annotated with this attribute, + /// it means that it is handling the resource disposal of the corresponding resource instance.
+ /// When a field or a property is annotated with this attribute, it means that this type owns the resource + /// and will handle the resource disposal properly (e.g. in own IDisposable implementation). + ///
+ [AttributeUsage( + AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] +internal sealed class HandlesResourceDisposalAttribute : Attribute { } + + /// + /// This annotation allows enforcing allocation-less usage patterns of delegates for performance-critical APIs. + /// When this annotation is applied to the parameter of a delegate type, + /// the IDE checks the input argument of this parameter: /// * When a lambda expression or anonymous method is passed as an argument, the IDE verifies that the passed closure /// has no captures of the containing local variables and the compiler is able to cache the delegate instance - /// to avoid heap allocations. Otherwise a warning is produced. - /// * The IDE warns when the method name or local function name is passed as an argument as this always results + /// to avoid heap allocations. Otherwise, a warning is produced. + /// * The IDE warns when the method name or local function name is passed as an argument because this always results /// in heap allocation of the delegate instance. /// /// - /// In C# 9.0+ code, the IDE will also suggest to annotate the anonymous function with the 'static' modifier + /// In C# 9.0+ code, the IDE will also suggest annotating the anonymous functions with the static modifier /// to make use of the similar analysis provided by the language/compiler. /// [AttributeUsage(AttributeTargets.Parameter)] @@ -645,7 +739,7 @@ internal sealed class RequireStaticDelegateAttribute : Attribute /// /// Indicates the type member or parameter of some type that should be used instead of all other ways - /// to get the value of that type. This annotation is useful when you have some "context" value evaluated + /// to get the value of that type. This annotation is useful when you have some 'context' value evaluated /// and stored somewhere, meaning that all other ways to get this value must be consolidated with the existing one. /// /// @@ -690,10 +784,12 @@ public PathReferenceAttribute([NotNull, PathReference] string basePath) /// Text inside these comments is added as source code when the template is applied. Template parameters /// can be used either as additional method parameters or as identifiers wrapped in two '$' signs. /// Use the attribute to specify macros for parameters. + /// The expression to be used in the expansion can be adjusted + /// by the parameter. /// /// - /// In this example, the 'forEach' method is a source template available over all values - /// of enumerable types, producing ordinary C# 'foreach' statement and placing the caret inside the block: + /// In this example, the forEach method is a source template available over all values + /// of enumerable types, producing an ordinary C# foreach statement and placing the caret inside the block: /// /// [SourceTemplate] /// public static void forEach<T>(this IEnumerable<T> xs) { @@ -704,19 +800,44 @@ public PathReferenceAttribute([NotNull, PathReference] string basePath) /// /// [AttributeUsage(AttributeTargets.Method)] -internal sealed class SourceTemplateAttribute : Attribute { } +internal sealed class SourceTemplateAttribute : Attribute + { + /// + /// Allows specifying the expression to capture for template execution if more than one expression + /// is available at the expansion point. + /// If not specified, is assumed. + /// + public SourceTemplateTargetExpression Target { get; set; } + } + + /// + /// Provides a value for the to define how to capture + /// the expression at the point of expansion + /// +internal enum SourceTemplateTargetExpression + { + /// Selects inner expression + /// value > 42.{caret} captures 42 + /// _args = args.{caret} captures args + Inner = 0, + + /// Selects outer expression + /// value > 42.{caret} captures value > 42 + /// _args = args.{caret} captures whole assignment + Outer = 1 + } /// /// Allows specifying a macro for a parameter of a source template. /// /// - /// You can apply the attribute on the whole method or on any of its additional parameters. The macro expression - /// is defined in the property. When applied on a method, the target + /// You can apply the attribute to the whole method or to any of its additional parameters. The macro expression + /// is defined in the property. When applied to a method, the target /// template parameter is defined in the property. To apply the macro silently /// for the parameter, set the property value to -1. /// /// - /// Applying the attribute on a source template method: + /// Applying the attribute to a source template method: /// /// [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")] /// public static void forEach<T>(this IEnumerable<T> collection) { @@ -725,7 +846,7 @@ internal sealed class SourceTemplateAttribute : Attribute { } /// } /// } /// - /// Applying the attribute on a template method parameter: + /// Applying the attribute to a template method parameter: /// /// [SourceTemplate] /// public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) { @@ -744,7 +865,7 @@ internal sealed class MacroAttribute : Attribute [CanBeNull] public string Expression { get; set; } /// - /// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed. + /// Allows specifying the occurrence of the target parameter that becomes editable when the template is deployed. /// /// /// If the target parameter is used several times in the template, only one occurrence becomes editable; @@ -755,7 +876,7 @@ internal sealed class MacroAttribute : Attribute /// /// Identifies the target parameter of a source template if the - /// is applied on a template method. + /// is applied to a template method. /// [CanBeNull] public string Target { get; set; } } @@ -763,9 +884,9 @@ internal sealed class MacroAttribute : Attribute /// /// Indicates how a method, constructor invocation, or property access /// over a collection type affects the contents of the collection. - /// When applied to a return value of a method, indicates if the returned collection - /// is created exclusively for the caller (CollectionAccessType.UpdatedContent) or - /// can be read/updated from outside (CollectionAccessType.Read | CollectionAccessType.UpdatedContent) + /// When applied to a return value of a method, indicates whether the returned collection + /// is created exclusively for the caller (CollectionAccessType.UpdatedContent) or + /// can be read/updated from outside (CollectionAccessType.Read/CollectionAccessType.UpdatedContent). /// Use to specify the access type. /// /// @@ -867,15 +988,15 @@ internal enum AssertionConditionType internal sealed class TerminatesProgramAttribute : Attribute { } /// - /// Indicates that the method is a pure LINQ method, with postponed enumeration (like Enumerable.Select, - /// .Where). This annotation allows inference of [InstantHandle] annotation for parameters + /// Indicates that the method is a pure LINQ method with postponed enumeration (like Enumerable.Select or + /// Enumerable.Where). This annotation allows inference of the [InstantHandle] annotation for parameters /// of delegate type by analyzing LINQ method chains. /// [AttributeUsage(AttributeTargets.Method)] internal sealed class LinqTunnelAttribute : Attribute { } /// - /// Indicates that IEnumerable passed as a parameter is not enumerated. + /// Indicates that an IEnumerable passed as a parameter is not enumerated. /// Use this annotation to suppress the 'Possible multiple enumeration of IEnumerable' inspection. /// /// @@ -900,25 +1021,25 @@ internal sealed class NoEnumerationAttribute : Attribute { } internal sealed class RegexPatternAttribute : Attribute { } /// - /// Language of injected code fragment inside marked by the string literal. + /// Language of the injected code fragment inside a string literal marked by the . /// internal enum InjectedLanguage { - CSS, - HTML, - JAVASCRIPT, - JSON, - XML + CSS = 0, + HTML = 1, + JAVASCRIPT = 2, + JSON = 3, + XML = 4 } /// - /// Indicates that the marked parameter, field, or property is accepting a string literal + /// Indicates that the marked parameter, field, or property accepts string literals /// containing code fragments in a specified language. /// /// /// void Foo([LanguageInjection(InjectedLanguage.CSS, Prefix = "body{", Suffix = "}")] string cssProps) /// { - /// // cssProps should only contains a list of CSS properties + /// // cssProps should only contain a list of CSS properties /// } /// /// @@ -945,111 +1066,131 @@ public LanguageInjectionAttribute([NotNull] string injectedLanguage) /// Specifies a language name of the injected code fragment. [CanBeNull] public string InjectedLanguageName { get; } - /// Specifies a string that "precedes" the injected string literal. + /// Specifies a string that 'precedes' the injected string literal. [CanBeNull] public string Prefix { get; set; } - /// Specifies a string that "follows" the injected string literal. + /// Specifies a string that 'follows' the injected string literal. [CanBeNull] public string Suffix { get; set; } } /// - /// Prevents the Member Reordering feature from tossing members of the marked class. + /// Prevents the Member Reordering feature in the IDE from tossing members of the marked class. /// /// /// The attribute must be mentioned in your member reordering patterns. /// [AttributeUsage( - AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum)] + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true)] internal sealed class NoReorderAttribute : Attribute { } /// - /// - /// Defines the code search template using the Structural Search and Replace syntax. + /// Defines a code search pattern using the Structural Search and Replace syntax. /// It allows you to find and, if necessary, replace blocks of code that match a specific pattern. + /// + /// /// Search and replace patterns consist of a textual part and placeholders. - /// Textural part must contain only identifiers allowed in the target language and will be matched exactly (white spaces, tabulation characters, and line breaks are ignored). + /// Textural part must contain only identifiers allowed in the target language and will be matched exactly + /// (whitespaces, tabulation characters, and line breaks are ignored). /// Placeholders allow matching variable parts of the target code blocks. - /// A placeholder has the following format: $placeholder_name$- where placeholder_name is an arbitrary identifier. - /// - /// - /// Available placeholders: + ///
+ /// A placeholder has the following format: + /// $placeholder_name$ - where placeholder_name is an arbitrary identifier. + /// Predefined placeholders: /// - /// $this$ - expression of containing type - /// $thisType$ - containing type - /// $member$ - current member placeholder - /// $qualifier$ - this placeholder is available in the replace pattern and can be used to insert a qualifier expression matched by the $member$ placeholder. - /// (Note that if $qualifier$ placeholder is used, then $member$ placeholder will match only qualified references) - /// $expression$ - expression of any type - /// $identifier$ - identifier placeholder - /// $args$ - any number of arguments - /// $arg$ - single argument - /// $arg1$ ... $arg10$ - single argument - /// $stmts$ - any number of statements - /// $stmt$ - single statement - /// $stmt1$ ... $stmt10$ - single statement - /// $name{Expression, 'Namespace.FooType'}$ - expression with 'Namespace.FooType' type - /// $expression{'Namespace.FooType'}$ - expression with 'Namespace.FooType' type - /// $name{Type, 'Namespace.FooType'}$ - 'Namespace.FooType' type - /// $type{'Namespace.FooType'}$ - 'Namespace.FooType' type - /// $statement{1,2}$ - 1 or 2 statements + /// $this$ - expression of containing type + /// $thisType$ - containing type + /// $member$ - current member placeholder + /// $qualifier$ - this placeholder is available in the replace pattern and can be used + /// to insert a qualifier expression matched by the $member$ placeholder. + /// (Note that if $qualifier$ placeholder is used, + /// then $member$ placeholder will match only qualified references) + /// $expression$ - expression of any type + /// $identifier$ - identifier placeholder + /// $args$ - any number of arguments + /// $arg$ - single argument + /// $arg1$ ... $arg10$ - single argument + /// $stmts$ - any number of statements + /// $stmt$ - single statement + /// $stmt1$ ... $stmt10$ - single statement + /// $name{Expression, 'Namespace.FooType'}$ - expression with the Namespace.FooType type + /// $expression{'Namespace.FooType'}$ - expression with the Namespace.FooType type + /// $name{Type, 'Namespace.FooType'}$ - Namespace.FooType type + /// $type{'Namespace.FooType'}$ - Namespace.FooType type + /// $statement{1,2}$ - 1 or 2 statements /// - ///
- /// - /// Note that you can also define your own placeholders of the supported types and specify arguments for each placeholder type. - /// This can be done using the following format: $name{type, arguments}$. Where 'name' - is the name of your placeholder, - /// 'type' - is the type of your placeholder (one of the following: Expression, Type, Identifier, Statement, Argument, Member), - /// 'arguments' - arguments list for your placeholder. Each placeholder type supports its own arguments, check examples below for more details. - /// The placeholder type may be omitted and determined from the placeholder name, if the name has one of the following prefixes: + /// You can also define your own placeholders of the supported types and specify arguments for each placeholder type. + /// This can be done using the following format: $name{type, arguments}$. Where + /// name - is the name of your placeholder, + /// type - is the type of your placeholder + /// (one of the following: Expression, Type, Identifier, Statement, Argument, Member), + /// arguments - a list of arguments for your placeholder. Each placeholder type supports its own arguments. + /// Check the examples below for more details. + /// The placeholder type may be omitted and determined from the placeholder name, + /// if the name has one of the following prefixes: /// - /// expr, expression - expression placeholder, e.g. $exprPlaceholder{}$, $expressionFoo{}$ - /// arg, argument - argument placeholder, e.g. $argPlaceholder{}$, $argumentFoo{}$ - /// ident, identifier - identifier placeholder, e.g. $identPlaceholder{}$, $identifierFoo{}$ - /// stmt, statement - statement placeholder, e.g. $stmtPlaceholder{}$, $statementFoo{}$ - /// type - type placeholder, e.g. $typePlaceholder{}$, $typeFoo{}$ - /// member - member placeholder, e.g. $memberPlaceholder{}$, $memberFoo{}$ + /// expr, expression - expression placeholder, e.g. $exprPlaceholder{}$, $expressionFoo{}$ + /// arg, argument - argument placeholder, e.g. $argPlaceholder{}$, $argumentFoo{}$ + /// ident, identifier - identifier placeholder, e.g. $identPlaceholder{}$, $identifierFoo{}$ + /// stmt, statement - statement placeholder, e.g. $stmtPlaceholder{}$, $statementFoo{}$ + /// type - type placeholder, e.g. $typePlaceholder{}$, $typeFoo{}$ + /// member - member placeholder, e.g. $memberPlaceholder{}$, $memberFoo{}$ /// - /// + ///
/// /// Expression placeholder arguments: /// - /// expressionType - string value in single quotes, specifies full type name to match (empty string by default) + /// expressionType - string value in single quotes, specifies full type name to match + /// (empty string by default) /// exactType - boolean value, specifies if expression should have exact type match (false by default) /// /// Examples: /// - /// $myExpr{Expression, 'Namespace.FooType', true}$ - defines expression placeholder, matching expressions of the 'Namespace.FooType' type with exact matching. - /// $myExpr{Expression, 'Namespace.FooType'}$ - defines expression placeholder, matching expressions of the 'Namespace.FooType' type or expressions which can be implicitly converted to 'Namespace.FooType'. - /// $myExpr{Expression}$ - defines expression placeholder, matching expressions of any type. - /// $exprFoo{'Namespace.FooType', true}$ - defines expression placeholder, matching expressions of the 'Namespace.FooType' type with exact matching. + /// $myExpr{Expression, 'Namespace.FooType', true}$ - defines an expression placeholder + /// matching expressions of the Namespace.FooType type with exact matching. + /// $myExpr{Expression, 'Namespace.FooType'}$ - defines an expression placeholder + /// matching expressions of the Namespace.FooType type or expressions that can be + /// implicitly converted to Namespace.FooType. + /// $myExpr{Expression}$ - defines an expression placeholder matching expressions of any type. + /// $exprFoo{'Namespace.FooType', true}$ - defines an expression placeholder + /// matching expressions of the Namespace.FooType type with exact matching. /// /// /// /// Type placeholder arguments: /// - /// type - string value in single quotes, specifies full type name to match (empty string by default) - /// exactType - boolean value, specifies if expression should have exact type match (false by default) + /// type - string value in single quotes, specifies the full type name to match (empty string by default) + /// exactType - boolean value, specifies whether the expression should have the exact type match + /// (false by default) /// /// Examples: /// - /// $myType{Type, 'Namespace.FooType', true}$ - defines type placeholder, matching 'Namespace.FooType' types with exact matching. - /// $myType{Type, 'Namespace.FooType'}$ - defines type placeholder, matching 'Namespace.FooType' types or types, which can be implicitly converted to 'Namespace.FooType'. - /// $myType{Type}$ - defines type placeholder, matching any type. - /// $typeFoo{'Namespace.FooType', true}$ - defines types placeholder, matching 'Namespace.FooType' types with exact matching. + /// $myType{Type, 'Namespace.FooType', true}$ - defines a type placeholder + /// matching Namespace.FooType types with exact matching. + /// $myType{Type, 'Namespace.FooType'}$ - defines a type placeholder matching Namespace.FooType + /// types or types that can be implicitly converted to Namespace.FooType. + /// $myType{Type}$ - defines a type placeholder matching any type. + /// $typeFoo{'Namespace.FooType', true}$ - defines a type placeholder matching Namespace.FooType + /// types with exact matching. /// /// /// /// Identifier placeholder arguments: /// /// nameRegex - string value in single quotes, specifies regex to use for matching (empty string by default) - /// nameRegexCaseSensitive - boolean value, specifies if name regex is case sensitive (true by default) + /// nameRegexCaseSensitive - boolean value, specifies if name regex is case-sensitive (true by default) /// type - string value in single quotes, specifies full type name to match (empty string by default) /// exactType - boolean value, specifies if expression should have exact type match (false by default) /// /// Examples: /// - /// $myIdentifier{Identifier, 'my.*', false, 'Namespace.FooType', true}$ - defines identifier placeholder, matching identifiers (ignoring case) starting with 'my' prefix with 'Namespace.FooType' type. - /// $myIdentifier{Identifier, 'my.*', true, 'Namespace.FooType', true}$ - defines identifier placeholder, matching identifiers (case sensitively) starting with 'my' prefix with 'Namespace.FooType' type. - /// $identFoo{'my.*'}$ - defines identifier placeholder, matching identifiers (case sensitively) starting with 'my' prefix. + /// $myIdentifier{Identifier, 'my.*', false, 'Namespace.FooType', true}$ - + /// defines an identifier placeholder matching identifiers (ignoring case) starting with my prefix with + /// Namespace.FooType type. + /// $myIdentifier{Identifier, 'my.*', true, 'Namespace.FooType', true}$ - + /// defines an identifier placeholder matching identifiers (case sensitively) starting with my prefix with + /// Namespace.FooType type. + /// $identFoo{'my.*'}$ - defines an identifier placeholder matching identifiers (case sensitively) + /// starting with my prefix. /// /// /// @@ -1060,9 +1201,9 @@ internal sealed class NoReorderAttribute : Attribute { } /// /// Examples: /// - /// $myStmt{Statement, 1, 2}$ - defines statement placeholder, matching 1 or 2 statements. - /// $myStmt{Statement}$ - defines statement placeholder, matching any number of statements. - /// $stmtFoo{1, 2}$ - defines statement placeholder, matching 1 or 2 statements. + /// $myStmt{Statement, 1, 2}$ - defines a statement placeholder matching 1 or 2 statements. + /// $myStmt{Statement}$ - defines a statement placeholder matching any number of statements. + /// $stmtFoo{1, 2}$ - defines a statement placeholder matching 1 or 2 statements. /// /// /// @@ -1073,26 +1214,28 @@ internal sealed class NoReorderAttribute : Attribute { } /// /// Examples: /// - /// $myArg{Argument, 1, 2}$ - defines argument placeholder, matching 1 or 2 arguments. - /// $myArg{Argument}$ - defines argument placeholder, matching any number of arguments. - /// $argFoo{1, 2}$ - defines argument placeholder, matching 1 or 2 arguments. + /// $myArg{Argument, 1, 2}$ - defines an argument placeholder matching 1 or 2 arguments. + /// $myArg{Argument}$ - defines an argument placeholder matching any number of arguments. + /// $argFoo{1, 2}$ - defines an argument placeholder matching 1 or 2 arguments. /// /// /// /// Member placeholder arguments: /// - /// docId - string value in single quotes, specifies XML documentation id of the member to match (empty by default) + /// docId - string value in single quotes, specifies XML documentation ID of the member to match (empty by default) /// /// Examples: /// - /// $myMember{Member, 'M:System.String.IsNullOrEmpty(System.String)'}$ - defines member placeholder, matching 'IsNullOrEmpty' member of the 'System.String' type. - /// $memberFoo{'M:System.String.IsNullOrEmpty(System.String)'}$ - defines member placeholder, matching 'IsNullOrEmpty' member of the 'System.String' type. + /// $myMember{Member, 'M:System.String.IsNullOrEmpty(System.String)'}$ - + /// defines a member placeholder matching IsNullOrEmpty member of the System.String type. + /// $memberFoo{'M:System.String.IsNullOrEmpty(System.String)'}$ - + /// defines a member placeholder matching IsNullOrEmpty member of the System.String type. /// /// - /// - /// For more information please refer to the Structural Search and Replace article. - /// - ///
+ /// + /// Structural Search and Replace + /// + /// Find and update deprecated APIs [AttributeUsage( AttributeTargets.Method | AttributeTargets.Constructor @@ -1113,27 +1256,32 @@ public CodeTemplateAttribute(string searchTemplate) } /// - /// Structural search pattern to use in the code template. - /// The pattern includes a textual part, which must contain only identifiers allowed in the target language, - /// and placeholders, which allow matching variable parts of the target code blocks. + /// Structural search pattern. /// + /// + /// The pattern includes a textual part, which must only contain identifiers allowed in the target language + /// and placeholders to match variable parts of the target code blocks. + /// public string SearchTemplate { get; } /// - /// Message to show when the search pattern was found. - /// You can also prepend the message text with "Error:", "Warning:", "Suggestion:" or "Hint:" prefix to specify the pattern severity. - /// Code patterns with replace templates produce suggestions by default. - /// However, if a replace template is not provided, then warning severity will be used. + /// Message to show when a code block matching the search pattern was found. /// + /// + /// You can also prepend the message text with 'Error:', 'Warning:', 'Suggestion:' or 'Hint:' prefix + /// to specify the pattern severity. + /// Code patterns with replace templates have the 'Suggestion' severity by default. + /// If a replace pattern is not provided, the pattern will have the 'Warning' severity. + /// public string Message { get; set; } /// - /// Structural search replace pattern to use in code template replacement. + /// Replace pattern to use for replacing a matched pattern. /// public string ReplaceTemplate { get; set; } /// - /// The replace message to show in the light bulb. + /// Replace message to show in the light bulb. /// public string ReplaceMessage { get; set; } @@ -1148,18 +1296,29 @@ public CodeTemplateAttribute(string searchTemplate) public bool MatchSimilarConstructs { get; set; } /// - /// Automatically insert namespace import directives or remove qualifiers that become redundant after the template is applied. + /// Automatically insert namespace import directives or remove qualifiers + /// that become redundant after the template is applied. /// public bool ShortenReferences { get; set; } /// /// The string to use as a suppression key. - /// By default the following suppression key is used 'CodeTemplate_SomeType_SomeMember', - /// where 'SomeType' and 'SomeMember' are names of the associated containing type and member to which this attribute is applied. + /// By default, the following suppression key is used: CodeTemplate_SomeType_SomeMember, + /// where 'SomeType' and 'SomeMember' are names of the associated containing type and member, + /// to which this attribute is applied. /// public string SuppressionKey { get; set; } } + /// + /// Indicates that the string literal passed as an argument to this parameter + /// should not be checked for spelling or grammar errors. + /// + [AttributeUsage(AttributeTargets.Parameter)] +internal sealed class IgnoreSpellingAndGrammarErrorsAttribute : Attribute + { + } + #region ASP.NET [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] @@ -1482,10 +1641,10 @@ public RouteParameterConstraintAttribute([NotNull] string constraintName) } /// - /// Indicates that the marked parameter, field, or property is an URI string. + /// Indicates that the marked parameter, field, or property is a URI string. /// /// - /// This attribute enables code completion, navigation, renaming and other features + /// This attribute enables code completion, navigation, renaming, and other features /// in URI string literals assigned to annotated parameters, fields, or properties. /// [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] @@ -1583,6 +1742,28 @@ internal sealed class AspMinimalApiGroupAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter)] internal sealed class AspMinimalApiHandlerAttribute : Attribute { } + /// + /// Indicates that the marked method contains Minimal API endpoint declaration. + /// + /// + /// The IDE will analyze all usages of methods marked with this attribute, + /// and will add all declared in attributes routes to completion, navigation and other features over URI strings. + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] +internal sealed class AspMinimalApiImplicitEndpointDeclarationAttribute : Attribute + { + public string HttpVerb { get; set; } + + public string RouteTemplate { get; set; } + + public Type BodyType { get; set; } + + /// + /// Comma-separated list of query parameters defined for endpoint + /// + public string QueryParameters { get; set; } + } + #endregion #region Razor @@ -1701,10 +1882,10 @@ internal sealed class XamlItemsControlAttribute : Attribute { } /// /// XAML attribute. Indicates the property of some BindingBase-derived type, that /// is used to bind some item of an ItemsControl-derived type. This annotation will - /// enable the DataContext type resolve for XAML bindings for such properties. + /// enable the DataContext type resolution for XAML bindings for such properties. /// /// - /// The property should have the tree ancestor of the ItemsControl type, or + /// The property should have a tree ancestor of the ItemsControl type or /// marked with the attribute. /// [AttributeUsage(AttributeTargets.Property)] @@ -1713,10 +1894,10 @@ internal sealed class XamlItemBindingOfItemsControlAttribute : Attribute { } /// /// XAML attribute. Indicates the property of some Style-derived type that /// is used to style items of an ItemsControl-derived type. This annotation will - /// enable the DataContext type resolve for XAML bindings for such properties. + /// enable the DataContext type resolution in XAML bindings for such properties. /// /// - /// Property should have the tree ancestor of the ItemsControl type or + /// Property should have a tree ancestor of the ItemsControl type or /// marked with the attribute. /// [AttributeUsage(AttributeTargets.Property)] @@ -1745,25 +1926,24 @@ internal sealed class XamlTwoWayBindingModeByDefaultAttribute : Attribute { } #region Unit Testing /// - /// Specifies the subject being tested by a test class or a test method. + /// Specifies a type being tested by a test class or a test method. /// /// - /// The can be applied to a test class or a test method to indicate what class - /// or interface the tests defined in them test. This information can be used by an IDE to provide better navigation - /// support or by test runners to group tests by subject and to provide better test reports. + /// This information can be used by the IDE to navigate between tests and tested types, + /// or by test runners to group tests by subject and to provide better test reports. /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)] internal sealed class TestSubjectAttribute : Attribute { /// - /// Gets the type of the subject being tested. + /// Gets the type being tested. /// [NotNull] public Type Subject { get; } /// - /// Initializes a new instance of the class with the specified subject type. + /// Initializes a new instance of the class with the specified tested type. /// - /// The type of the subject being tested. + /// The type being tested. public TestSubjectAttribute([NotNull] Type subject) { Subject = subject; @@ -1771,12 +1951,13 @@ public TestSubjectAttribute([NotNull] Type subject) } /// - /// Signifies a generic argument as the test subject for a test class. + /// Marks a generic argument as the test subject for a test class. /// /// - /// The can be applied to a generic parameter of a base test class to indicate that - /// the type passed as the argument is the class being tested. This information can be used by an IDE to provide better - /// navigation support or by test runners to group tests by subject and to provide better test reports. + /// Can be applied to a generic parameter of a base test class to indicate that + /// the type passed as the argument is the class being tested. This information can be used by the IDE + /// to navigate between tests and tested types, + /// or by test runners to group tests by subject and to provide better test reports. /// /// /// public class BaseTestClass<[MeansTestSubject] T>