Exemplo n.º 1
0
        protected override MemberDeclarationSyntax CreateType()
        {
            return(SF.InterfaceDeclaration
                   (
                       CreateAttributes(),
                       SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)),
                       Symbols.GetNameSyntaxToken(Type),
                       null,
                       CreateBaseList(),
                       SF.List <TypeParameterConstraintClauseSyntax>(),
                       SF.List(CreateMembers())
                   ));

            SyntaxList <AttributeListSyntax> CreateAttributes()
            {
                TypeOfExpressionSyntax typeOfExpression          = SF.TypeOfExpression(Symbols.GetNameSyntax(Type));
                SyntaxToken            fullyQualifiedNameLiteral = SF.Literal(Type.FullyQualifiedName);

                return(SF.List(new[] {
                    SF.AttributeList(SF.SeparatedList(new[] {
                        SF.Attribute(
                            SF.ParseName("JsiiInterface"),
                            SF.ParseAttributeArgumentList($"({typeOfExpression}, {fullyQualifiedNameLiteral})")
                            )
                    }))
                }));
            }

            BaseListSyntax CreateBaseList()
            {
                IEnumerable <BaseTypeSyntax> baseTypes = GetBaseTypes();

                return(baseTypes?.Any() == true?SF.BaseList(SF.SeparatedList(baseTypes)) : null);

                IEnumerable <BaseTypeSyntax> GetBaseTypes()
                {
                    foreach (TypeReference interfaceReference in Type.Interfaces ?? Enumerable.Empty <TypeReference>())
                    {
                        Namespaces.Add(interfaceReference);
                        yield return(SF.SimpleBaseType(Symbols.GetTypeSyntax(interfaceReference)));
                    }
                }
            }

            IEnumerable <MemberDeclarationSyntax> CreateMembers()
            {
                return(CreateProperties().Concat(CreateMethods()));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Generates the class for the provided grain types.
        /// </summary>
        /// <param name="type">The grain interface type.</param>
        /// <param name="onEncounteredType">
        /// The callback invoked when a type is encountered.
        /// </param>
        /// <returns>
        /// The generated class.
        /// </returns>
        internal static TypeDeclarationSyntax GenerateClass(Type type, Action <Type> onEncounteredType)
        {
            var typeInfo     = type.GetTypeInfo();
            var genericTypes = typeInfo.IsGenericTypeDefinition
                                   ? typeInfo.GetGenericArguments().Select(_ => SF.TypeParameter(_.ToString())).ToArray()
                                   : new TypeParameterSyntax[0];

            var attributes = new List <AttributeSyntax>
            {
                CodeGeneratorCommon.GetGeneratedCodeAttributeSyntax(),
#if !NETSTANDARD
                SF.Attribute(typeof(ExcludeFromCodeCoverageAttribute).GetNameSyntax()),
#endif
                SF.Attribute(typeof(SerializerAttribute).GetNameSyntax())
                .AddArgumentListArguments(
                    SF.AttributeArgument(SF.TypeOfExpression(type.GetTypeSyntax(includeGenericParameters: false))))
            };

            var className = CodeGeneratorCommon.ClassPrefix + type.GetParseableName(GeneratedTypeNameOptions);
            var fields    = GetFields(type);

            // Mark each field type for generation
            foreach (var field in fields)
            {
                var fieldType = field.FieldInfo.FieldType;
                onEncounteredType(fieldType);
            }

            var members = new List <MemberDeclarationSyntax>(GenerateStaticFields(fields))
            {
                GenerateDeepCopierMethod(type, fields),
                GenerateSerializerMethod(type, fields),
                GenerateDeserializerMethod(type, fields),
            };

            var classDeclaration =
                SF.ClassDeclaration(className)
                .AddModifiers(SF.Token(SyntaxKind.InternalKeyword))
                .AddAttributeLists(SF.AttributeList().AddAttributes(attributes.ToArray()))
                .AddMembers(members.ToArray())
                .AddConstraintClauses(type.GetTypeConstraintSyntax());

            if (genericTypes.Length > 0)
            {
                classDeclaration = classDeclaration.AddTypeParameterListParameters(genericTypes);
            }

            return(classDeclaration);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Generates the class for the provided grain types.
        /// </summary>
        /// <param name="grainType">
        /// The grain interface type.
        /// </param>
        /// <param name="onEncounteredType">
        /// The callback which is invoked when a type is encountered.
        /// </param>
        /// <returns>
        /// The generated class.
        /// </returns>
        internal static TypeDeclarationSyntax GenerateClass(Type grainType, Action <Type> onEncounteredType)
        {
            var grainTypeInfo = grainType.GetTypeInfo();
            var genericTypes  = grainTypeInfo.IsGenericTypeDefinition
                                   ? grainTypeInfo.GetGenericArguments()
                                .Select(_ => SF.TypeParameter(_.ToString()))
                                .ToArray()
                                   : new TypeParameterSyntax[0];

            // Create the special marker attribute.
            var markerAttribute =
                SF.Attribute(typeof(GrainReferenceAttribute).GetNameSyntax())
                .AddArgumentListArguments(
                    SF.AttributeArgument(
                        SF.TypeOfExpression(grainType.GetTypeSyntax(includeGenericParameters: false))));
            var attributes = SF.AttributeList()
                             .AddAttributes(
                CodeGeneratorCommon.GetGeneratedCodeAttributeSyntax(),
                SF.Attribute(typeof(SerializableAttribute).GetNameSyntax()),
#if !NETSTANDARD_TODO
                //ExcludeFromCodeCoverageAttribute became an internal class in netstandard
                SF.Attribute(typeof(ExcludeFromCodeCoverageAttribute).GetNameSyntax()),
#endif
                markerAttribute);

            var className        = CodeGeneratorCommon.ClassPrefix + TypeUtils.GetSuitableClassName(grainType) + ClassSuffix;
            var classDeclaration =
                SF.ClassDeclaration(className)
                .AddModifiers(SF.Token(SyntaxKind.InternalKeyword))
                .AddBaseListTypes(
                    SF.SimpleBaseType(typeof(GrainReference).GetTypeSyntax()),
                    SF.SimpleBaseType(grainType.GetTypeSyntax()))
                .AddConstraintClauses(grainType.GetTypeConstraintSyntax())
                .AddMembers(GenerateConstructors(className))
                .AddMembers(
                    GenerateInterfaceIdProperty(grainType),
                    GenerateInterfaceNameProperty(grainType),
                    GenerateIsCompatibleMethod(grainType),
                    GenerateGetMethodNameMethod(grainType))
                .AddMembers(GenerateInvokeMethods(grainType, onEncounteredType))
                .AddAttributeLists(attributes);

            if (genericTypes.Length > 0)
            {
                classDeclaration = classDeclaration.AddTypeParameterListParameters(genericTypes);
            }

            return(classDeclaration);
        }
Exemplo n.º 4
0
 public static SyntaxList <AttributeListSyntax> GenerateStructLayoutAttributes()
 {
     return(SF.SingletonList(
                SF.AttributeList(
                    SF.SingletonSeparatedList(
                        SF.Attribute(SF.IdentifierName("StructLayout"))
                        .WithArgumentList(
                            SF.AttributeArgumentList(
                                SF.SingletonSeparatedList(
                                    SF.AttributeArgument(
                                        SF.MemberAccessExpression(
                                            SK.SimpleMemberAccessExpression,
                                            SF.IdentifierName("LayoutKind"),
                                            SF.IdentifierName("Explicit"))))))))));
 }
Exemplo n.º 5
0
        public static AttributeSyntax GenAttribute(string name, string args)
        {
            var attribure = SF.Attribute(SF.IdentifierName(name));

            if (args != null)
            {
                attribure = attribure.WithArgumentList(
                    SF.AttributeArgumentList(
                        SF.SingletonSeparatedList(
                            SF.AttributeArgument(
                                SF.ParseExpression(args)))));
            }

            return(attribure);
        }
Exemplo n.º 6
0
        protected override MemberDeclarationSyntax CreateType()
        {
            return(SF.ClassDeclaration
                   (
                       CreateAttributes(),
                       SF.TokenList(SF.Token(SyntaxKind.InternalKeyword)),
                       GetProxyTypeNameSyntax(),
                       null,
                       CreateBaseList(),
                       SF.List <TypeParameterConstraintClauseSyntax>(),
                       SF.List(CreateMembers())
                   ));

            SyntaxList <AttributeListSyntax> CreateAttributes()
            {
                TypeOfExpressionSyntax typeOfExpression          = SF.TypeOfExpression(Symbols.GetNameSyntax(Type));
                SyntaxToken            fullyQualifiedNameLiteral = SF.Literal(Type.FullyQualifiedName);

                return(SF.List(new[] {
                    SF.AttributeList(SF.SeparatedList(new[] {
                        SF.Attribute(
                            SF.ParseName("JsiiInterfaceProxy"),
                            SF.ParseAttributeArgumentList($"({typeOfExpression}, {fullyQualifiedNameLiteral})")
                            )
                    }))
                }));
            }

            BaseListSyntax CreateBaseList()
            {
                return(SF.BaseList(SF.SeparatedList(GetBaseTypes())));

                IEnumerable <BaseTypeSyntax> GetBaseTypes()
                {
                    yield return(SF.SimpleBaseType(SF.ParseTypeName("DeputyBase")));

                    Namespaces.Add(Type);
                    yield return(SF.SimpleBaseType(Symbols.GetNameSyntax(Type, disambiguate: true)));
                }
            }

            IEnumerable <MemberDeclarationSyntax> CreateMembers()
            {
                return(CreateConstructors()
                       .Concat(CreateProperties())
                       .Concat(CreateMethods()));
            }
        }
        private SyntaxList <AttributeListSyntax> CreateSerializationAttribute(SymbolData symbol)
        {
            string requiredValueName;

            if (symbol.IsRequired)
            {
                requiredValueName = (symbol.isNullable) ? "AllowNull" : "Always";
            }
            else
            {
                requiredValueName = "Default";
            }

            Func <string, string, string, AttributeArgumentSyntax> createAttr =
                (lhs, expr, name) =>
            {
                // lhs = expr.name
                return(SF.AttributeArgument(
                           SF.MemberAccessExpression(
                               SyntaxKind.SimpleMemberAccessExpression,
                               SF.IdentifierName(expr),
                               SF.Token(SyntaxKind.DotToken),
                               SF.IdentifierName(name)))
                       .WithNameEquals(
                           SF.NameEquals(SF.IdentifierName(lhs))));
            };

            var attributes = SF.SeparatedList(new[]
            {
                // Required = Required.[requiredValueName]
                createAttr("Required", "Required", requiredValueName),
            });

            if (requiredValueName == "Default" && !symbol.isNullable)
            {
                // NullValueHandling = NullValueHandling.Ignore
                attributes = attributes.Add(
                    createAttr("NullValueHandling", "NullValueHandling", "Ignore"));
            }

            return(SF.SingletonList(
                       SF.AttributeList(
                           SF.SingletonSeparatedList(
                               SF.Attribute(SF.IdentifierName("JsonProperty"))
                               .WithArgumentList(
                                   SF.AttributeArgumentList(attributes))))));
        }
Exemplo n.º 8
0
        SeparatedSyntaxList <EnumMemberDeclarationSyntax> CreateValues()
        {
            return(SF.SeparatedList(Type.Members.Select(GetMemberDeclaration)));

            EnumMemberDeclarationSyntax GetMemberDeclaration(EnumMember member)
            {
                EnumMemberDeclarationSyntax declaration = SF.EnumMemberDeclaration
                                                          (
                    SF.List(GetAttributeLists()),
                    Symbols.GetNameSyntaxToken(Type, member),
                    null
                                                          );

                if (member.Docs != null)
                {
                    DocCommentGeneratorBase <EnumMember> generator = new EnumMemberDocCommentGenerator(member);
                    SyntaxTriviaList trivia = SF.TriviaList(generator.CreateDocComment());

                    declaration = declaration.WithLeadingTrivia(trivia);
                }

                return(declaration);

                IEnumerable <AttributeListSyntax> GetAttributeLists()
                {
                    yield return(SF.AttributeList(SF.SingletonSeparatedList(
                                                      SF.Attribute(
                                                          SF.ParseName("JsiiEnumMember"),
                                                          SF.ParseAttributeArgumentList($"(name: \"{member.Name}\")")
                                                          )
                                                      )));

                    if (member.Docs?.Stability == Stability.Deprecated)
                    {
                        var argument = member.Docs?.Deprecated != null?SF.Literal(member.Docs?.Deprecated).ToString() : "";

                        yield return(SF.AttributeList(SF.SingletonSeparatedList(
                                                          SF.Attribute(
                                                              SF.ParseName("System.Obsolete"),
                                                              SF.ParseAttributeArgumentList($"({argument})")
                                                              )
                                                          )));
                    }
                }
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Yields the CompiledHandlebars Class Declaration ClassDeclaration
 /// public static class CompiledHandlebarsTemplate<TViewModel> {}
 /// </summary>
 internal static ClassDeclarationSyntax CompiledHandlebarsClassDeclaration(string templateName, string attribute)
 {
     return
         (SF.ClassDeclaration(
              new SyntaxList <AttributeListSyntax>().Add(
                  SF.AttributeList(new SeparatedSyntaxList <AttributeSyntax>().Add(
                                       SF.Attribute(SF.ParseName(attribute)))
                                   )),
              SF.TokenList(
                  SF.Token(SyntaxKind.PublicKeyword),
                  SF.Token(SyntaxKind.StaticKeyword)),
              SF.Identifier(templateName),
              default(TypeParameterListSyntax),
              default(BaseListSyntax),
              default(SyntaxList <TypeParameterConstraintClauseSyntax>),
              default(SyntaxList <MemberDeclarationSyntax>)
              ));
 }
Exemplo n.º 10
0
        private static MemberDeclarationSyntax GenerateSerializerMethod(Type type, List <FieldInfoMember> fields)
        {
            Expression <Action> serializeInner =
                () =>
                SerializationManager.SerializeInner(default(object), default(ISerializationContext), default(Type));
            var contextParameter = SF.IdentifierName("context");

            var body = new List <StatementSyntax>
            {
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(type.GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("input")
                        .WithInitializer(
                            SF.EqualsValueClause(
                                SF.CastExpression(type.GetTypeSyntax(), SF.IdentifierName("untypedInput"))))))
            };

            var inputExpression = SF.IdentifierName("input");

            // Serialize all members.
            foreach (var field in fields)
            {
                body.Add(
                    SF.ExpressionStatement(
                        serializeInner.Invoke()
                        .AddArgumentListArguments(
                            SF.Argument(field.GetGetter(inputExpression, forceAvoidCopy: true)),
                            SF.Argument(contextParameter),
                            SF.Argument(SF.TypeOfExpression(field.FieldInfo.FieldType.GetTypeSyntax())))));
            }

            return
                (SF.MethodDeclaration(typeof(void).GetTypeSyntax(), "Serializer")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("untypedInput")).WithType(typeof(object).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("context")).WithType(typeof(ISerializationContext).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("expected")).WithType(typeof(Type).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList()
                     .AddAttributes(SF.Attribute(typeof(SerializerMethodAttribute).GetNameSyntax()))));
        }
Exemplo n.º 11
0
        private async Task <Document> AddAnnotation(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var annotationsHttp   = root.FindToken(diagnostic.Location.SourceSpan.Start).Parent as AttributeListSyntax;
            var methodDeclaration = annotationsHttp.Parent as MethodDeclarationSyntax;

            var annotationValidate = SF.AttributeList()
                                     .AddAttributes(SF.Attribute(SF.IdentifierName("ValidateAntiForgeryToken")))
                                     .WithLeadingTrivia(CodeFixUtil.KeepLastLine(annotationsHttp.GetLeadingTrivia()));

            var nodes = new List <SyntaxNode>();

            nodes.Add(annotationValidate);

            var newRoot = root.InsertNodesAfter(annotationsHttp, nodes);

            return(document.WithSyntaxRoot(newRoot));
        }
Exemplo n.º 12
0
        SyntaxList <AttributeListSyntax> GetAttributeLists()
        {
            return(SF.List(new[] { SF.AttributeList(SF.SeparatedList(GetAttributes())) }));

            IEnumerable <AttributeSyntax> GetAttributes()
            {
                SyntaxToken nameLiteral     = SF.Literal(Property.Name);
                SyntaxToken typeJsonLiteral = SF.Literal(JsonConvert.SerializeObject(Property.Type));
                SyntaxToken trueLiteral     = SF.Token(SyntaxKind.TrueKeyword);

                string argumentList = IsOverride ?
                                      $"({nameLiteral}, {typeJsonLiteral}, {trueLiteral})" :
                                      $"({nameLiteral}, {typeJsonLiteral})";

                yield return(SF.Attribute(
                                 SF.ParseName("JsiiProperty"),
                                 SF.ParseAttributeArgumentList(argumentList)
                                 ));
            }
        }
Exemplo n.º 13
0
        public static CompilationUnitSyntax AddGeneratedCodeAttribute(GeneratedSyntax generatedSyntax)
        {
            var codeGenTargetAttributes =
                SF.AttributeList()
                .AddAttributes(
                    generatedSyntax.SourceAssemblies.Select(
                        asm =>
                        SF.Attribute(typeof(OrleansCodeGenerationTargetAttribute).GetNameSyntax())
                        .AddArgumentListArguments(
                            SF.AttributeArgument(asm.GetName().FullName.GetLiteralExpression()))).ToArray())
                .WithTarget(SF.AttributeTargetSpecifier(SF.Token(SyntaxKind.AssemblyKeyword)));
            var generatedCodeAttribute =
                SF.AttributeList()
                .AddAttributes(
                    SF.Attribute(typeof(GeneratedCodeAttribute).GetNameSyntax())
                    .AddArgumentListArguments(
                        SF.AttributeArgument("Orleans-CodeGenerator".GetLiteralExpression()),
                        SF.AttributeArgument(RuntimeVersion.FileVersion.GetLiteralExpression())))
                .WithTarget(SF.AttributeTargetSpecifier(SF.Token(SyntaxKind.AssemblyKeyword)));

            return(generatedSyntax.Syntax.AddAttributeLists(generatedCodeAttribute, codeGenTargetAttributes));
        }
Exemplo n.º 14
0
        SyntaxList <AttributeListSyntax> GetAttributeLists()
        {
            return(SF.List(GetAttributesLists()));

            IEnumerable <AttributeListSyntax> GetAttributesLists()
            {
                SyntaxToken nameLiteral     = SF.Literal(Property.Name);
                SyntaxToken typeJsonLiteral = SF.Literal(JsonConvert.SerializeObject(Property.Type, SerializerSettings));
                SyntaxToken trueLiteral     = SF.Token(SyntaxKind.TrueKeyword);

                string argumentList = $"name: {nameLiteral}, typeJson: {typeJsonLiteral}";

                if (Property.IsOptional)
                {
                    argumentList += $", isOptional: {trueLiteral}";
                }
                if (IsOverride)
                {
                    argumentList += $", isOverride: {trueLiteral}";
                }

                yield return(SF.AttributeList(SF.SingletonSeparatedList(SF.Attribute(
                                                                            SF.ParseName("JsiiProperty"),
                                                                            SF.ParseAttributeArgumentList($"({argumentList})")
                                                                            ))));

                if (Property.Docs?.Stability == Stability.Deprecated)
                {
                    var argument = Property.Docs?.Deprecated != null?SF.Literal(Property.Docs?.Deprecated).ToString() : "";

                    yield return(SF.AttributeList(SF.SingletonSeparatedList(SF.Attribute(
                                                                                SF.ParseName("System.Obsolete"),
                                                                                SF.ParseAttributeArgumentList($"({argument})")
                                                                                ))));
                }
            }
        }
        private ClassDeclarationSyntax CreateClass(SymbolData symbol)
        {
            var className = symbol.Name.ToClassName();
            var node      = SF.ClassDeclaration(className)
                            .AddModifiers(SF.Token(SyntaxKind.PublicKeyword));

            if (_options.IsJsonSerializable)
            {
                node = node.WithAttributeLists(
                    SF.SingletonList(
                        SF.AttributeList(
                            SF.SingletonSeparatedList(
                                SF.Attribute(SF.IdentifierName("JsonObject"))))));
            }

            if (!string.IsNullOrEmpty(symbol.Summary))
            {
                var comment = new DocumentComment()
                {
                    Summary = symbol.Summary
                };
                node = node.WithLeadingTrivia(comment.ConstructTriviaList());
            }

            var props = new List <MemberDeclarationSyntax>();

            foreach (var member in symbol.Members)
            {
                props.Add(ConstructImpl(member) as MemberDeclarationSyntax);
                if (member.TypeName == "object")
                {
                    var childSymbol = member.CreateInstanceSymbol();
                    props.Add(CreateProperty(childSymbol));
                }
            }
            return(node.AddMembers(props.ToArray()));
        }
Exemplo n.º 16
0
        SyntaxList <AttributeListSyntax> GetAttributeLists()
        {
            return(SF.List(new[] { SF.AttributeList(SF.SeparatedList(GetAttributes())) }));

            IEnumerable <AttributeSyntax> GetAttributes()
            {
                SyntaxToken nameLiteral        = SF.Literal(Method.Name);
                SyntaxToken returnsJsonLiteral = Method.Returns == null?
                                                 SF.Token(SyntaxKind.NullKeyword) :
                                                     SF.Literal(JsonConvert.SerializeObject(Method.Returns));

                SyntaxToken parametersJsonLiteral = Method.GetParametersJsonSyntaxToken();
                SyntaxToken trueLiteral           = SF.Token(SyntaxKind.TrueKeyword);

                string argumentList = IsOverride ?
                                      $"({nameLiteral}, {returnsJsonLiteral}, {parametersJsonLiteral}, {trueLiteral})" :
                                      $"({nameLiteral}, {returnsJsonLiteral}, {parametersJsonLiteral})";

                yield return(SF.Attribute(
                                 SF.ParseName("JsiiMethod"),
                                 SF.ParseAttributeArgumentList(argumentList)
                                 ));
            }
        }
Exemplo n.º 17
0
        protected override MemberDeclarationSyntax CreateType()
        {
            return(SF.InterfaceDeclaration
                   (
                       CreateAttributes(),
                       SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)),
                       Symbols.GetNameSyntaxToken(Type),
                       null,
                       CreateBaseList(),
                       SF.List <TypeParameterConstraintClauseSyntax>(),
                       SF.List(CreateMembers())
                   ));

            SyntaxList <AttributeListSyntax> CreateAttributes()
            {
                TypeOfExpressionSyntax typeOfExpression          = SF.TypeOfExpression(Symbols.GetNameSyntax(Type));
                SyntaxToken            fullyQualifiedNameLiteral = SF.Literal(Type.FullyQualifiedName);

                return(SF.List(GetAttributeLists()));

                IEnumerable <AttributeListSyntax> GetAttributeLists()
                {
                    yield return(SF.AttributeList(SF.SeparatedList(new[] {
                        SF.Attribute(
                            SF.ParseName("JsiiInterface"),
                            SF.ParseAttributeArgumentList($"(nativeType: {typeOfExpression}, fullyQualifiedName: {fullyQualifiedNameLiteral})")
                            )
                    })));

                    if (Type.Docs?.Stability == Stability.Deprecated)
                    {
                        var argument = Type.Docs?.Deprecated != null?SF.Literal(Type.Docs?.Deprecated).ToString() : "";

                        yield return(SF.AttributeList(SF.SeparatedList(new[] {
                            SF.Attribute(
                                SF.ParseName("System.Obsolete"),
                                SF.ParseAttributeArgumentList($"({argument})")
                                )
                        })));
                    }
                }
            }

            BaseListSyntax CreateBaseList()
            {
                IEnumerable <BaseTypeSyntax> baseTypes = GetBaseTypes();

                return(baseTypes?.Any() ?? false?SF.BaseList(SF.SeparatedList(baseTypes)) : null);

                IEnumerable <BaseTypeSyntax> GetBaseTypes()
                {
                    foreach (string interfaceReference in Type.Interfaces ?? Enumerable.Empty <string>())
                    {
                        Namespaces.Add(Symbols.GetTypeFromFullyQualifiedName(interfaceReference));
                        yield return(SF.SimpleBaseType(Symbols.GetNameSyntax(interfaceReference, disambiguate: true)));
                    }
                }
            }

            IEnumerable <MemberDeclarationSyntax> CreateMembers()
            {
                return(CreateProperties().Concat(CreateMethods()));
            }
        }
