/// <summary>
        /// Is overridden to define how the type definition is translated by this strategy.
        /// </summary>
        /// <param name="type">Type definition that should be tranlated.</param>
        /// <param name="templatingEngine">Templating engine that can be used to fill predefined code snippets.</param>
        /// <returns>Result of the translation.</returns>
        protected override CodeFragment Translate(Type type, ITemplatingEngine templatingEngine)
        {
            var decorators  = DecoratorTranslator.GenerateDecorators(type);
            var properties  = GeneratePropertyDefinitions(type, templatingEngine);
            var declaration = GenerateClassDeclaration(type);
            var deps        = declaration.dependencies.Merge(properties.dependencies).Merge(decorators.Dependencies);

            var code = templatingEngine.UseTemplate("ClassDefinition", new Dictionary <string, string>
            {
                { "Decorators", decorators.DecoratorCode },
                { "ClassName", type.GetNameWithGenericTypeParameters() },
                { "ClassDeclaration", declaration.code },
                { "Documentation", GenerateDocumentationComment(type) },
                { "Properties", properties.code.AddIndentation() },
                { "Dependencies", GenerateDependencyInitialization(deps, templatingEngine) },
                { "ConstructorCode", declaration.isDerived
                    ? $"{ Environment.NewLine }super();".AddIndentation(2)
                    : string.Empty }
            });

            return(new CodeFragment(
                       CodeFragmentId.ForClrType(type),
                       code,
                       deps));
        }
Exemple #2
0
 private string GenerateEnumValues(Type type, ITemplatingEngine templatingEngine)
 {
     return(string.Join("," + Environment.NewLine, Enum.GetNames(type).Select(name =>
                                                                              templatingEngine.UseTemplate("EnumValue", new Dictionary <string, string>
     {
         { "EnumValueName", name },
         { "Documentation", GenerateDocumentationComment(type.GetMember(name).Single()) },
         { "EnumValue", Convert.ChangeType(Enum.Parse(type, name), Enum.GetUnderlyingType(type)).ToString() }
     }))));
 }
Exemple #3
0
        /// <summary>
        /// Is overridden to define how the type definition is translated by this strategy.
        /// </summary>
        /// <param name="type">Type definition that should be tranlated.</param>
        /// <param name="templatingEngine">Templating engine that can be used to fill predefined code snippets.</param>
        /// <returns>Result of the translation.</returns>
        protected override CodeFragment Translate(Type type, ITemplatingEngine templatingEngine)
        {
            var code = templatingEngine.UseTemplate("EnumDefinition", new Dictionary <string, string>
            {
                { "EnumName", type.Name },
                { "Documentation", GenerateDocumentationComment(type) },
                { "EnumValues", GenerateEnumValues(type, templatingEngine).AddIndentation() },
                { "EnumAttributeMaps", GenerateEnumAttributeMaps(type, templatingEngine) }
            });

            return(new CodeFragment(
                       CodeFragmentId.ForClrType(type),
                       code,
                       CodeDependencies.Empty));
        }
Exemple #4
0
 private string GenerateEnumAttributeMap(Type type, ITemplatingEngine templatingEngine, string mapName, string mapValueTemplate)
 {
     return(templatingEngine.UseTemplate("EnumAttributeMap", new Dictionary <string, string>
     {
         { "EnumName", type.Name },
         { "MapName", mapName },
         { "MapItems", string.Join($",{Environment.NewLine}",
                                   from memberName in Enum.GetNames(type)
                                   select templatingEngine.UseTemplate("EnumAttributeMapItem", new Dictionary <string, string>
             {
                 { "EnumName", type.Name },
                 { "EnumMember", memberName },
                 { "MappedValue", mapValueTemplate.FormatWith(type.GetMember(memberName).SingleOrDefault().CreateFormattingContext()) }
             })).AddIndentation() }
     }));
 }
        /// <summary>
        /// Creates a <see cref="TranslationStrategyBase"/>.
        /// </summary>
        /// <param name="configurationSource">Source for the configuration that should be used.</param>
        /// <param name="templatingEngine">Engine to use for loading templates.</param>
        /// <param name="documentationSource">Source for looking up documentation comments for members.</param>
        /// <param name="logger">Logger to use for writing log messages.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="templatingEngine"/> or <paramref name="documentationSource"/> or <paramref name="logger"/> is null.</exception>
        protected TranslationStrategyBase(IConfigurationSource configurationSource, ITemplatingEngine templatingEngine, IDocumentationSource documentationSource, ILogger logger)
        {
            if (configurationSource == null)
            {
                throw new ArgumentNullException(nameof(configurationSource));
            }

            _templatingEngine    = templatingEngine ?? throw new ArgumentNullException(nameof(templatingEngine));
            _documentationSource = documentationSource ?? throw new ArgumentNullException(nameof(documentationSource));

            Logger = logger ?? throw new ArgumentNullException(nameof(logger));
            TypeReferenceTranslator = new DefaultTypeReferenceTranslator(configurationSource, logger);
            DecoratorTranslator     = new DecoratorTranslator(configurationSource);
            Configuration           = configurationSource.GetSection <TranspilationConfiguration>()
                                      ?? TranspilationConfiguration.Default;
        }
