示例#1
0
        public void GenericTypeNameRewriter_CanReplaceTypeParametersWithTypeArguments(string original, string expected)
        {
            // Arrange
            var visitor = new GenericTypeNameRewriter(new Dictionary <string, GenericTypeNameRewriter.Binding>()
            {
                { "TItem1", new GenericTypeNameRewriter.Binding()
                  {
                      Content = "Type1",
                  } },
                { "TItem2", new GenericTypeNameRewriter.Binding()
                  {
                      Content = "Type2",
                  } },
                { "TItem3", new GenericTypeNameRewriter.Binding()
                  {
                      Content = null,
                  } },
            });

            var parsed = SyntaxFactory.ParseTypeName(original);

            // Act
            var actual = visitor.Visit(parsed);

            // Assert
            Assert.Equal(expected, actual.ToString());
        }
示例#2
0
            private string RewriteTypeName(GenericTypeNameRewriter rewriter, string typeName)
            {
                var parsed    = SyntaxFactory.ParseTypeName(typeName);
                var rewritten = (TypeSyntax)rewriter.Visit(parsed);

                return(rewritten.ToFullString());
            }
示例#3
0
            private void Process(ComponentExtensionNode node)
            {
                // First collect all of the information we have about each type parameter
                var bindings = new Dictionary <string, GenericTypeNameRewriter.Binding>();

                foreach (var attribute in node.Component.GetTypeParameters())
                {
                    bindings.Add(attribute.Name, new GenericTypeNameRewriter.Binding()
                    {
                        Attribute = attribute,
                    });
                }

                foreach (var typeArgumentNode in node.TypeArguments)
                {
                    var binding = bindings[typeArgumentNode.TypeParameterName];
                    binding.Node    = typeArgumentNode;
                    binding.Content = GetContent(typeArgumentNode);
                }

                // Right now we don't have type inference, so all type arguments are required.
                var missing = new List <BoundAttributeDescriptor>();

                foreach (var binding in bindings)
                {
                    if (binding.Value.Node == null || string.IsNullOrWhiteSpace(binding.Value.Content))
                    {
                        missing.Add(binding.Value.Attribute);
                    }
                }

                if (missing.Count > 0)
                {
                    // We add our own error for this because its likely the user will see other errors due
                    // to incorrect codegen without the types. Our errors message will pretty clearly indicate
                    // what to do, whereas the other errors might be confusing.
                    node.Diagnostics.Add(BlazorDiagnosticFactory.Create_GenericComponentMissingTypeArgument(node.Source, node, missing));
                }

                var rewriter = new GenericTypeNameRewriter(bindings);

                // Rewrite the component type name
                node.TypeName = RewriteTypeName(rewriter, node.TypeName);

                foreach (var attribute in node.Attributes)
                {
                    if (attribute.BoundAttribute?.IsGenericTypedProperty() ?? false && attribute.TypeName != null)
                    {
                        // If we know the type name, then replace any generic type parameter inside it with
                        // the known types.
                        attribute.TypeName = RewriteTypeName(rewriter, attribute.TypeName);
                    }
                }

                foreach (var childContent in node.ChildContents)
                {
                    if (childContent.BoundAttribute?.IsGenericTypedProperty() ?? false && childContent.TypeName != null)
                    {
                        // If we know the type name, then replace any generic type parameter inside it with
                        // the known types.
                        childContent.TypeName = RewriteTypeName(rewriter, childContent.TypeName);
                    }
                }
            }