Exemplo n.º 18
0
        protected override MemberDeclarationSyntax CreateType()
        {
            return(SF.ClassDeclaration
                   (
                       CreateAttributes(),
                       SF.TokenList(
                           SF.Token(SyntaxKind.InternalKeyword),
                           SF.Token(SyntaxKind.SealedKeyword)),
                       GetProxyTypeNameSyntax(),
                       null,
                       CreateBaseList(),
                       SF.List <TypeParameterConstraintClauseSyntax>(),
                       SF.List(CreateMembers())
                   ));

            SyntaxList <AttributeListSyntax> CreateAttributes()
            {
                var typeOfExpression          = SF.TypeOfExpression(Symbols.GetNameSyntax(Type));
                var fullyQualifiedNameLiteral = SF.Literal(Type.FullyQualifiedName);

                return(SF.List(GetAttributeLists()));

                IEnumerable <AttributeListSyntax> GetAttributeLists()
                {
                    yield return(SF.AttributeList(SF.SingletonSeparatedList(
                                                      SF.Attribute(
                                                          SF.ParseName("JsiiTypeProxy"),
                                                          SF.ParseAttributeArgumentList($"(nativeType: {typeOfExpression}, fullyQualifiedName: {fullyQualifiedNameLiteral})")
                                                          )
                                                      )));

                    if (Type.Docs?.Stability == Stability.Deprecated)
                    {
                        var argument = Type.Docs?.Deprecated != null?SF.Literal(Type.Docs?.Deprecated).ToString() : "";

                        yield return(SF.AttributeList(SF.SingletonSeparatedList(
                                                          SF.Attribute(
                                                              SF.ParseName("System.Obsolete"),
                                                              SF.ParseAttributeArgumentList($"({argument})")
                                                              )
                                                          )));
                    }
                }
            }

            BaseListSyntax CreateBaseList()
            {
                return(SF.BaseList(SF.SeparatedList(GetBaseTypes())));

                IEnumerable <BaseTypeSyntax> GetBaseTypes()
                {
                    if (Type is InterfaceType)
                    {
                        yield return(SF.SimpleBaseType(SF.ParseTypeName("DeputyBase")));
                    }

                    Namespaces.Add(Type);
                    yield return(SF.SimpleBaseType(Symbols.GetNameSyntax(Type, disambiguate: true)));
                }
            }

            IEnumerable <MemberDeclarationSyntax> CreateMembers()
            {
                return(CreateConstructors()
                       .Concat(CreateProperties())
                       .Concat(CreateMethods()));
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Returns syntax for the deep copier method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deep copier method.</returns>
        private static MemberDeclarationSyntax GenerateDeepCopierMethod(Type type, List <FieldInfoMember> fields)
        {
            var originalVariable = SF.IdentifierName("original");
            var inputVariable    = SF.IdentifierName("input");
            var resultVariable   = SF.IdentifierName("result");

            var body = new List <StatementSyntax>();

            if (type.GetTypeInfo().GetCustomAttribute <ImmutableAttribute>() != null)
            {
                // Immutable types do not require copying.
                var typeName = type.GetParseableName(new TypeFormattingOptions(includeGlobal: false));
                var comment  = SF.Comment($"// No deep copy required since {typeName} is marked with the [Immutable] attribute.");
                body.Add(SF.ReturnStatement(originalVariable).WithLeadingTrivia(comment));
            }
            else
            {
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("input")
                            .WithInitializer(
                                SF.EqualsValueClause(
                                    SF.ParenthesizedExpression(
                                        SF.CastExpression(type.GetTypeSyntax(), originalVariable)))))));
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("result")
                            .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type))))));

                // Record this serialization.
                Expression <Action <ICopyContext> > recordObject =
                    ctx => ctx.RecordCopy(default(object), default(object));
                var context = SF.IdentifierName("context");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(context)
                        .AddArgumentListArguments(SF.Argument(originalVariable), SF.Argument(resultVariable))));

                // Copy all members from the input to the result.
                foreach (var field in fields)
                {
                    body.Add(SF.ExpressionStatement(field.GetSetter(resultVariable, field.GetGetter(inputVariable, context))));
                }

                body.Add(SF.ReturnStatement(resultVariable));
            }

            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "DeepCopier")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("original")).WithType(typeof(object).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("context")).WithType(typeof(ICopyContext).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList().AddAttributes(SF.Attribute(typeof(CopierMethodAttribute).GetNameSyntax()))));
        }
