public void Add_DuplicateValues_MixedCase_OneExemption() { var exemptions = new ExemptionCollection(); exemptions.Add("foo"); exemptions.Add("FOO"); Assert.Single(exemptions); }
public void Add_DistinctValues_MultipleExemptions() { const int ExpectedCount = 2; var exemptions = new ExemptionCollection(); exemptions.Add("foo"); exemptions.Add("bar"); Assert.Equal(ExpectedCount, exemptions.Count); }
public void Add_DuplicateValues_DuplicateAttributes_OneExemptionWithOneAttribute() { var exemptions = new ExemptionCollection(); exemptions.Add("foo", new AttributeCollection(Tuple.Create("Assembly", "A"))); exemptions.Add("foo", new AttributeCollection(Tuple.Create("Assembly", "A"))); Assert.Single(exemptions); Assert.Single(exemptions["foo"]); }
public void Add_DuplicateValues_DistinctAttributeNames_OneExemptionWithOneAttribute() { var exemptions = new ExemptionCollection(); exemptions.Add("foo", new AttributeCollection(Tuple.Create("Assembly", "A"))); exemptions.Add("foo", new AttributeCollection(Tuple.Create("Parameter", "B"))); var attributes = exemptions["foo"]; Assert.Single(exemptions); Assert.Single(attributes); Assert.DoesNotContain("Assembly", attributes.Names); Assert.Contains("Parameter", attributes.Names); Assert.Single(attributes["Parameter"]); }
public void Add_SingleValue_OneExemption() { var exemptions = new ExemptionCollection(); exemptions.Add("foo"); Assert.Single(exemptions); }
private void AddExemptionsFromAttributes(IEnumerable <AttributeData> attributes, SyntaxNode decoratedSyntax, SemanticModel semanticModel) { foreach (var attribute in attributes) { var attributeName = attribute.AttributeClass.Name; if (ExemptionAttributeNames.Contains(attributeName)) { var exemptionAttribute = new ExemptionAttribute(attribute); switch (exemptionAttribute.Name) { case ExemptFromStringLiteralsRuleAttributeName: case ImplementationAllowedToUseStringLiteralsAttributeName: AddScopeExemption(exemptionAttribute, decoratedSyntax.GetDeclaredOrReferencedSymbol(semanticModel)); break; case AcceptsStringLiteralArgumentsAttributeName: case AllowExternalCodeToAcceptStringLiteralArgumentsAttributeName: AddInvocationExemption(exemptionAttribute, decoratedSyntax.GetDeclaredOrReferencedSymbol(semanticModel)); break; case AllowThisNonLocalizedLiteralAttributeName: _exemptStrings.Add(exemptionAttribute.Literal, DefaultAttributes); break; } } if (decoratedSyntax == null && attributeName.Contains("AssemblyMetadata") && attribute.ConstructorArguments[0].Value.ToString() == "Localize.Constant") { _exemptStrings.Add(attribute.ConstructorArguments[1].Value.ToString(), DefaultAttributes); } } }
private static void LoadScopeAndOrInvocationExemptions( IEnumerable <XElement> exemptionNodes, ExemptionCollection scopeExemptions, ExemptionCollection invocationExemptions) { // Type and member exemptions will, by default, apply to both scopes and invocations. // This method allows users to specify an "AppliesTo" attribute to control whether an // exemption applies to only one or the other. foreach (var exemption in exemptionNodes) { var appliesAttribute = exemption.Attribute("AppliesTo"); if (appliesAttribute != null) { var attributePairs = exemption.Attributes() .Where(x => x != appliesAttribute) .Select(x => Tuple.Create(x.Name.LocalName, x.Value)).ToArray(); AttributeCollection attributes = null; if (attributePairs.Length > 0) { attributes = new AttributeCollection(attributePairs); } if (string.Equals(appliesAttribute.Value, "Scope", StringComparison.OrdinalIgnoreCase)) { scopeExemptions.Add(exemption.Value, attributes); } else { invocationExemptions.Add(exemption.Value, attributes); } } else { var exemptions = new[] { exemption }; scopeExemptions.UnionWith(exemptions); invocationExemptions.UnionWith(exemptions); } } }
private void AddInvocationExemption(ExemptionAttribute exemptionAttribute, ISymbol decoratedSymbol) { string target; AttributeCollection attributes = DefaultAttributes; switch (exemptionAttribute.Scope) { case ExemptionScope.Class: case ExemptionScope.BaseClass: // Exempts any literal being passed to a member of this class or a class that derives from the base if (decoratedSymbol != null) { // Must be decorating a named type target = ExemptionAttribute.GetTargetFromAttributeOrSymbol <INamedTypeSymbol>(exemptionAttribute, decoratedSymbol); _exemptTypes.Add(target, DefaultAttributes); } else { // Must be an assembly attribute target = ExemptionAttribute.GetTargetFromAttribute(exemptionAttribute); _exemptTypes.Add(target, DefaultAttributes); } break; case ExemptionScope.Method: // Exempts any literal being passed to the specified method and optionally, parameter(s) // Note: this can only occur as an assembly attribute var targetParts = ExemptionAttribute.GetTargetFromAttribute(exemptionAttribute) .Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); target = targetParts[0]; if (targetParts.Length > 1) { attributes.Add(Parameter, string.Join("|", targetParts.Skip(1))); } _exemptMembers.Add(target, attributes); break; case ExemptionScope.Parameter: // Exempts the specified parameter of the associated method // Note: cannot occur as an assembly attribute if (decoratedSymbol != null) { target = ExemptionAttribute.GetTargetFromAttribute(exemptionAttribute); attributes.Add(Parameter, target); _exemptMembers.Add(decoratedSymbol.GetFullName(), attributes); } break; case ExemptionScope.Unknown: if (decoratedSymbol != null) { // Exempts literals being assigned to the decorated field, property, or indexer and exempts literals being used // in the invocation of the decorated method or method within the decorated type var decoratedSymbolName = decoratedSymbol.GetFullName(); if (decoratedSymbol is IFieldSymbol) { _exemptFields.Add(decoratedSymbolName, DefaultAttributes); } else if (decoratedSymbol is IPropertySymbol || decoratedSymbol is IMethodSymbol) { if (!string.IsNullOrEmpty(exemptionAttribute.Target)) { attributes.Add(Parameter, exemptionAttribute.Target); } _exemptMembers.Add(decoratedSymbolName, attributes); } else if (decoratedSymbol is ITypeSymbol) { _exemptTypes.Add(decoratedSymbolName, DefaultAttributes); } } break; } }
private void AddScopeExemption(ExemptionAttribute exemptionAttribute, ISymbol decoratedSymbol) { string target; switch (exemptionAttribute.Scope) { case ExemptionScope.File: target = ExemptionAttribute.GetTargetFromAttribute(exemptionAttribute); if (!Path.IsPathRooted(target)) { target = string.Concat("*", target); } _exemptFilenames.Add(target); break; case ExemptionScope.Namespace: target = ExemptionAttribute.GetTargetFromAttributeOrSymbol <INamespaceSymbol>(exemptionAttribute, decoratedSymbol); if (!target.EndsWith("*", StringComparison.Ordinal)) { target = string.Concat(target, "*"); } _exemptNamespaces.Add(target); break; case ExemptionScope.Class: target = ExemptionAttribute.GetTargetFromAttributeOrSymbol <INamedTypeSymbol>(exemptionAttribute, decoratedSymbol); _exemptTypeScopes.Add(target); break; case ExemptionScope.Constant: target = ExemptionAttribute.GetTargetFromAttribute(exemptionAttribute); _exemptStrings.Add(target, DefaultAttributes); break; case ExemptionScope.Disabled: case ExemptionScope.Unknown: if (decoratedSymbol == null) { _exemptAssemblies.Add(_compilation.AssemblyName); } else { var decoratedSymbolName = decoratedSymbol.GetFullName(); if (decoratedSymbol is IFieldSymbol) { _exemptFieldScopes.Add(decoratedSymbolName); } else if (decoratedSymbol is IPropertySymbol || decoratedSymbol is IMethodSymbol) { _exemptMemberScopes.Add(decoratedSymbolName); } else if (decoratedSymbol is ITypeSymbol) { _exemptTypeScopes.Add(decoratedSymbolName); } } break; } }