private void ConfigureBoundAttribute(
        BoundAttributeDescriptorBuilder builder,
        IPropertySymbol property,
        INamedTypeSymbol containingType)
    {
        var attributeNameAttribute = property
                                     .GetAttributes()
                                     .Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, _htmlAttributeNameAttributeSymbol))
                                     .FirstOrDefault();

        bool   hasExplicitName;
        string attributeName;

        if (attributeNameAttribute == null ||
            attributeNameAttribute.ConstructorArguments.Length == 0 ||
            string.IsNullOrEmpty((string)attributeNameAttribute.ConstructorArguments[0].Value))
        {
            hasExplicitName = false;
            attributeName   = HtmlConventions.ToHtmlCase(property.Name);
        }
        else
        {
            hasExplicitName = true;
            attributeName   = (string)attributeNameAttribute.ConstructorArguments[0].Value;
        }

        var hasPublicSetter = property.SetMethod != null && property.SetMethod.DeclaredAccessibility == Accessibility.Public;
        var typeName        = GetFullName(property.Type);

        builder.TypeName = typeName;
        builder.SetPropertyName(property.Name);

        if (hasPublicSetter)
        {
            builder.Name = attributeName;

            if (property.Type.TypeKind == TypeKind.Enum)
            {
                builder.IsEnum = true;
            }

            if (IncludeDocumentation)
            {
                var xml = property.GetDocumentationCommentXml();

                if (!string.IsNullOrEmpty(xml))
                {
                    builder.Documentation = xml;
                }
            }
        }
        else if (hasExplicitName && !IsPotentialDictionaryProperty(property))
        {
            // Specified HtmlAttributeNameAttribute.Name though property has no public setter.
            var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidAttributeNameNullOrEmpty(GetFullName(containingType), property.Name);
            builder.Diagnostics.Add(diagnostic);
        }

        ConfigureDictionaryBoundAttribute(builder, property, containingType, attributeNameAttribute, attributeName, hasPublicSetter);
    }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets a value that indicates whether the property is a child content property. Properties are
        /// considered child content if they have the type <c>RenderFragment</c> or <c>RenderFragment{T}</c>.
        /// </summary>
        /// <param name="attribute">The <see cref="BoundAttributeDescriptorBuilder"/>.</param>
        /// <returns>Returns <c>true</c> if the property is child content, otherwise <c>false</c>.</returns>
        public static bool IsChildContentProperty(this BoundAttributeDescriptorBuilder attribute)
        {
            var key = ComponentMetadata.Component.ChildContentKey;

            return
                (attribute.Metadata.TryGetValue(key, out var value) &&
                 string.Equals(value, bool.TrueString));
        }
        /// <summary>
        /// Gets a value that indicates whether the property is a parameterized child content property. Properties are
        /// considered parameterized child content if they have the type <c>RenderFragment{T}</c> (for some T).
        /// </summary>
        /// <param name="attribute">The <see cref="BoundAttributeDescriptor"/>.</param>
        /// <returns>Returns <c>true</c> if the property is parameterized child content, otherwise <c>false</c>.</returns>
        public static bool IsParameterizedChildContentProperty(this BoundAttributeDescriptorBuilder attribute)
        {
            if (attribute == null)
            {
                throw new ArgumentNullException(nameof(attribute));
            }

            return(attribute.IsChildContentProperty() &&
                   !string.Equals(attribute.TypeName, BlazorApi.RenderFragment.FullTypeName, StringComparison.Ordinal));
        }
    public static BoundAttributeDescriptorBuilder AddMetadata(this BoundAttributeDescriptorBuilder builder, string key, string value)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.Metadata[key] = value;

        return(builder);
    }
    public static BoundAttributeDescriptorBuilder Name(this BoundAttributeDescriptorBuilder builder, string name)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.Name = name;

        return(builder);
    }
    public static BoundAttributeDescriptorBuilder Documentation(this BoundAttributeDescriptorBuilder builder, string documentation)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.Documentation = documentation;

        return(builder);
    }
    public static BoundAttributeDescriptorBuilder AsEnum(this BoundAttributeDescriptorBuilder builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.IsEnum = true;

        return(builder);
    }
    public static BoundAttributeDescriptorBuilder PropertyName(this BoundAttributeDescriptorBuilder builder, string propertyName)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.SetPropertyName(propertyName);

        return(builder);
    }
    public static BoundAttributeDescriptorBuilder AddDiagnostic(this BoundAttributeDescriptorBuilder builder, RazorDiagnostic diagnostic)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.Diagnostics.Add(diagnostic);

        return(builder);
    }