Exemplo n.º 20
0
 private static AttributeSyntax Attribute(string attributeName)
 {
     return(SF.Attribute(SF.IdentifierName(attributeName)));
 }
Exemplo n.º 21
0
        protected override MemberDeclarationSyntax CreateType()
        {
            return(SF.ClassDeclaration
                   (
                       CreateAttributes(),
                       CreateModifiers(),
                       Symbols.GetNameSyntaxToken(Type),
                       null,
                       CreateBaseList(),
                       SF.List <TypeParameterConstraintClauseSyntax>(),
                       SF.List(CreateMembers())
                   ));

            SyntaxList <AttributeListSyntax> CreateAttributes()
            {
                TypeOfExpressionSyntax typeOfExpression          = SF.TypeOfExpression(Symbols.GetNameSyntax(Type));
                SyntaxToken            fullyQualifiedNameLiteral = SF.Literal(Type.FullyQualifiedName);
                SyntaxToken            parametersJsonLiteral     = Type.Initializer.GetParametersJsonSyntaxToken();

                return(SF.List(new[] {
                    SF.AttributeList(SF.SeparatedList(new[] {
                        SF.Attribute(
                            SF.ParseName("JsiiClass"),
                            SF.ParseAttributeArgumentList($"({typeOfExpression}, {fullyQualifiedNameLiteral}, {parametersJsonLiteral})")
                            )
                    }))
                }));
            }

            SyntaxTokenList CreateModifiers()
            {
                SyntaxTokenList modifierList = SF.TokenList(SF.Token(SyntaxKind.PublicKeyword));

                if (Type.IsAbstract)
                {
                    modifierList = modifierList.Add(SF.Token(SyntaxKind.AbstractKeyword));
                }

                return(modifierList);
            }

            BaseListSyntax CreateBaseList()
            {
                return(SF.BaseList(SF.SeparatedList(GetBaseTypes())));

                IEnumerable <BaseTypeSyntax> GetBaseTypes()
                {
                    if (Type.Base == null)
                    {
                        yield return(SF.SimpleBaseType(SF.ParseTypeName("DeputyBase")));
                    }
                    else
                    {
                        Namespaces.Add(Type.Base);
                        yield return(SF.SimpleBaseType(Symbols.GetNameSyntax(Type.Base.FullyQualifiedName, disambiguate: true)));
                    }

                    if (Type.Interfaces == null)
                    {
                        yield break;
                    }

                    foreach (TypeReference interfaceReference in Type.Interfaces)
                    {
                        Namespaces.Add(interfaceReference);
                        yield return(SF.SimpleBaseType(Symbols.GetNameSyntax(interfaceReference.FullyQualifiedName, disambiguate: true)));
                    }
                }
            }

            IEnumerable <MemberDeclarationSyntax> CreateMembers()
            {
                return(CreateConstructors()
                       .Concat(CreateProperties())
                       .Concat(CreateMethods()));
            }
        }