Exemple #6
0
        /// <summary>
        /// Is overridden to define how the type definition is translated by this strategy.
        /// </summary>
        /// <param name="type">Type definition that should be tranlated.</param>
        /// <param name="templatingEngine">Templating engine that can be used to fill predefined code snippets.</param>
        /// <returns>Result of the translation.</returns>
        protected override CodeFragment Translate(Type type, ITemplatingEngine templatingEngine)
        {
            var properties  = GeneratePropertyDefinitions(type, templatingEngine, out var dependencies);
            var declaration = GenerateClassDeclaration(type);

            dependencies = dependencies.Merge(declaration.dependencies);

            var code = templatingEngine.UseTemplate("InterfaceDefinition", new Dictionary <string, string>
            {
                { "InterfaceDeclaration", declaration.code },
                { "Documentation", GenerateDocumentationComment(type) },
                { "Properties", properties.AddIndentation() }
            });

            return(new CodeFragment(
                       CodeFragmentId.ForClrType(type),
                       code,
                       dependencies));
        }
Exemple #7
0
        private string GeneratePropertyDefinitions(Type type, ITemplatingEngine templatingEngine, out CodeDependencies dependencies)
        {
            var propertyCodeSnippets = new List <string>();
            var deps = CodeDependencies.Empty;

            foreach (var property in type.GetProperties())
            {
                Logger.WriteInformation($"Translating property {property.Name} on type {type}.");

                var typeReferenceTranslation = TypeReferenceTranslator.Translate(property.PropertyType);
                deps = deps.Merge(typeReferenceTranslation.Dependencies);

                propertyCodeSnippets.Add(templatingEngine.UseTemplate("InterfacePropertyDefinition", new Dictionary <string, string>
                {
                    { "PropertyName", GetTypeScriptPropertyName(property) },
                    { "Documentation", GenerateDocumentationComment(property) },
                    { "PropertyType", typeReferenceTranslation.ReferencedTypeName }
                }));
            }

            dependencies = deps;
            return(string.Join(Environment.NewLine, propertyCodeSnippets));
        }
Exemple #8
0
 private string GenerateEnumAttributeMaps(Type type, ITemplatingEngine templatingEngine)
 {
     return(string.Join(Environment.NewLine,
                        Configuration.EnumAttributeMaps.Select(map => GenerateEnumAttributeMap(type, templatingEngine, map.Key, map.Value))));
 }