Ejemplo n.º 10
0
    public static bool IsDirectiveAttribute(this BoundAttributeDescriptorBuilder builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        return
            (builder.Metadata.TryGetValue(ComponentMetadata.Common.DirectiveAttribute, out var value) &&
             string.Equals(bool.TrueString, value));
    }
        /// <summary>
        /// Gets a value that indicates whether the property is a child content property. Properties are
        /// considered child content if they have the type <c>RenderFragment</c> or <c>RenderFragment{T}</c>.
        /// </summary>
        /// <param name="attribute">The <see cref="BoundAttributeDescriptorBuilder"/>.</param>
        /// <returns>Returns <c>true</c> if the property is child content, otherwise <c>false</c>.</returns>
        public static bool IsChildContentProperty(this BoundAttributeDescriptorBuilder attribute)
        {
            if (attribute == null)
            {
                throw new ArgumentNullException(nameof(attribute));
            }

            var key = BlazorMetadata.Component.ChildContentKey;
            return
                attribute.Metadata.TryGetValue(key, out var value) &&
                string.Equals(value, bool.TrueString);
        }
Ejemplo n.º 12
0
    public static string GetPropertyName(this BoundAttributeDescriptorBuilder builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        if (builder.Metadata.TryGetValue(TagHelperMetadata.Common.PropertyName, out var value))
        {
            return(value);
        }

        return(null);
    }
Ejemplo n.º 13
0
    public static void AsDictionary(
        this BoundAttributeDescriptorBuilder builder,
        string attributeNamePrefix,
        string valueTypeName)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.IsDictionary = true;
        builder.IndexerAttributeNamePrefix = attributeNamePrefix;
        builder.IndexerValueTypeName       = valueTypeName;
    }
Ejemplo n.º 14
0
    public static void SetPropertyName(this BoundAttributeDescriptorBuilder builder, string propertyName)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        if (propertyName == null)
        {
            throw new ArgumentNullException(nameof(propertyName));
        }

        builder.Metadata[TagHelperMetadata.Common.PropertyName] = propertyName;
    }