Exemplo n.º 22
0
        void Save(string packageOutputRoot, ISymbolMap symbols, Assembly assembly, string tarballFileName, string jsiiFileName)
        {
            if (assembly.Docs != null)
            {
                // TODO: Use Microsoft.Extensions.Logging instead of Console.Error.
                Console.Error.WriteLine("Warning: Ignoring documentation comment on assembly ${assembly.Name}. Assembly-level documentation comments are not supported for .NET");
            }

            SaveProjectFile();
            SaveAssemblyInfo(assembly.Name, assembly.Version, tarballFileName);

            foreach (Type type in assembly.Types?.Values ?? Enumerable.Empty <Type>())
            {
                SaveType(type);
            }

            void SaveProjectFile()
            {
                XElement project =
                    new XElement("Project",
                                 new XAttribute("Sdk", "Microsoft.NET.Sdk"),
                                 new XElement("PropertyGroup",
                                              new XElement("TargetFramework", "netstandard2.0"),
                                              new XElement("GeneratePackageOnBuild", true),
                                              new XElement("Authors", _authors),
                                              new XElement("Company", _company),
                                              new XElement("PackageVersion", assembly.Version)
                                              ),
                                 new XElement("ItemGroup",
                                              new XElement("EmbeddedResource",
                                                           new XAttribute("Include", tarballFileName)
                                                           )
                                              ),
                                 new XElement("ItemGroup",
                                              new XElement("PackageReference",
                                                           new XAttribute("Include", "Amazon.JSII.Runtime"),
                                                           new XAttribute("Version", JsiiVersion.Version)
                                                           ),
                                              GetDependencies()
                                              .Distinct()
                                              .Select(d => new { Package = symbols.GetAssemblyName(d.Key), Version = d.Value.Version })
                                              .Select(d =>
                                                      new XElement("PackageReference",
                                                                   new XAttribute("Include", d.Package),
                                                                   new XAttribute("Version", d.Version)
                                                                   )
                                                      )
                                              )
                                 );

                if (!_fileSystem.Directory.Exists(packageOutputRoot))
                {
                    _fileSystem.Directory.CreateDirectory(packageOutputRoot);
                }

                // Save to StringBuilder instead of directly to path, so that we can
                // redirect the output through the filesystem shim. Project files are
                // small, so this shouldn't be a memory hog.
                StringBuilder     builder  = new StringBuilder();
                XmlWriterSettings settings = new XmlWriterSettings
                {
                    // Visual Studio omits the XML declaration when creating project files, so we do too.
                    OmitXmlDeclaration = true,
                    // Visual Studio indents project files (they are often edited by hand), so we do too.
                    Indent = true,
                };

                using (XmlWriter writer = XmlWriter.Create(builder, settings))
                {
                    project.Save(writer);
                }

                string csProjPath = Path.Combine(packageOutputRoot, $"{assembly.GetNativeName()}.csproj");

                _fileSystem.File.WriteAllText(csProjPath, builder.ToString());

                IEnumerable <KeyValuePair <string, PackageVersion> > GetDependencies()
                {
                    foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(assembly))
                    {
                        yield return(dependency);
                    }

                    IEnumerable <KeyValuePair <string, PackageVersion> > GetDependenciesCore(DependencyRoot root)
                    {
                        if (root.Dependencies == null)
                        {
                            yield break;
                        }
                        foreach (var kvp in root.Dependencies)
                        {
                            yield return(kvp);

                            foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(kvp.Value))
                            {
                                yield return(dependency);
                            }
                        }
                    }
                }
            }

            void SaveAssemblyInfo(string name, string version, string tarball)
            {
                SyntaxTree assemblyInfo = SF.SyntaxTree(
                    SF.CompilationUnit(
                        SF.List <ExternAliasDirectiveSyntax>(),
                        SF.List(new[] {
                    SF.UsingDirective(SF.ParseName("Amazon.JSII.Runtime.Deputy"))
                }),
                        SF.List(new[] {
                    SF.AttributeList(
                        SF.AttributeTargetSpecifier(
                            SF.Identifier("assembly"),
                            SF.Token(SyntaxKind.ColonToken)
                            ),
                        SF.SeparatedList(new[] {
                        SF.Attribute(
                            SF.ParseName("JsiiAssembly"),
                            SF.ParseAttributeArgumentList($"({SF.Literal(name)}, {SF.Literal(version)}, {SF.Literal(tarball)})")
                            )
                    })
                        )
                }),
                        SF.List <MemberDeclarationSyntax>()
                        ).NormalizeWhitespace(elasticTrivia: true)
                    );

                string assemblyInfoPath = Path.Combine(packageOutputRoot, "AssemblyInfo.cs");

                _fileSystem.File.WriteAllText(assemblyInfoPath, assemblyInfo.ToString());
            }

            void SaveType(Type type)
            {
                string packageName = Path.GetFileName(packageOutputRoot);
                string @namespace  = symbols.GetNamespace(type);

                if (@namespace.StartsWith(packageName))
                {
                    @namespace = @namespace.Substring(packageName.Length).TrimStart('.');
                }

                string directory = Path.Combine(packageOutputRoot, Path.Combine(@namespace.Split('.')));

                switch (type.Kind)
                {
                case TypeKind.Class:
                    SaveTypeFile($"{symbols.GetName(type)}.cs", new ClassGenerator(assembly.Name, (ClassType)type, symbols).CreateSyntaxTree());
                    return;

                case TypeKind.Enum:
                    SaveTypeFile($"{symbols.GetName(type)}.cs", new EnumGenerator(assembly.Name, (EnumType)type, symbols).CreateSyntaxTree());
                    return;

                case TypeKind.Interface:
                    InterfaceType interfaceType = (InterfaceType)type;

                    SaveTypeFile($"{symbols.GetName(interfaceType)}.cs", new InterfaceGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree());
                    SaveTypeFile($"{symbols.GetInterfaceProxyName(interfaceType)}.cs", new InterfaceProxyGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree());

                    if (interfaceType.IsDataType == true)
                    {
                        SaveTypeFile($"{symbols.GetInterfaceDefaultName(interfaceType)}.cs", new InterfaceDefaultGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree());
                    }

                    return;

                default:
                    throw new ArgumentException($"Unkown type kind: {type.Kind}", nameof(type));
                }

                void SaveTypeFile(string filename, SyntaxTree syntaxTree)
                {
                    if (!_fileSystem.Directory.Exists(directory))
                    {
                        _fileSystem.Directory.CreateDirectory(directory);
                    }

                    _fileSystem.File.WriteAllText(
                        Path.Combine(directory, filename),
                        syntaxTree.ToString()
                        );
                }
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Returns syntax for the deep copier method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deep copier method.</returns>
        private static MemberDeclarationSyntax GenerateDeepCopierMethod(Type type, List <FieldInfoMember> fields)
        {
            var originalVariable = SF.IdentifierName("original");
            var inputVariable    = SF.IdentifierName("input");
            var resultVariable   = SF.IdentifierName("result");

            var body = new List <StatementSyntax>();

            if (type.GetCustomAttribute <ImmutableAttribute>() != null)
            {
                // Immutable types do not require copying.
                body.Add(SF.ReturnStatement(originalVariable));
            }
            else
            {
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("input")
                            .WithInitializer(
                                SF.EqualsValueClause(
                                    SF.ParenthesizedExpression(
                                        SF.CastExpression(type.GetTypeSyntax(), originalVariable)))))));
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("result")
                            .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type))))));

                // Copy all members from the input to the result.
                foreach (var field in fields)
                {
                    body.Add(SF.ExpressionStatement(field.GetSetter(resultVariable, field.GetGetter(inputVariable))));
                }

                // Record this serialization.
                Expression <Action> recordObject =
                    () => SerializationContext.Current.RecordObject(default(object), default(object));
                var currentSerializationContext =
                    SyntaxFactory.AliasQualifiedName(
                        SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)),
                        SF.IdentifierName("Orleans"))
                    .Qualify("Serialization")
                    .Qualify("SerializationContext")
                    .Qualify("Current");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(currentSerializationContext)
                        .AddArgumentListArguments(SF.Argument(originalVariable), SF.Argument(resultVariable))));

                body.Add(SF.ReturnStatement(resultVariable));
            }

            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "DeepCopier")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("original")).WithType(typeof(object).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList().AddAttributes(SF.Attribute(typeof(CopierMethodAttribute).GetNameSyntax()))));
        }
