/* * Copyright 2007-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace JetBrains.Annotations { /// /// Indicates that marked element should be localized or not. /// [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)] internal sealed class LocalizationRequiredAttribute : Attribute { /// /// Initializes a new instance of the class. /// /// true if a element should be localized; otherwise, false. public LocalizationRequiredAttribute(bool required) { Required = required; } /// /// Gets a value indicating whether a element should be localized. /// /// true if a element should be localized; otherwise, false. [UsedImplicitly] public bool Required { get; private set; } /// /// Returns whether the value of the given object is equal to the current . /// /// The object to test the value equality of. /// /// true if the value of the given object is equal to that of the current; otherwise, false. /// public override bool Equals(object obj) { var attribute = obj as LocalizationRequiredAttribute; return attribute != null && attribute.Required == Required; } /// /// Returns the hash code for this instance. /// /// A hash code for the current . public override int GetHashCode() { return base.GetHashCode(); } } /// /// Indicates that marked method builds string by format pattern and (optional) arguments. /// Parameter, which contains format string, should be given in constructor. /// The format string should be in -like form /// [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] internal sealed class StringFormatMethodAttribute : Attribute { /// /// Initializes new instance of StringFormatMethodAttribute /// /// Specifies which parameter of an annotated method should be treated as format-string public StringFormatMethodAttribute(string formatParameterName) { FormatParameterName = formatParameterName; } /// /// Gets format parameter name /// [UsedImplicitly] public string FormatParameterName { get; private set; } } /// /// Indicates that the function argument should be string literal and match one of the parameters of the caller function. /// For example, has such parameter. /// [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] internal sealed class InvokerParameterNameAttribute : Attribute { } /// /// Indicates that the value of marked element could be null sometimes, so the check for null is necessary before its usage /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] internal sealed class CanBeNullAttribute : Attribute { } /// /// Indicates that the value of marked element could never be null /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] internal sealed class NotNullAttribute : Attribute { } /// /// Describes dependency between method input and output /// /// ///

Function definition table syntax:

/// /// FDT ::= FDTRow [;FDTRow]* /// FDTRow ::= Input => Output | Output <= Input /// Input ::= ParameterName: Value [, Input]* /// Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value} /// Value ::= true | false | null | notnull | canbenull /// /// If method has single input parameter, it's name could be omitted.
/// Using "halt" (or "void"/"nothing", which is the same) for method output means that methos doesn't return normally.
/// "canbenull" annotation is only applicable for output parameters.
/// You can use multiple [ContractAnnotation] for each FDT row, or use single attribute with rows separated by semicolon.
///
/// /// /// [ContractAnnotation("=> halt")] public void TerminationMethod() /// [ContractAnnotation("halt <= condition: false")] public void Assert(bool condition, string text) // Regular Assertion method /// [ContractAnnotation("s:null => true")] public bool IsNullOrEmpty(string s) // String.IsNullOrEmpty /// [ContractAnnotation("null => null; notnull => notnull")] public object Transform(object data) // Method which returns null if parameter is null, and not null if parameter is not null /// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")] public bool TryParse(string s, out Person result) /// /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] internal sealed class ContractAnnotationAttribute : Attribute { public ContractAnnotationAttribute([NotNull] string fdt) : this(fdt, false) { } public ContractAnnotationAttribute([NotNull] string fdt, bool forceFullStates) { FDT = fdt; ForceFullStates = forceFullStates; } public string FDT { get; private set; } public bool ForceFullStates { get; private set; } } /// /// Indicates that the value of marked type (or its derivatives) cannot be compared using '==' or '!=' operators. /// There is only exception to compare with null, it is permitted /// [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)] internal sealed class CannotApplyEqualityOperatorAttribute : Attribute { } /// /// When applied to target attribute, specifies a requirement for any type which is marked with /// target attribute to implement or inherit specific type or types /// /// /// /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement /// public class ComponentAttribute : Attribute /// {} /// /// [Component] // ComponentAttribute requires implementing IComponent interface /// public class MyComponent : IComponent /// {} /// /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] [BaseTypeRequired(typeof(Attribute))] internal sealed class BaseTypeRequiredAttribute : Attribute { /// /// Initializes new instance of BaseTypeRequiredAttribute /// /// Specifies which types are required public BaseTypeRequiredAttribute(Type baseType) { BaseTypes = new[] { baseType }; } /// /// Gets enumerations of specified base types /// public Type[] BaseTypes { get; private set; } } /// /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), /// so this symbol will not be marked as unused (as well as by other usage inspections) /// [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)] internal sealed class UsedImplicitlyAttribute : Attribute { [UsedImplicitly] public UsedImplicitlyAttribute() : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } [UsedImplicitly] public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) { UseKindFlags = useKindFlags; TargetFlags = targetFlags; } [UsedImplicitly] public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags) : this(useKindFlags, ImplicitUseTargetFlags.Default) { } [UsedImplicitly] public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) : this(ImplicitUseKindFlags.Default, targetFlags) { } [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; } /// /// Gets value indicating what is meant to be used /// [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; } } /// /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes as unused (as well as by other usage inspections) /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] internal sealed class MeansImplicitUseAttribute : Attribute { [UsedImplicitly] public MeansImplicitUseAttribute() : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } [UsedImplicitly] public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) { UseKindFlags = useKindFlags; TargetFlags = targetFlags; } [UsedImplicitly] public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags) : this(useKindFlags, ImplicitUseTargetFlags.Default) { } [UsedImplicitly] public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) : this(ImplicitUseKindFlags.Default, targetFlags) { } [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; } /// /// Gets value indicating what is meant to be used /// [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; } } [Flags] internal enum ImplicitUseKindFlags { Default = Access | Assign | InstantiatedWithFixedConstructorSignature, /// /// Only entity marked with attribute considered used /// Access = 1, /// /// Indicates implicit assignment to a member /// Assign = 2, /// /// Indicates implicit instantiation of a type with fixed constructor signature. /// That means any unused constructor parameters won't be reported as such. /// InstantiatedWithFixedConstructorSignature = 4, /// /// Indicates implicit instantiation of a type /// InstantiatedNoFixedConstructorSignature = 8, } /// /// Specify what is considered used implicitly when marked with or /// [Flags] internal enum ImplicitUseTargetFlags { Default = Itself, Itself = 1, /// /// Members of entity marked with attribute are considered used /// Members = 2, /// /// Entity marked with attribute and all its members considered used /// WithMembers = Itself | Members } /// /// This attribute is intended to mark publicly available API which should not be removed and so is treated as used. /// [MeansImplicitUse] internal sealed class PublicAPIAttribute : Attribute { public PublicAPIAttribute() { } public PublicAPIAttribute(string comment) { } } /// /// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. /// If the parameter is delegate, indicates that delegate is executed while the method is executed. /// If the parameter is enumerable, indicates that it is enumerated while the method is executed. /// [AttributeUsage(AttributeTargets.Parameter, Inherited = true)] internal sealed class InstantHandleAttribute : Attribute { } /// /// Indicates that method doesn't contain observable side effects. /// The same as System.Diagnostics.Contracts.PureAttribute /// [AttributeUsage(AttributeTargets.Method, Inherited = true)] internal sealed class PureAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter)] internal class PathReferenceAttribute : Attribute { public PathReferenceAttribute() { } [UsedImplicitly] public PathReferenceAttribute([PathReference] string basePath) { BasePath = basePath; } [UsedImplicitly] public string BasePath { get; private set; } } // ASP.NET MVC attributes [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] internal sealed class AspMvcActionAttribute : Attribute { [UsedImplicitly] public string AnonymousProperty { get; private set; } public AspMvcActionAttribute() { } public AspMvcActionAttribute(string anonymousProperty) { AnonymousProperty = anonymousProperty; } } [AttributeUsage(AttributeTargets.Parameter)] internal sealed class AspMvcAreaAttribute : PathReferenceAttribute { [UsedImplicitly] public string AnonymousProperty { get; private set; } [UsedImplicitly] public AspMvcAreaAttribute() { } public AspMvcAreaAttribute(string anonymousProperty) { AnonymousProperty = anonymousProperty; } } [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] internal sealed class AspMvcControllerAttribute : Attribute { [UsedImplicitly] public string AnonymousProperty { get; private set; } public AspMvcControllerAttribute() { } public AspMvcControllerAttribute(string anonymousProperty) { AnonymousProperty = anonymousProperty; } } [AttributeUsage(AttributeTargets.Parameter)] internal sealed class AspMvcMasterAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter)] internal sealed class AspMvcModelTypeAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] internal sealed class AspMvcPartialViewAttribute : PathReferenceAttribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] internal sealed class AspMvcSupressViewErrorAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter)] internal sealed class AspMvcTemplateAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] internal sealed class AspMvcViewAttribute : PathReferenceAttribute { } [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)] internal sealed class AspMvcActionSelectorAttribute : Attribute { } // Razor attributes [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, Inherited = true)] internal sealed class RazorSectionAttribute : Attribute { } /// /// Indicates that the marked method is assertion method, i.e. it halts control flow if one of the conditions is satisfied. /// To set the condition, mark one of the parameters with attribute /// /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] internal sealed class AssertionMethodAttribute : Attribute { } /// /// Indicates the condition parameter of the assertion method. /// The method itself should be marked by attribute. /// The mandatory argument of the attribute is the assertion type. /// /// [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] internal sealed class AssertionConditionAttribute : Attribute { private readonly AssertionConditionType myConditionType; /// /// Initializes new instance of AssertionConditionAttribute /// /// Specifies condition type public AssertionConditionAttribute(AssertionConditionType conditionType) { myConditionType = conditionType; } /// /// Gets condition type /// public AssertionConditionType ConditionType { get { return myConditionType; } } } /// /// Specifies assertion type. If the assertion method argument satisifes the condition, then the execution continues. /// Otherwise, execution is assumed to be halted /// internal enum AssertionConditionType { /// /// Indicates that the marked parameter should be evaluated to true /// IS_TRUE = 0, /// /// Indicates that the marked parameter should be evaluated to false /// IS_FALSE = 1, /// /// Indicates that the marked parameter should be evaluated to null value /// IS_NULL = 2, /// /// Indicates that the marked parameter should be evaluated to not null value /// IS_NOT_NULL = 3, } /// /// Indicates that the marked method unconditionally terminates control flow execution. /// For example, it could unconditionally throw exception /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] internal sealed class TerminatesProgramAttribute : Attribute { } /// /// Indicates that IEnumerable, passed as parameter, is not enumerated. /// [AttributeUsage(AttributeTargets.Parameter)] internal sealed class NoEnumerationAttribute : Attribute { } }