Ejemplo n.º 15
0
    private static void BuildBoundAttributeDescriptorFromPropertyInfo(
        BoundAttributeDescriptorBuilder builder,
        string name,
        PropertyInfo propertyInfo)
    {
        builder
        .Name(name)
        .PropertyName(propertyInfo.Name)
        .TypeName(propertyInfo.PropertyType.FullName);

        if (propertyInfo.PropertyType.GetTypeInfo().IsEnum)
        {
            builder.AsEnum();
        }
    }
        private static void ReadBoundAttribute(BoundAttributeDescriptorBuilder builder, JObject attribute, JsonSerializer serializer)
        {
            var descriptorKind           = attribute[nameof(BoundAttributeDescriptor.Kind)].Value <string>();
            var name                     = attribute[nameof(BoundAttributeDescriptor.Name)].Value <string>();
            var typeName                 = attribute[nameof(BoundAttributeDescriptor.TypeName)].Value <string>();
            var isEnum                   = attribute[nameof(BoundAttributeDescriptor.IsEnum)].Value <bool>();
            var indexerNamePrefix        = attribute[nameof(BoundAttributeDescriptor.IndexerNamePrefix)].Value <string>();
            var indexerTypeName          = attribute[nameof(BoundAttributeDescriptor.IndexerTypeName)].Value <string>();
            var documentation            = attribute[nameof(BoundAttributeDescriptor.Documentation)].Value <string>();
            var diagnostics              = attribute[nameof(BoundAttributeDescriptor.Diagnostics)].Value <JArray>();
            var metadata                 = attribute[nameof(BoundAttributeDescriptor.Metadata)].Value <JObject>();
            var boundAttributeParameters = attribute[nameof(BoundAttributeDescriptor.BoundAttributeParameters)].Value <JArray>();

            builder.Name          = name;
            builder.TypeName      = typeName;
            builder.Documentation = documentation;

            if (indexerNamePrefix != null)
            {
                builder.AsDictionary(indexerNamePrefix, indexerTypeName);
            }

            if (isEnum)
            {
                builder.IsEnum = true;
            }

            foreach (var diagnostic in diagnostics)
            {
                var diagnosticReader = diagnostic.CreateReader();
                var diagnosticObject = serializer.Deserialize <RazorDiagnostic>(diagnosticReader);
                builder.Diagnostics.Add(diagnosticObject);
            }

            var metadataReader = metadata.CreateReader();
            var metadataValue  = serializer.Deserialize <Dictionary <string, string> >(metadataReader);

            foreach (var item in metadataValue)
            {
                builder.Metadata[item.Key] = item.Value;
            }

            foreach (var boundAttributeParameter in boundAttributeParameters)
            {
                var parameter = boundAttributeParameter.Value <JObject>();
                builder.BindAttributeParameter(b => ReadBoundAttributeParameter(b, parameter, serializer));
            }
        }
        private static void ReadBoundAttributeParameters(JsonReader reader, BoundAttributeDescriptorBuilder builder)
        {
            if (!reader.Read())
            {
                return;
            }

            if (reader.TokenType != JsonToken.StartArray)
            {
                return;
            }

            do
            {
                ReadBoundAttributeParameter(reader, builder);
            } while (reader.TokenType != JsonToken.EndArray);
        }
