/// <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)); }
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() } })))); }
/// <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)); }
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; }
/// <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)); }
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)); }
private string GenerateEnumAttributeMaps(Type type, ITemplatingEngine templatingEngine) { return(string.Join(Environment.NewLine, Configuration.EnumAttributeMaps.Select(map => GenerateEnumAttributeMap(type, templatingEngine, map.Key, map.Value)))); }
/// <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); }