Exemplo n.º 24
0
        void Save(string packageOutputRoot, ISymbolMap symbols, Assembly assembly, string tarballFileName, string jsiiFileName)
        {
            if (assembly.Docs != null)
            {
                // TODO: Use Microsoft.Extensions.Logging instead of Console.Error.
                Console.Error.WriteLine($"Warning: Ignoring documentation comment on assembly {assembly.Name}. Assembly-level documentation comments are not supported for .NET");
            }

            SaveProjectFile();
            SaveAssemblyInfo(assembly.Name, assembly.Version, tarballFileName);
            SaveDependencyAnchorFile();

            foreach (Type type in assembly.Types?.Values ?? Enumerable.Empty <Type>())
            {
                SaveType(type);
            }

            void SaveProjectFile()
            {
                XElement project =
                    new XElement("Project",
                                 new XAttribute("Sdk", "Microsoft.NET.Sdk"),
                                 new XElement("PropertyGroup", assembly.GetMsBuildProperties()),
                                 new XElement("ItemGroup",
                                              new XElement("EmbeddedResource",
                                                           new XAttribute("Include", tarballFileName)
                                                           )
                                              ),
                                 new XElement("ItemGroup",
                                              new XElement("PackageReference",
                                                           new XAttribute("Include", "Amazon.JSII.Runtime"),
                                                           new XAttribute("Version", JsiiVersion.Version)
                                                           ),
                                              GetDependencies()
                                              .Distinct()
                                              .Select(d => new { Package = symbols.GetAssemblyName(d.Key), Version = d.Value.GetDecoratedVersion() })
                                              .Select(d =>
                                                      new XElement("PackageReference",
                                                                   new XAttribute("Include", d.Package),
                                                                   new XAttribute("Version", d.Version)
                                                                   )
                                                      )
                                              )
                                 );

                if (!_fileSystem.Directory.Exists(packageOutputRoot))
                {
                    _fileSystem.Directory.CreateDirectory(packageOutputRoot);
                }

                // Save to StringBuilder instead of directly to path, so that we can
                // redirect the output through the filesystem shim. Project files are
                // small, so this shouldn't be a memory hog.
                StringBuilder     builder  = new StringBuilder();
                XmlWriterSettings settings = new XmlWriterSettings
                {
                    // Visual Studio omits the XML declaration when creating project files, so we do too.
                    OmitXmlDeclaration = true,
                    // Visual Studio indents project files (they are often edited by hand), so we do too.
                    Indent = true,
                };

                using (XmlWriter writer = XmlWriter.Create(builder, settings))
                {
                    project.Save(writer);
                }

                string csProjPath = Path.Combine(packageOutputRoot, $"{assembly.GetNativePackageId()}.csproj");

                _fileSystem.File.WriteAllText(csProjPath, builder.ToString());

                IEnumerable <KeyValuePair <string, PackageVersion> > GetDependencies()
                {
                    foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(assembly))
                    {
                        yield return(dependency);
                    }

                    IEnumerable <KeyValuePair <string, PackageVersion> > GetDependenciesCore(DependencyRoot root)
                    {
                        if (root.Dependencies == null)
                        {
                            yield break;
                        }
                        foreach (var kvp in root.Dependencies)
                        {
                            yield return(kvp);

                            foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(kvp.Value))
                            {
                                yield return(dependency);
                            }
                        }
                    }
                }
            }

            void SaveDependencyAnchorFile()
            {
                string anchorNamespace = $"{assembly.GetNativeNamespace()}.Internal.DependencyResolution";
                var    syntaxTree      = SF.SyntaxTree(
                    SF.CompilationUnit(
                        SF.List <ExternAliasDirectiveSyntax>(),
                        SF.List <UsingDirectiveSyntax>(),
                        SF.List <AttributeListSyntax>(),
                        SF.List <MemberDeclarationSyntax>(new[] {
                    SF.NamespaceDeclaration(
                        SF.IdentifierName(anchorNamespace),
                        SF.List <ExternAliasDirectiveSyntax>(),
                        SF.List <UsingDirectiveSyntax>(),
                        SF.List(new MemberDeclarationSyntax[] { GenerateDependencyAnchor() })
                        )
                })
                        ).NormalizeWhitespace(elasticTrivia: true)
                    );

                string directory = GetNamespaceDirectory(packageOutputRoot, @anchorNamespace);

                SaveSyntaxTree(directory, "Anchor.cs", syntaxTree);

                ClassDeclarationSyntax GenerateDependencyAnchor()
                {
                    return(SF.ClassDeclaration(
                               SF.List <AttributeListSyntax>(),
                               SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)),
                               SF.Identifier("Anchor"),
                               null,
                               null,
                               SF.List <TypeParameterConstraintClauseSyntax>(),
                               SF.List(new MemberDeclarationSyntax[] {
                        SF.ConstructorDeclaration(
                            SF.List <AttributeListSyntax>(),
                            SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)),
                            SF.Identifier("Anchor"),
                            SF.ParameterList(SF.SeparatedList <ParameterSyntax>()),
                            null,
                            SF.Block(SF.List(GenerateAnchorReferences())),
                            null
                            )
                    })
                               ));

                    IEnumerable <StatementSyntax> GenerateAnchorReferences()
                    {
                        return(assembly.Dependencies?.Keys
                               .Select(k => assembly.GetNativeNamespace(k))
                               .Select(n => $"{n}.Internal.DependencyResolution.Anchor")
                               .Select(t => SF.ExpressionStatement(SF.ObjectCreationExpression(
                                                                       SF.Token(SyntaxKind.NewKeyword),
                                                                       SF.ParseTypeName(t),
                                                                       SF.ArgumentList(SF.SeparatedList <ArgumentSyntax>()),
                                                                       null
                                                                       ))) ?? Enumerable.Empty <StatementSyntax>());
                    }
                }
            }

            void SaveAssemblyInfo(string name, string version, string tarball)
            {
                SyntaxTree assemblyInfo = SF.SyntaxTree(
                    SF.CompilationUnit(
                        SF.List <ExternAliasDirectiveSyntax>(),
                        SF.List(new[] {
                    SF.UsingDirective(SF.ParseName("Amazon.JSII.Runtime.Deputy"))
                }),
                        SF.List(new[] {
                    SF.AttributeList(
                        SF.AttributeTargetSpecifier(
                            SF.Identifier("assembly"),
                            SF.Token(SyntaxKind.ColonToken)
                            ),
                        SF.SeparatedList(new[] {
                        SF.Attribute(
                            SF.ParseName("JsiiAssembly"),
                            SF.ParseAttributeArgumentList($"({SF.Literal(name)}, {SF.Literal(version)}, {SF.Literal(tarball)})")
                            )
                    })
                        )
                }),
                        SF.List <MemberDeclarationSyntax>()
                        ).NormalizeWhitespace(elasticTrivia: true)
                    );

                string assemblyInfoPath = Path.Combine(packageOutputRoot, "AssemblyInfo.cs");

                _fileSystem.File.WriteAllText(assemblyInfoPath, assemblyInfo.ToString());
            }

            void SaveType(Type type)
            {
                string @namespace = symbols.GetNamespace(type);
                string directory  = GetNamespaceDirectory(packageOutputRoot, @namespace);

                switch (type.Kind)
                {
                case TypeKind.Class:
                {
                    var classType = (ClassType)type;

                    if (classType.IsAbstract)
                    {
                        SaveTypeFile($"{symbols.GetAbstractClassProxyName(classType)}.cs",
                                     new AbstractClassProxyGenerator(assembly.Name, classType, symbols).CreateSyntaxTree());
                    }

                    SaveTypeFile($"{symbols.GetName(type)}.cs",
                                 new ClassGenerator(assembly.Name, classType, symbols).CreateSyntaxTree());
                    return;
                }

                case TypeKind.Enum:
                {
                    SaveTypeFile($"{symbols.GetName(type)}.cs",
                                 new EnumGenerator(assembly.Name, (EnumType)type, symbols).CreateSyntaxTree());
                    return;
                }

                case TypeKind.Interface:
                {
                    InterfaceType interfaceType = (InterfaceType)type;

                    SaveTypeFile($"{symbols.GetName(interfaceType)}.cs",
                                 new InterfaceGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree());
                    SaveTypeFile($"{symbols.GetInterfaceProxyName(interfaceType)}.cs",
                                 new InterfaceProxyGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree());

                    if (interfaceType.IsDataType)
                    {
                        SaveTypeFile($"{symbols.GetInterfaceDefaultName(interfaceType)}.cs",
                                     new InterfaceDefaultGenerator(assembly.Name, interfaceType, symbols)
                                     .CreateSyntaxTree());
                    }

                    return;
                }

                default:
                {
                    throw new ArgumentException($"Unkown type kind: {type.Kind}", nameof(type));
                }
                }

                void SaveTypeFile(string filename, SyntaxTree syntaxTree)
                {
                    SaveSyntaxTree(directory, filename, syntaxTree);
                }
            }

            void SaveSyntaxTree(string directory, string filename, SyntaxTree syntaxTree)
            {
                if (!_fileSystem.Directory.Exists(directory))
                {
                    _fileSystem.Directory.CreateDirectory(directory);
                }

                _fileSystem.File.WriteAllText(
                    Path.Combine(directory, filename),
                    syntaxTree.ToString()
                    );
            }
        }