Exemple #9
0
 /// <summary>
 /// Creates a <see cref="EnumDefinitionTranslator"/>.
 /// </summary>
 /// <param name="configurationSource">Source for the configuration that should be used.</param>
 /// <param name="templatingEngine">Engine to use for loading templates.</param>
 /// <param name="documentationSource">Source for looking up documentation comments for members.</param>
 /// <param name="logger">Logger to use for writing log messages.</param>
 /// <exception cref="ArgumentNullException">Thrown when <paramref name="templatingEngine"/> or <paramref name="documentationSource"/> or <paramref name="logger"/> is null.</exception>
 public EnumDefinitionTranslationStrategy(IConfigurationSource configurationSource, ITemplatingEngine templatingEngine, IDocumentationSource documentationSource, ILogger logger)
     : base(configurationSource, templatingEngine, documentationSource, logger)
 {
 }
        /// <summary>
        /// Creates a <see cref="DefaultTypeDefinitionTranslator"/>.
        /// </summary>
        /// <param name="configurationSource">Source for the configuration that should be used.</param>
        /// <param name="templatingEngine">Engine to use for loading templates.</param>
        /// <param name="documentationSource">Source for looking up documentation comments for members.</param>
        /// <param name="logger">Logger to use for writing log messages.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="templatingEngine"/> or <paramref name="documentationSource"/> or <paramref name="logger"/> is null.</exception>
        public DefaultTypeDefinitionTranslator(IConfigurationSource configurationSource, ITemplatingEngine templatingEngine, IDocumentationSource documentationSource, ILogger logger)
        {
            if (configurationSource == null)
            {
                throw new ArgumentNullException(nameof(configurationSource));
            }
            if (templatingEngine == null)
            {
                throw new ArgumentNullException(nameof(templatingEngine));
            }
            if (documentationSource == null)
            {
                throw new ArgumentNullException(nameof(documentationSource));
            }

            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            _strategies = new ITypeDefinitionTranslationStrategy[]
            {
                new ClassDefinitionTranslationStrategy(configurationSource, templatingEngine, documentationSource, logger),
                new InterfaceDefinitionTranslationStrategy(configurationSource, templatingEngine, documentationSource, logger),
                new EnumDefinitionTranslationStrategy(configurationSource, templatingEngine, documentationSource, logger)
            };
        }
 /// <summary>
 /// Is overridden to define how the type definition is translated by this strategy.
 /// </summary>
 /// <param name="type">Type definition that should be tranlated.</param>
 /// <param name="templatingEngine">Templating engine that can be used to fill predefined code snippets.</param>
 /// <returns>Result of the translation.</returns>
 protected abstract CodeFragment Translate(Type type, ITemplatingEngine templatingEngine);
 /// <summary>
 /// Creates a <see cref="ClassDefinitionTranslationStrategy"/>.
 /// </summary>
 /// <param name="configurationSource">Source for the configuration that should be used.</param>
 /// <param name="templatingEngine">Engine to use for loading templates.</param>
 /// <param name="documentationSource">Source for looking up documentation comments for members.</param>
 /// <param name="logger">Logger to use for writing log messages.</param>
 /// <exception cref="ArgumentNullException">Thrown when <paramref name="templatingEngine"/> or <paramref name="documentationSource"/> or <paramref name="logger"/> is null.</exception>
 public ClassDefinitionTranslationStrategy(IConfigurationSource configurationSource, ITemplatingEngine templatingEngine, IDocumentationSource documentationSource, ILogger logger)
     : base(configurationSource, templatingEngine, documentationSource, logger)
 {
     _defaultValueProvider = new DefaultValueProvider(configurationSource, logger, TypeReferenceTranslator);
 }
        private string GenerateDependencyInitialization(CodeDependencies dependencies, ITemplatingEngine templatingEngine)
        {
            if (!Configuration.RuntimeDependencyLoading)
            {
                return(string.Empty);
            }

            var loadableDependencies = dependencies.CodeFragments
                                       .Where(x => x.TryRecreateClrType(out var type) && !type.IsInterface)
                                       .Select(x => x.ExportedName).Concat(dependencies.Imports.Select(x => x.Name));

            return(templatingEngine.UseTemplate("DependencyInitialization", new Dictionary <string, string>
            {
                { "Dependencies", string.Join(", ", loadableDependencies) }
            }));
        }
        private (string code, CodeDependencies dependencies) GeneratePropertyDefinitions(Type type, ITemplatingEngine templatingEngine)
        {
            var propertyCodeSnippets = new List <string>();
            var deps = CodeDependencies.Empty;

            foreach (var property in GetPropertiesForTranspilation(type))
            {
                Logger.WriteInformation($"Translating property {property.Name} on type {type}.");

                var typeReferenceTranslation = TypeReferenceTranslator.Translate(property.PropertyType);
                var decorators = DecoratorTranslator.GenerateDecorators(property);
                deps = deps
                       .Merge(typeReferenceTranslation.Dependencies)
                       .Merge(decorators.Dependencies);

                propertyCodeSnippets.Add(templatingEngine.UseTemplate("ClassPropertyDefinition", new Dictionary <string, string>
                {
                    { "Decorators", decorators.DecoratorCode },
                    { "PropertyName", GetTypeScriptPropertyName(property) },
                    { "Documentation", GenerateDocumentationComment(property) },
                    { "PropertyType", typeReferenceTranslation.ReferencedTypeName },
                    { "Assignment", _defaultValueProvider.Assignment(property) }
                }));
            }

            var properties = string.Join(Environment.NewLine, propertyCodeSnippets);

            return(properties, deps);
        }