示例#1
0
    public static TagHelperDescriptorBuilder BoundAttributeDescriptor(
        this TagHelperDescriptorBuilder builder,
        Action <BoundAttributeDescriptorBuilder> configure)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.BindAttribute(configure);

        return(builder);
    }
示例#2
0
        private void CreateTypeParameterProperty(TagHelperDescriptorBuilder builder, ITypeParameterSymbol typeParameter, bool cascade)
        {
            builder.BindAttribute(pb =>
            {
                pb.DisplayName = typeParameter.Name;
                pb.Name        = typeParameter.Name;
                pb.TypeName    = typeof(Type).FullName;
                pb.SetPropertyName(typeParameter.Name);

                pb.Metadata[ComponentMetadata.Component.TypeParameterKey]            = bool.TrueString;
                pb.Metadata[ComponentMetadata.Component.TypeParameterIsCascadingKey] = cascade.ToString();

                // Type constraints (like "Image" or "Foo") are stored indepenently of
                // things like constructor constraints and not null constraints in the
                // type parameter so we create a single string representation of all the constraints
                // here.
                var constraintString = new StringBuilder();
                if (typeParameter.ConstraintTypes.Any())
                {
                    constraintString.Append(string.Join(", ", typeParameter.ConstraintTypes.Select(t => t.Name)));
                }
                if (typeParameter.HasConstructorConstraint)
                {
                    constraintString.Append(", new()");
                }
                if (typeParameter.HasNotNullConstraint)
                {
                    constraintString.Append(", notnull");
                }
                if (typeParameter.HasReferenceTypeConstraint)
                {
                    constraintString.Append(", class");
                }
                if (typeParameter.HasUnmanagedTypeConstraint)
                {
                    constraintString.Append(", unmanaged");
                }
                if (typeParameter.HasValueTypeConstraint)
                {
                    constraintString.Append(", struct");
                }

                if (constraintString.Length > 0)
                {
                    constraintString.Insert(0, "where " + typeParameter.Name + " : ");
                    pb.Metadata[ComponentMetadata.Component.TypeParameterConstraintsKey] = constraintString.ToString();
                }

                pb.Documentation = string.Format(CultureInfo.InvariantCulture, ComponentResources.ComponentTypeParameter_Documentation, typeParameter.Name, builder.Name);
            });
        }
        private void CreateTypeParameterProperty(TagHelperDescriptorBuilder builder, ITypeSymbol typeParameter)
        {
            builder.BindAttribute(pb =>
            {
                pb.DisplayName = typeParameter.Name;
                pb.Name        = typeParameter.Name;
                pb.TypeName    = typeof(Type).FullName;
                pb.SetPropertyName(typeParameter.Name);

                pb.Metadata[BlazorMetadata.Component.TypeParameterKey] = bool.TrueString;

                pb.Documentation = string.Format(Resources.ComponentTypeParameter_Documentation, typeParameter.Name, builder.Name);
            });
        }
示例#4
0
        private void CreateTypeParameterProperty(TagHelperDescriptorBuilder builder, ITypeSymbol typeParameter, bool cascade)
        {
            builder.BindAttribute(pb =>
            {
                pb.DisplayName = typeParameter.Name;
                pb.Name        = typeParameter.Name;
                pb.TypeName    = typeof(Type).FullName;
                pb.SetPropertyName(typeParameter.Name);

                pb.Metadata[ComponentMetadata.Component.TypeParameterKey]            = bool.TrueString;
                pb.Metadata[ComponentMetadata.Component.TypeParameterIsCascadingKey] = cascade.ToString();

                pb.Documentation = string.Format(CultureInfo.InvariantCulture, ComponentResources.ComponentTypeParameter_Documentation, typeParameter.Name, builder.Name);
            });
        }
    private void AddBoundAttributes(INamedTypeSymbol type, TagHelperDescriptorBuilder builder)
    {
        var accessibleProperties = GetAccessibleProperties(type);

        foreach (var property in accessibleProperties)
        {
            if (ShouldSkipDescriptorCreation(property))
            {
                continue;
            }

            builder.BindAttribute(attributeBuilder =>
            {
                ConfigureBoundAttribute(attributeBuilder, property, type);
            });
        }
    }