Exemplo n.º 25
0
        /// <summary>
        /// Returns syntax for the deserializer method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deserializer method.</returns>
        private static MemberDeclarationSyntax GenerateDeserializerMethod(Type type, List <FieldInfoMember> fields)
        {
            Expression <Action> deserializeInner =
                () => SerializationManager.DeserializeInner(default(Type), default(BinaryTokenStreamReader));
            var streamParameter = SF.IdentifierName("stream");

            var resultDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(type.GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("result")
                        .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type)))));
            var resultVariable = SF.IdentifierName("result");

            var body = new List <StatementSyntax> {
                resultDeclaration
            };

            // Value types cannot be referenced, only copied, so there is no need to box & record instances of value types.
            if (!type.IsValueType)
            {
                // Record the result for cyclic deserialization.
                Expression <Action> recordObject = () => DeserializationContext.Current.RecordObject(default(object));
                var currentSerializationContext  =
                    SyntaxFactory.AliasQualifiedName(
                        SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)),
                        SF.IdentifierName("Orleans"))
                    .Qualify("Serialization")
                    .Qualify("DeserializationContext")
                    .Qualify("Current");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(currentSerializationContext)
                        .AddArgumentListArguments(SF.Argument(resultVariable))));
            }

            // Deserialize all fields.
            foreach (var field in fields)
            {
                var deserialized =
                    deserializeInner.Invoke()
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(field.Type)),
                        SF.Argument(streamParameter));
                body.Add(
                    SF.ExpressionStatement(
                        field.GetSetter(
                            resultVariable,
                            SF.CastExpression(field.Type, deserialized))));
            }

            body.Add(SF.ReturnStatement(SF.CastExpression(type.GetTypeSyntax(), resultVariable)));
            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "Deserializer")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("expected")).WithType(typeof(Type).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("stream")).WithType(typeof(BinaryTokenStreamReader).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList()
                     .AddAttributes(SF.Attribute(typeof(DeserializerMethodAttribute).GetNameSyntax()))));
        }
