private void ExecuteGenerator(GeneratorExecutionContext context) { INamedTypeSymbol[] symbols = context .GetAllTypes() .ToArray(); //This finds all the context symbols trying to be generated var dataContextSymbols = symbols .Where(s => s.HasAttributeExact <RequiredDataModelAttribute>()) .ToArray(); //.Where(s => !s.IsGenericType) foreach (var contextSymbol in dataContextSymbols) { StringBuilder builder = new StringBuilder(); UsingsEmitter usingsEmitter = new(); NamespaceDecoratorEmitter namespaceDecorator = new NamespaceDecoratorEmitter(CreateContextClassEmitter(contextSymbol), contextSymbol.ContainingNamespace.FullNamespaceString()); usingsEmitter.AddNamespaces(GGDBFConstants.DEFAULT_NAMESPACES); foreach (var type in RetrieveModelTypes(contextSymbol)) { AddNamespacesForType(type, usingsEmitter); } usingsEmitter.Emit(builder); namespaceDecorator.Emit(builder); context.AddSource(contextSymbol.Name, ConvertFileToNode(context, builder).ToString()); EmitSerializableModelTypes(contextSymbol, context); EmitModelKeyTypes(contextSymbol, context); } }
private void EmitModelKeyTypeSource(INamedTypeSymbol contextSymbol, GeneratorExecutionContext context, INamedTypeSymbol type) { string keyName = new TablePrimaryKeyParser().ParseSimple(type); StringBuilder builder = new StringBuilder(); UsingsEmitter usingsEmitter = new(); NamespaceDecoratorEmitter namespaceDecorator = new NamespaceDecoratorEmitter(new CompositeKeyTypeEmitter(keyName, type, Accessibility.Public), contextSymbol.ContainingNamespace.FullNamespaceString()); //If the type is another namespace we should import it //so we don't have to use fullnames. AddNamespacesForType(type, usingsEmitter); usingsEmitter.AddNamespaces(GGDBFConstants.DEFAULT_NAMESPACES); usingsEmitter.Emit(builder); namespaceDecorator.Emit(builder); string source = builder.ToString(); string hashMapKey = $"{keyName} {source.Substring(source.IndexOf('{'))}"; //Keys could be shared in cases of multiple contexts if (EmittedKeyTypes.Contains(hashMapKey)) { return; } EmittedKeyTypes.Add(hashMapKey); context.AddSource($"{contextSymbol.Name}_{keyName}", ConvertFileToNode(context, builder).ToString()); }
private static void EmitSerializableTypeSource(INamedTypeSymbol contextSymbol, GeneratorExecutionContext context, INamedTypeSymbol type) { if (!type.HasForeignKeyDefined() && !type.HasOwnedTypePropertyWithForeignKey()) { return; } string serializableTypeName = new ForeignKeyContainingPropertyNameParser().ParseNonGeneric(contextSymbol, type); StringBuilder builder = new StringBuilder(); UsingsEmitter usingsEmitter = new(); NamespaceDecoratorEmitter namespaceDecorator = new NamespaceDecoratorEmitter(new SerializableTypeClassEmitter(serializableTypeName, type, contextSymbol, Accessibility.Public), contextSymbol.ContainingNamespace.FullNamespaceString()); //If the type is another namespace we should import it //so we don't have to use fullnames. AddNamespacesForType(type, usingsEmitter); //Add namespaces for each property foreach (var t in type .GetMembers() .Where(m => m.Kind == SymbolKind.Property) .Cast <IPropertySymbol>() .Select(p => p.Type) .Select(t => t as INamedTypeSymbol) .Where(t => t != null)) { AddNamespacesForType(t, usingsEmitter); } usingsEmitter.AddNamespaces(GGDBFConstants.DEFAULT_NAMESPACES); usingsEmitter.Emit(builder); namespaceDecorator.Emit(builder); context.AddSource($"{serializableTypeName}", ConvertFileToNode(context, builder).ToString()); }