Skip to content

Commit

Permalink
Switch to lighter handler type detection in dapper
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kzu committed Dec 21, 2024
1 parent 56e8b94 commit 1b8240f
Showing 1 changed file with 175 additions and 3 deletions.
178 changes: 175 additions & 3 deletions src/StructId.Analyzer/DapperGenerator.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -62,8 +63,14 @@ protected override IncrementalValuesProvider<TemplateArgs> 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<TypeDeclarationSyntax>()
.First()
.Identifier.Text;

// Use lighter symbol since our template rendering only uses the type name.
handler = new KnownTypeNameSymbol(identifier);
}
}

Expand Down Expand Up @@ -152,4 +159,169 @@ record SelectorModel(
IEnumerable<StructIdCustomModel> CustomIds,
IEnumerable<ValueHandlerModel> CustomValues,
IEnumerable<ValueHandlerModelCode> 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<string> MemberNames => throw new System.NotImplementedException();

public ImmutableArray<ITypeParameterSymbol> TypeParameters => throw new System.NotImplementedException();

public ImmutableArray<ITypeSymbol> TypeArguments => throw new System.NotImplementedException();

public ImmutableArray<NullableAnnotation> 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<IMethodSymbol> InstanceConstructors => throw new System.NotImplementedException();

public ImmutableArray<IMethodSymbol> StaticConstructors => throw new System.NotImplementedException();

public ImmutableArray<IMethodSymbol> 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<IFieldSymbol> 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<INamedTypeSymbol> Interfaces => throw new System.NotImplementedException();

public ImmutableArray<INamedTypeSymbol> 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<Location> Locations => throw new System.NotImplementedException();

public ImmutableArray<SyntaxReference> 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<TResult>(SymbolVisitor<TResult> visitor) => throw new System.NotImplementedException();
public TResult Accept<TArgument, TResult>(SymbolVisitor<TArgument, TResult> visitor, TArgument argument) => throw new System.NotImplementedException();
public INamedTypeSymbol Construct(params ITypeSymbol[] typeArguments) => throw new System.NotImplementedException();
public INamedTypeSymbol Construct(ImmutableArray<ITypeSymbol> typeArguments, ImmutableArray<NullableAnnotation> 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<AttributeData> 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<ISymbol> GetMembers() => throw new System.NotImplementedException();
public ImmutableArray<ISymbol> GetMembers(string name) => throw new System.NotImplementedException();
public ImmutableArray<CustomModifier> GetTypeArgumentCustomModifiers(int ordinal) => throw new System.NotImplementedException();
public ImmutableArray<INamedTypeSymbol> GetTypeMembers() => throw new System.NotImplementedException();
public ImmutableArray<INamedTypeSymbol> GetTypeMembers(string name) => throw new System.NotImplementedException();
public ImmutableArray<INamedTypeSymbol> GetTypeMembers(string name, int arity) => throw new System.NotImplementedException();
public ImmutableArray<SymbolDisplayPart> ToDisplayParts(NullableFlowState topLevelNullability, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException();
public ImmutableArray<SymbolDisplayPart> ToDisplayParts(SymbolDisplayFormat? format = null) => throw new System.NotImplementedException();
public string ToDisplayString(NullableFlowState topLevelNullability, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException();
public ImmutableArray<SymbolDisplayPart> ToMinimalDisplayParts(SemanticModel semanticModel, NullableFlowState topLevelNullability, int position, SymbolDisplayFormat? format = null) => throw new System.NotImplementedException();
public ImmutableArray<SymbolDisplayPart> 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();
}
}

0 comments on commit 1b8240f

Please sign in to comment.