From 1b8240fd7b1c207f39e4249860bd190807bd1cc9 Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Sat, 21 Dec 2024 03:47:34 -0300 Subject: [PATCH] Switch to lighter handler type detection in dapper Instead of updating the compilation and using the resulting type name, just apply the template in-memory and locate the resulting identifier. A fake INamedTypeSymbol stands-in for the full symbol for Scriban rendering. --- src/StructId.Analyzer/DapperGenerator.cs | 178 ++++++++++++++++++++++- 1 file changed, 175 insertions(+), 3 deletions(-) diff --git a/src/StructId.Analyzer/DapperGenerator.cs b/src/StructId.Analyzer/DapperGenerator.cs index 6436652..e7f9b04 100644 --- a/src/StructId.Analyzer/DapperGenerator.cs +++ b/src/StructId.Analyzer/DapperGenerator.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Globalization; using System.Linq; -using System.Reflection.Metadata.Ecma335; +using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Scriban; @@ -62,8 +63,14 @@ protected override IncrementalValuesProvider OnInitialize(Incremen // Consider templatized handlers that will be emitted as custom handlers too for registration. if (templated != null) { - var compilation = args.KnownTypes.Compilation.AddSyntaxTrees(templated.Syntax.SyntaxTree); - handler = compilation.Assembly.GetAllTypes().FirstOrDefault(x => x.Name == templated.TypeName); + var identifier = templated.Template.Syntax.ApplyValue(templated.TValue) + .DescendantNodes() + .OfType() + .First() + .Identifier.Text; + + // Use lighter symbol since our template rendering only uses the type name. + handler = new KnownTypeNameSymbol(identifier); } } @@ -152,4 +159,169 @@ record SelectorModel( IEnumerable CustomIds, IEnumerable CustomValues, IEnumerable TemplatizedValueHandlers); + +#pragma warning disable RS1009 // Only internal implementations of this interface are allowed + class KnownTypeNameSymbol(string typeName) : INamedTypeSymbol +#pragma warning restore RS1009 // Only internal implementations of this interface are allowed + { + public string Name => typeName; + public string ToDisplayString(SymbolDisplayFormat? format = null) => typeName; + + public int Arity => throw new System.NotImplementedException(); + + public bool IsGenericType => throw new System.NotImplementedException(); + + public bool IsUnboundGenericType => throw new System.NotImplementedException(); + + public bool IsScriptClass => throw new System.NotImplementedException(); + + public bool IsImplicitClass => throw new System.NotImplementedException(); + + public bool IsComImport => throw new System.NotImplementedException(); + + public bool IsFileLocal => throw new System.NotImplementedException(); + + public IEnumerable MemberNames => throw new System.NotImplementedException(); + + public ImmutableArray TypeParameters => throw new System.NotImplementedException(); + + public ImmutableArray TypeArguments => throw new System.NotImplementedException(); + + public ImmutableArray TypeArgumentNullableAnnotations => throw new System.NotImplementedException(); + + public INamedTypeSymbol OriginalDefinition => throw new System.NotImplementedException(); + + public IMethodSymbol? DelegateInvokeMethod => throw new System.NotImplementedException(); + + public INamedTypeSymbol? EnumUnderlyingType => throw new System.NotImplementedException(); + + public INamedTypeSymbol ConstructedFrom => throw new System.NotImplementedException(); + + public ImmutableArray InstanceConstructors => throw new System.NotImplementedException(); + + public ImmutableArray StaticConstructors => throw new System.NotImplementedException(); + + public ImmutableArray Constructors => throw new System.NotImplementedException(); + + public ISymbol? AssociatedSymbol => throw new System.NotImplementedException(); + + public bool MightContainExtensionMethods => throw new System.NotImplementedException(); + + public INamedTypeSymbol? TupleUnderlyingType => throw new System.NotImplementedException(); + + public ImmutableArray TupleElements => throw new System.NotImplementedException(); + + public bool IsSerializable => throw new System.NotImplementedException(); + + public INamedTypeSymbol? NativeIntegerUnderlyingType => throw new System.NotImplementedException(); + + public TypeKind TypeKind => throw new System.NotImplementedException(); + + public INamedTypeSymbol? BaseType => throw new System.NotImplementedException(); + + public ImmutableArray Interfaces => throw new System.NotImplementedException(); + + public ImmutableArray AllInterfaces => throw new System.NotImplementedException(); + + public bool IsReferenceType => throw new System.NotImplementedException(); + + public bool IsValueType => throw new System.NotImplementedException(); + + public bool IsAnonymousType => throw new System.NotImplementedException(); + + public bool IsTupleType => throw new System.NotImplementedException(); + + public bool IsNativeIntegerType => throw new System.NotImplementedException(); + + public SpecialType SpecialType => throw new System.NotImplementedException(); + + public bool IsRefLikeType => throw new System.NotImplementedException(); + + public bool IsUnmanagedType => throw new System.NotImplementedException(); + + public bool IsReadOnly => throw new System.NotImplementedException(); + + public bool IsRecord => throw new System.NotImplementedException(); + + public NullableAnnotation NullableAnnotation => throw new System.NotImplementedException(); + + public bool IsNamespace => throw new System.NotImplementedException(); + + public bool IsType => throw new System.NotImplementedException(); + + public SymbolKind Kind => throw new System.NotImplementedException(); + + public string Language => throw new System.NotImplementedException(); + + public string MetadataName => throw new System.NotImplementedException(); + + public int MetadataToken => throw new System.NotImplementedException(); + + public ISymbol ContainingSymbol => throw new System.NotImplementedException(); + + public IAssemblySymbol ContainingAssembly => throw new System.NotImplementedException(); + + public IModuleSymbol ContainingModule => throw new System.NotImplementedException(); + + public INamedTypeSymbol ContainingType => throw new System.NotImplementedException(); + + public INamespaceSymbol ContainingNamespace => throw new System.NotImplementedException(); + + public bool IsDefinition => throw new System.NotImplementedException(); + + public bool IsStatic => throw new System.NotImplementedException(); + + public bool IsVirtual => throw new System.NotImplementedException(); + + public bool IsOverride => throw new System.NotImplementedException(); + + public bool IsAbstract => throw new System.NotImplementedException(); + + public bool IsSealed => throw new System.NotImplementedException(); + + public bool IsExtern => throw new System.NotImplementedException(); + + public bool IsImplicitlyDeclared => throw new System.NotImplementedException(); + + public bool CanBeReferencedByName => throw new System.NotImplementedException(); + + public ImmutableArray Locations => throw new System.NotImplementedException(); + + public ImmutableArray DeclaringSyntaxReferences => throw new System.NotImplementedException(); + + public Accessibility DeclaredAccessibility => throw new System.NotImplementedException(); + + public bool HasUnsupportedMetadata => throw new System.NotImplementedException(); + + ITypeSymbol ITypeSymbol.OriginalDefinition => throw new System.NotImplementedException(); + + ISymbol ISymbol.OriginalDefinition => throw new System.NotImplementedException(); + + public void Accept(SymbolVisitor visitor) => throw new System.NotImplementedException(); + public TResult? Accept(SymbolVisitor visitor) => throw new System.NotImplementedException(); + public TResult Accept(SymbolVisitor visitor, TArgument argument) => throw new System.NotImplementedException(); + public INamedTypeSymbol Construct(params ITypeSymbol[] typeArguments) => throw new System.NotImplementedException(); + public INamedTypeSymbol Construct(ImmutableArray typeArguments, ImmutableArray typeArgumentNullableAnnotations) => throw new System.NotImplementedException(); + public INamedTypeSymbol ConstructUnboundGenericType() => throw new System.NotImplementedException(); + public bool Equals(ISymbol? other, SymbolEqualityComparer equalityComparer) => throw new System.NotImplementedException(); + public bool Equals(ISymbol? other) => throw new System.NotImplementedException(); + public ISymbol? FindImplementationForInterfaceMember(ISymbol interfaceMember) => throw new System.NotImplementedException(); + public ImmutableArray GetAttributes() => throw new System.NotImplementedException(); + public string? GetDocumentationCommentId() => throw new System.NotImplementedException(); + public string? GetDocumentationCommentXml(CultureInfo? preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default) => throw new System.NotImplementedException(); + public ImmutableArray GetMembers() => throw new System.NotImplementedException(); + public ImmutableArray GetMembers(string name) => throw new System.NotImplementedException(); + public ImmutableArray GetTypeArgumentCustomModifiers(int ordinal) => throw new System.NotImplementedException(); + public ImmutableArray GetTypeMembers() => throw new System.NotImplementedException(); + public ImmutableArray GetTypeMembers(string name) => throw new System.NotImplementedException(); + public ImmutableArray GetTypeMembers(string name, int arity) => throw new System.NotImplementedException(); + public ImmutableArray ToDisplayParts(NullableFlowState topLevelNullability, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException(); + public ImmutableArray ToDisplayParts(SymbolDisplayFormat? format = null) => throw new System.NotImplementedException(); + public string ToDisplayString(NullableFlowState topLevelNullability, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException(); + public ImmutableArray ToMinimalDisplayParts(SemanticModel semanticModel, NullableFlowState topLevelNullability, int position, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException(); + public ImmutableArray ToMinimalDisplayParts(SemanticModel semanticModel, int position, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException(); + public string ToMinimalDisplayString(SemanticModel semanticModel, NullableFlowState topLevelNullability, int position, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException(); + public string ToMinimalDisplayString(SemanticModel semanticModel, int position, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException(); + public ITypeSymbol WithNullableAnnotation(NullableAnnotation nullableAnnotation) => throw new System.NotImplementedException(); + } } \ No newline at end of file