protected IStTypeNode MapTypeReference(ITypeSymbol typeSymbol, TypeMappings typeMappings, bool forField = false) { var arraySymbol = typeSymbol as IArrayTypeSymbol; if (arraySymbol != null) { return(new StExpressionWithTypeArguments() .WithExpression(new StIdentifier().WithEscapedText("Array")) .WithTypeArgument(this.MapTypeReference(arraySymbol.ElementType, typeMappings))); } foreach (var mapping in typeMappings.PrimitiveTypeMappings) { if (this.TypeMatches(typeSymbol, mapping.Key)) { return(new StExpressionWithTypeArguments().WithExpression(new StIdentifier().WithEscapedText(mapping.Value))); } } foreach (var mapping in typeMappings.ComplexTypeMappings) { if (this.TypeMatches(typeSymbol, mapping.Key)) { return(mapping.Value()); } } var dictionaryInterface = typeSymbol .Interfaces .FirstOrDefault(i => i.IsGenericType && i.ConstructedFrom.GetFullMetadataName() == typeof(IDictionary <,>).FullName && i.TypeArguments[0].GetFullMetadataName() == typeof(string).FullName); if (dictionaryInterface != null) { return (new StTypeLiteralNode() .WithMember( new StIndexSignatureDeclaration() .WithParameter(p => p.WithName(new StIdentifier().WithEscapedText("key")).WithType(new StKeywordTypeNodeStringKeyword())) .WithType(this.MapTypeReference(dictionaryInterface.TypeArguments[1], typeMappings)))); } var collectionInterface = typeSymbol.Interfaces.FirstOrDefault(i => i.IsGenericType && i.ConstructedFrom.GetFullMetadataName() == typeof(IEnumerable <>).FullName); if (collectionInterface != null) { return(new StExpressionWithTypeArguments() .WithExpression(new StIdentifier().WithEscapedText("Array")) .WithTypeArgument(this.MapTypeReference(collectionInterface.TypeArguments[0], typeMappings))); } if (this.HasBaseModelNamespace(typeSymbol)) { if ((this.Settings.NullableNodes || this.Settings.OptionalNodes) && forField) { var union = new StUnionTypeNode() .WithType(new StExpressionWithTypeArguments() .WithExpression(new StIdentifier().WithEscapedText(typeSymbol.Name))); if (this.Settings.NullableNodes) { union.types.Add(new StKeywordTypeNodeNullKeyword()); } if (this.Settings.OptionalNodes) { union.types.Add(new StKeywordTypeNodeUndefinedKeyword()); } return(union); } else { return(new StExpressionWithTypeArguments() .WithExpression(new StIdentifier().WithEscapedText(typeSymbol.Name))); } } if (this.Settings.SkipUnmappedTypeReferences) { return(null); } else { throw new InvalidOperationException($"Type {typeSymbol.ToDisplayString()} cannot be mapped."); } }
protected void GenerateForClass(CodeFileCSharp input, INamedTypeSymbol classSymbol, TypeMappings typeMappings) { var members = classSymbol.GetMembers() .Where(m => m.DeclaredAccessibility == Accessibility.Public && !m.IsStatic && m.Kind == SymbolKind.Field) .OfType <IFieldSymbol>() .ToArray(); var heritage = new StHeritageClause() .WithToken(FullSyntaxTree.TransportModel.SyntaxKind.ExtendsKeyword); var interfaceDefinition = new StInterfaceDeclaration() .WithModifier(new StExportKeywordToken()) .WithName(new StIdentifier().WithEscapedText(classSymbol.Name)); var addHeritage = false; if (classSymbol.BaseType != null && typeof(object).FullName != classSymbol.BaseType.GetFullMetadataName()) { var baseType = this.MapTypeReference(classSymbol.BaseType, typeMappings); if (baseType != null && baseType is StExpressionWithTypeArguments expressionWithTypeArguments) { heritage.WithType(t => expressionWithTypeArguments); addHeritage = true; } } if (addHeritage) { interfaceDefinition.WithHeritageClaus(b => heritage); } foreach (var member in members) { interfaceDefinition.WithMember( new StPropertySignature() .WithName(new StIdentifier().WithEscapedText(member.Name)) .WithType(this.MapTypeReference(member.Type, typeMappings, true))); } this.OutputFile.Model.statements.Add(interfaceDefinition); }