Exemplo n.º 26
0
        /// <summary>
        /// Returns syntax for the deserializer method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deserializer method.</returns>
        private static MemberDeclarationSyntax GenerateDeserializerMethod(Type type, List <FieldInfoMember> fields)
        {
            Expression <Action <IDeserializationContext> > deserializeInner =
                ctx => ctx.DeserializeInner(default(Type));
            var contextParameter = SF.IdentifierName("context");

            var resultDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(type.GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("result")
                        .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type)))));
            var resultVariable = SF.IdentifierName("result");

            var body = new List <StatementSyntax> {
                resultDeclaration
            };

            // Value types cannot be referenced, only copied, so there is no need to box & record instances of value types.
            if (!type.GetTypeInfo().IsValueType)
            {
                // Record the result for cyclic deserialization.
                Expression <Action <IDeserializationContext> > recordObject = ctx => ctx.RecordObject(default(object));
                var currentSerializationContext = contextParameter;
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(currentSerializationContext)
                        .AddArgumentListArguments(SF.Argument(resultVariable))));
            }

            // Deserialize all fields.
            foreach (var field in fields)
            {
                var deserialized =
                    deserializeInner.Invoke(contextParameter)
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(field.Type)));
                body.Add(
                    SF.ExpressionStatement(
                        field.GetSetter(
                            resultVariable,
                            SF.CastExpression(field.Type, deserialized))));
            }

            // If the type implements the internal IOnDeserialized lifecycle method, invoke it's method now.
            if (typeof(IOnDeserialized).IsAssignableFrom(type))
            {
                Expression <Action <IOnDeserialized> > onDeserializedMethod = _ => _.OnDeserialized(default(ISerializerContext));

                // C#: ((IOnDeserialized)result).OnDeserialized(context);
                var typedResult          = SF.ParenthesizedExpression(SF.CastExpression(typeof(IOnDeserialized).GetTypeSyntax(), resultVariable));
                var invokeOnDeserialized = onDeserializedMethod.Invoke(typedResult).AddArgumentListArguments(SF.Argument(contextParameter));
                body.Add(SF.ExpressionStatement(invokeOnDeserialized));
            }

            body.Add(SF.ReturnStatement(SF.CastExpression(type.GetTypeSyntax(), resultVariable)));
            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "Deserializer")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("expected")).WithType(typeof(Type).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("context")).WithType(typeof(IDeserializationContext).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList()
                     .AddAttributes(SF.Attribute(typeof(DeserializerMethodAttribute).GetNameSyntax()))));
        }