Ejemplo n.º 18
0
    private static void ReadBoundAttribute(BoundAttributeDescriptorBuilder builder, JObject attribute, JsonSerializer serializer)
    {
        attribute["Kind"].Value <string>();
        string  name          = attribute["Name"].Value <string>();
        string  typeName      = attribute["TypeName"].Value <string>();
        bool    flag          = attribute["IsEnum"].Value <bool>();
        string  text          = attribute["IndexerNamePrefix"].Value <string>();
        string  valueTypeName = attribute["IndexerTypeName"].Value <string>();
        string  documentation = attribute["Documentation"].Value <string>();
        JArray  jArray        = attribute["Diagnostics"].Value <JArray>();
        JObject jObject       = attribute["Metadata"].Value <JObject>();
        JArray  jArray2       = attribute["BoundAttributeParameters"].Value <JArray>();

        builder.Name          = name;
        builder.TypeName      = typeName;
        builder.Documentation = documentation;
        if (text != null)
        {
            builder.AsDictionary(text, valueTypeName);
        }
        if (flag)
        {
            builder.IsEnum = true;
        }
        foreach (JToken item2 in jArray)
        {
            JsonReader      reader = item2.CreateReader();
            RazorDiagnostic item   = serializer.Deserialize <RazorDiagnostic>(reader);
            builder.Diagnostics.Add(item);
        }
        JsonReader reader2 = jObject.CreateReader();

        foreach (KeyValuePair <string, string> item3 in serializer.Deserialize <Dictionary <string, string> >(reader2))
        {
            builder.Metadata[item3.Key] = item3.Value;
        }
        foreach (JToken item4 in jArray2)
        {
            JObject parameter = item4.Value <JObject>();
            builder.BindAttributeParameter(delegate(BoundAttributeParameterDescriptorBuilder b)
            {
                ReadBoundAttributeParameter(b, parameter, serializer);
            });
        }
    }
    private void ConfigureDictionaryBoundAttribute(
        BoundAttributeDescriptorBuilder builder,
        IPropertySymbol property,
        INamedTypeSymbol containingType,
        AttributeData attributeNameAttribute,
        string attributeName,
        bool hasPublicSetter)
    {
        string dictionaryAttributePrefix    = null;
        var    dictionaryAttributePrefixSet = false;

        if (attributeNameAttribute != null)
        {
            foreach (var argument in attributeNameAttribute.NamedArguments)
            {
                if (argument.Key == TagHelperTypes.HtmlAttributeName.DictionaryAttributePrefix)
                {
                    dictionaryAttributePrefix    = (string)argument.Value.Value;
                    dictionaryAttributePrefixSet = true;
                    break;
                }
            }
        }

        var dictionaryArgumentTypes = GetDictionaryArgumentTypes(property);

        if (dictionaryArgumentTypes != null)
        {
            var prefix = dictionaryAttributePrefix;
            if (attributeNameAttribute == null || !dictionaryAttributePrefixSet)
            {
                prefix = attributeName + "-";
            }

            if (prefix != null)
            {
                var dictionaryValueType     = dictionaryArgumentTypes[1];
                var dictionaryValueTypeName = GetFullName(dictionaryValueType);
                builder.AsDictionary(prefix, dictionaryValueTypeName);
            }
        }

        var dictionaryKeyType = dictionaryArgumentTypes?[0];

        if (dictionaryKeyType?.SpecialType != SpecialType.System_String)
        {
            if (dictionaryAttributePrefix != null)
            {
                // DictionaryAttributePrefix is not supported unless associated with an
                // IDictionary<string, TValue> property.
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidAttributePrefixNotNull(GetFullName(containingType), property.Name);
                builder.Diagnostics.Add(diagnostic);
            }

            return;
        }
        else if (!hasPublicSetter && attributeNameAttribute != null && !dictionaryAttributePrefixSet)
        {
            // Must set DictionaryAttributePrefix when using HtmlAttributeNameAttribute with a dictionary property
            // that lacks a public setter.
            var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidAttributePrefixNull(GetFullName(containingType), property.Name);
            builder.Diagnostics.Add(diagnostic);

            return;
        }
    }
        private static void ReadBoundAttributeParameter(JsonReader reader, BoundAttributeDescriptorBuilder builder)
        {
            if (!reader.Read())
            {
                return;
            }

            if (reader.TokenType != JsonToken.StartObject)
            {
                return;
            }

            builder.BindAttributeParameter(parameter =>
            {
                reader.ReadProperties(propertyName =>
                {
                    switch (propertyName)
                    {
                    case nameof(BoundAttributeParameterDescriptor.Name):
                        if (reader.Read())
                        {
                            var name       = (string)reader.Value;
                            parameter.Name = name;
                        }
                        break;

                    case nameof(BoundAttributeParameterDescriptor.TypeName):
                        if (reader.Read())
                        {
                            var typeName       = (string)reader.Value;
                            parameter.TypeName = typeName;
                        }
                        break;

                    case nameof(BoundAttributeParameterDescriptor.IsEnum):
                        if (reader.Read())
                        {
                            var isEnum       = (bool)reader.Value;
                            parameter.IsEnum = isEnum;
                        }
                        break;

                    case nameof(BoundAttributeParameterDescriptor.Documentation):
                        if (reader.Read())
                        {
                            var documentation       = (string)reader.Value;
                            parameter.Documentation = documentation;
                        }
                        break;

                    case nameof(BoundAttributeParameterDescriptor.Metadata):
                        ReadMetadata(reader, parameter.Metadata);
                        break;

                    case nameof(BoundAttributeParameterDescriptor.Diagnostics):
                        ReadDiagnostics(reader, parameter.Diagnostics);
                        break;
                    }
                });
            });
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Gets a value that indicates whether the property is a parameterized child content property. Properties are
 /// considered parameterized child content if they have the type <c>RenderFragment{T}</c> (for some T).
 /// </summary>
 /// <param name="attribute">The <see cref="BoundAttributeDescriptor"/>.</param>
 /// <returns>Returns <c>true</c> if the property is parameterized child content, otherwise <c>false</c>.</returns>
 public static bool IsParameterizedChildContentProperty(this BoundAttributeDescriptorBuilder attribute)
 {
     return(attribute.IsChildContentProperty() &&
            !string.Equals(attribute.TypeName, ComponentsApi.RenderFragment.FullTypeName, StringComparison.Ordinal));
 }