internal static string GetTargetFromAttributeOrSymbol <TExpected>(ExemptionAttribute exemptionAttribute, ISymbol decoratedSymbol)
        {
            if (!string.IsNullOrWhiteSpace(exemptionAttribute.Target))
            {
                return(exemptionAttribute.Target);
            }

            if (decoratedSymbol is TExpected)
            {
                return(decoratedSymbol.GetFullName());
            }

            var attributeName = exemptionAttribute.Name;
            var scopeName     = Enum.GetName(typeof(ExemptionScope), exemptionAttribute.Scope);

            throw new AttributeMissingTargetException(
                      string.Format(CultureInfo.CurrentCulture, "Attribute {0} is missing a Target value.", attributeName),
                      attributeName,
                      scopeName);
        }
예제 #2
0
        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);
                }
            }
        }
 public static string GetTargetFromAttribute(ExemptionAttribute exemptionAttribute)
 {
     return(GetTargetFromAttributeOrSymbol <ISymbol>(exemptionAttribute, null));
 }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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;
            }
        }