示例#6
0
        private void CreateContextParameter(TagHelperDescriptorBuilder builder, string childContentName)
        {
            builder.BindAttribute(b =>
            {
                b.Name     = ComponentMetadata.ChildContent.ParameterAttributeName;
                b.TypeName = typeof(string).FullName;
                b.Metadata.Add(ComponentMetadata.Component.ChildContentParameterNameKey, bool.TrueString);

                if (childContentName == null)
                {
                    b.Documentation = ComponentResources.ChildContentParameterName_TopLevelDocumentation;
                }
                else
                {
                    b.Documentation = string.Format(ComponentResources.ChildContentParameterName_Documentation, childContentName);
                }
            });
        }
        private void CreateProperty(TagHelperDescriptorBuilder builder, IPropertySymbol property, PropertyKind kind)
        {
            builder.BindAttribute(pb =>
            {
                pb.Name     = property.Name;
                pb.TypeName = property.Type.ToDisplayString(FullNameTypeDisplayFormat);
                pb.SetPropertyName(property.Name);

                if (kind == PropertyKind.Enum)
                {
                    pb.IsEnum = true;
                }

                if (kind == PropertyKind.ChildContent)
                {
                    pb.Metadata.Add(BlazorMetadata.Component.ChildContentKey, bool.TrueString);
                }

                if (kind == PropertyKind.Delegate)
                {
                    pb.Metadata.Add(BlazorMetadata.Component.DelegateSignatureKey, bool.TrueString);
                }

                if (HasTypeParameter(property.Type))
                {
                    pb.Metadata.Add(BlazorMetadata.Component.GenericTypedKey, bool.TrueString);
                }

                var xml = property.GetDocumentationCommentXml();
                if (!string.IsNullOrEmpty(xml))
                {
                    pb.Documentation = xml;
                }
            });

            bool HasTypeParameter(ITypeSymbol type)
            {
                if (type is ITypeParameterSymbol)
                {
                    return(true);
                }

                // We need to check for cases like:
                // [Parameter] List<T> MyProperty { get; set; }
                // AND
                // [Parameter] List<string> MyProperty { get; set; }
                //
                // We need to inspect the type arguments to tell the difference between a property that
                // uses the containing class' type parameter(s) and a vanilla usage of generic types like
                // List<> and Dictionary<,>
                //
                // Since we need to handle cases like RenderFragment<List<T>>, this check must be recursive.
                if (type is INamedTypeSymbol namedType && namedType.IsGenericType)
                {
                    var typeArguments = namedType.TypeArguments;
                    for (var i = 0; i < typeArguments.Length; i++)
                    {
                        if (HasTypeParameter(typeArguments[i]))
                        {
                            return(true);
                        }
                    }

                    // Another case to handle - if the type being inspected is a nested type
                    // inside a generic containing class. The common usage for this would be a case
                    // where a generic templated component defines a 'context' nested class.
                    if (namedType.ContainingType != null && HasTypeParameter(namedType.ContainingType))
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
        private static void ReadBoundAttribute(JsonReader reader, TagHelperDescriptorBuilder builder)
        {
            if (!reader.Read())
            {
                return;
            }

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

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

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

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

                    case nameof(BoundAttributeDescriptor.IndexerNamePrefix):
                        if (reader.Read())
                        {
                            var indexerNamePrefix = (string)reader.Value;
                            if (indexerNamePrefix != null)
                            {
                                attribute.IsDictionary = true;
                                attribute.IndexerAttributeNamePrefix = indexerNamePrefix;
                            }
                        }
                        break;

                    case nameof(BoundAttributeDescriptor.IndexerTypeName):
                        if (reader.Read())
                        {
                            var indexerTypeName = (string)reader.Value;
                            if (indexerTypeName != null)
                            {
                                attribute.IsDictionary         = true;
                                attribute.IndexerValueTypeName = indexerTypeName;
                            }
                        }
                        break;

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

                    case nameof(BoundAttributeDescriptor.BoundAttributeParameters):
                        ReadBoundAttributeParameters(reader, attribute);
                        break;

                    case nameof(BoundAttributeDescriptor.Diagnostics):
                        ReadDiagnostics(reader, attribute.Diagnostics);
                        break;

                    case nameof(BoundAttributeDescriptor.Metadata):
                        ReadMetadata(reader, attribute.Metadata);
                        break;
                    }
                });
            });
        }
示例#9
0
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType != JsonToken.StartObject)
        {
            return(null);
        }
        JObject jObject       = JObject.Load(reader);
        string  kind          = jObject["Kind"].Value <string>();
        string  name          = jObject["Name"].Value <string>();
        string  assemblyName  = jObject["AssemblyName"].Value <string>();
        JArray  jArray        = jObject["TagMatchingRules"].Value <JArray>();
        JArray  jArray2       = jObject["BoundAttributes"].Value <JArray>();
        JArray  jArray3       = jObject["AllowedChildTags"].Value <JArray>();
        string  documentation = jObject["Documentation"].Value <string>();
        string  tagOutputHint = jObject["TagOutputHint"].Value <string>();
        bool    caseSensitive = jObject["CaseSensitive"].Value <bool>();
        JArray  jArray4       = jObject["Diagnostics"].Value <JArray>();
        JObject jObject2      = jObject["Metadata"].Value <JObject>();
        TagHelperDescriptorBuilder tagHelperDescriptorBuilder = TagHelperDescriptorBuilder.Create(kind, name, assemblyName);

        tagHelperDescriptorBuilder.Documentation = documentation;
        tagHelperDescriptorBuilder.TagOutputHint = tagOutputHint;
        tagHelperDescriptorBuilder.CaseSensitive = caseSensitive;
        foreach (JToken item2 in jArray)
        {
            JObject rule = item2.Value <JObject>();
            tagHelperDescriptorBuilder.TagMatchingRule(delegate(TagMatchingRuleDescriptorBuilder b)
            {
                ReadTagMatchingRule(b, rule, serializer);
            });
        }
        foreach (JToken item3 in jArray2)
        {
            JObject attribute = item3.Value <JObject>();
            tagHelperDescriptorBuilder.BindAttribute(delegate(BoundAttributeDescriptorBuilder b)
            {
                ReadBoundAttribute(b, attribute, serializer);
            });
        }
        foreach (JToken item4 in jArray3)
        {
            JObject tag = item4.Value <JObject>();
            tagHelperDescriptorBuilder.AllowChildTag(delegate(AllowedChildTagDescriptorBuilder childTagBuilder)
            {
                ReadAllowedChildTag(childTagBuilder, tag, serializer);
            });
        }
        foreach (JToken item5 in jArray4)
        {
            JsonReader      reader2 = item5.CreateReader();
            RazorDiagnostic item    = serializer.Deserialize <RazorDiagnostic>(reader2);
            tagHelperDescriptorBuilder.Diagnostics.Add(item);
        }
        JsonReader reader3 = jObject2.CreateReader();

        foreach (KeyValuePair <string, string> item6 in serializer.Deserialize <Dictionary <string, string> >(reader3))
        {
            tagHelperDescriptorBuilder.Metadata[item6.Key] = item6.Value;
        }
        return(tagHelperDescriptorBuilder.Build());
    }