Exemplo n.º 27
0
        /// <summary>
        /// Generates the class for the provided grain types.
        /// </summary>
        /// <param name="type">The grain interface type.</param>
        /// <param name="onEncounteredType">
        /// The callback invoked when a type is encountered.
        /// </param>
        /// <returns>
        /// The generated class.
        /// </returns>
        internal static IEnumerable <TypeDeclarationSyntax> GenerateClass(Type type, Action <Type> onEncounteredType)
        {
            var typeInfo     = type.GetTypeInfo();
            var genericTypes = typeInfo.IsGenericTypeDefinition
                                   ? typeInfo.GetGenericArguments().Select(_ => SF.TypeParameter(_.ToString())).ToArray()
                                   : new TypeParameterSyntax[0];

            var attributes = new List <AttributeSyntax>
            {
                CodeGeneratorCommon.GetGeneratedCodeAttributeSyntax(),
                SF.Attribute(typeof(ExcludeFromCodeCoverageAttribute).GetNameSyntax()),
                SF.Attribute(typeof(SerializerAttribute).GetNameSyntax())
                .AddArgumentListArguments(
                    SF.AttributeArgument(SF.TypeOfExpression(type.GetTypeSyntax(includeGenericParameters: false))))
            };

            var className = CodeGeneratorCommon.ClassPrefix + type.GetParseableName(GeneratedTypeNameOptions);
            var fields    = GetFields(type);

            // Mark each field type for generation
            foreach (var field in fields)
            {
                var fieldType = field.FieldInfo.FieldType;
                onEncounteredType(fieldType);
            }

            var members = new List <MemberDeclarationSyntax>(GenerateStaticFields(fields))
            {
                GenerateDeepCopierMethod(type, fields),
                GenerateSerializerMethod(type, fields),
                GenerateDeserializerMethod(type, fields),
            };

            if (typeInfo.IsConstructedGenericType || !typeInfo.IsGenericTypeDefinition)
            {
                members.Add(GenerateRegisterMethod(type));
                members.Add(GenerateConstructor(className));
                attributes.Add(SF.Attribute(typeof(RegisterSerializerAttribute).GetNameSyntax()));
            }

            var classDeclaration =
                SF.ClassDeclaration(className)
                .AddModifiers(SF.Token(SyntaxKind.InternalKeyword))
                .AddAttributeLists(SF.AttributeList().AddAttributes(attributes.ToArray()))
                .AddMembers(members.ToArray())
                .AddConstraintClauses(type.GetTypeConstraintSyntax());

            if (genericTypes.Length > 0)
            {
                classDeclaration = classDeclaration.AddTypeParameterListParameters(genericTypes);
            }

            var classes = new List <TypeDeclarationSyntax> {
                classDeclaration
            };

            if (typeInfo.IsGenericTypeDefinition)
            {
                // Create a generic representation of the serializer type.
                var serializerType =
                    SF.GenericName(classDeclaration.Identifier)
                    .WithTypeArgumentList(
                        SF.TypeArgumentList()
                        .AddArguments(
                            type.GetGenericArguments()
                            .Select(_ => SF.OmittedTypeArgument())
                            .Cast <TypeSyntax>()
                            .ToArray()));
                var registererClassName = className + "_" +
                                          string.Join("_",
                                                      type.GetTypeInfo().GenericTypeParameters.Select(_ => _.Name)) + "_" +
                                          RegistererClassSuffix;
                classes.Add(
                    SF.ClassDeclaration(registererClassName)
                    .AddModifiers(SF.Token(SyntaxKind.InternalKeyword))
                    .AddAttributeLists(
                        SF.AttributeList()
                        .AddAttributes(
                            CodeGeneratorCommon.GetGeneratedCodeAttributeSyntax(),
                            SF.Attribute(typeof(ExcludeFromCodeCoverageAttribute).GetNameSyntax()),
                            SF.Attribute(typeof(RegisterSerializerAttribute).GetNameSyntax())))
                    .AddMembers(
                        GenerateMasterRegisterMethod(type, serializerType),
                        GenerateConstructor(registererClassName)));
            }

            return(classes);
        }
Exemplo n.º 28
0
        public static byte[] CreateControllerCode(IService service)
        {
            var @file      = SF.CompilationUnit();
            var @namespace = SF.NamespaceDeclaration(SF.ParseName("MBase.ServiceHost.Controllers")).NormalizeWhitespace();

            @file = @file
                    .AddUsings(SF.UsingDirective(SF.IdentifierName("System")));
            @file = @file
                    .AddUsings(SF.UsingDirective(SF.IdentifierName("Microsoft.AspNetCore.Mvc")));
            @file = @file
                    .AddUsings(SF.UsingDirective(SF.IdentifierName("System.Threading.Tasks")));

            @file = @file.AddUsings(SF.UsingDirective(SF.IdentifierName(service.GetType().Namespace)));
            @file = @file.AddUsings(SF.UsingDirective(SF.IdentifierName(service.GetType().Namespace + ".Models")));

            foreach (var item in service.Commands.Where(m => typeof(ICommand).IsAssignableFrom(m.GetType())))
            {
                @file = @file.AddUsings(SF.UsingDirective(SF.IdentifierName(item.GetType().Namespace)));
            }



            var classDeclaration = SF.ClassDeclaration(service.GetType().Name.ToString() + "Controller")
                                   .AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
                                   .AddBaseListTypes(SF.SimpleBaseType(SF.ParseTypeName("ControllerBase")))
                                   .WithAttributeLists(
                SF.List(
                    new AttributeListSyntax[] {
                SF.AttributeList(
                    SF.SingletonSeparatedList(
                        SF.Attribute(SF.IdentifierName("Route"))
                        .WithArgumentList(
                            SF.AttributeArgumentList(
                                SF.SingletonSeparatedList(
                                    SF.AttributeArgument(
                                        SF.LiteralExpression(SyntaxKind.StringLiteralExpression, SF.Literal($"api/[controller]")))))))),
                SF.AttributeList(
                    SF.SingletonSeparatedList(
                        SF.Attribute(SF.IdentifierName("ApiController"))))
            }));

            List <MemberDeclarationSyntax> controllerMembers = new List <MemberDeclarationSyntax>();

            controllerMembers.Add(
                SF.FieldDeclaration(
                    SF.VariableDeclaration(
                        SF.ParseTypeName(service.GetType().Name))
                    .AddVariables(SF.VariableDeclarator("_service")))
                .AddModifiers(SF.Token(SyntaxKind.PrivateKeyword)));

            controllerMembers.Add(
                SF.ConstructorDeclaration(service.GetType().Name.ToString() + "Controller")
                .WithParameterList(
                    SF.ParameterList(
                        SF.SingletonSeparatedList(
                            SF.Parameter(
                                SF.Identifier("service"))
                            .WithType(
                                SF.IdentifierName("IService")))

                        ))
                .AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
                .WithBody(SF.Block(SF.ParseStatement($"this._service = ({service.GetType().Name})service;"))));

            foreach (var item in service.Commands.Where(m => typeof(ICommand).IsAssignableFrom(m.GetType())))
            {
                var syntax = @$ "

            var response = await CommandHelper.ExecuteMethod<{item.Name}>(new {item.Name}(),new Request<{item.Name}>(request, new MessageEnvelope()));