Skip to content

Commit

Permalink
Use reflection to call CoreTypeMapping.Clone()
Browse files Browse the repository at this point in the history
  • Loading branch information
lorcQc committed Feb 7, 2024
1 parent cdd5348 commit 6912fc0
Show file tree
Hide file tree
Showing 6 changed files with 6,097 additions and 4,410 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Imports System.Linq.Expressions
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax

Namespace Design.Query.Internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2233,125 +2233,159 @@ Namespace Design.AnnotationCodeGeneratorProvider
Return True
End If

parameters.Namespaces.Add(GetType(Type).Namespace)
parameters.Namespaces.Add(GetType(BindingFlags).Namespace)

Dim cloneMethod = GetCloneMethod(typeMapping.GetType(), {
"comparer",
"keyComparer",
"providerValueComparer",
"mappingInfo",
"converter",
"clrType",
"storeTypePostfix",
"jsonValueReaderWriter",
"elementMapping"
})

parameters.Namespaces.Add(cloneMethod.DeclaringType.Namespace)

mainBuilder.
AppendLine(".Clone(").
AppendLine($"DirectCast(GetType({code.Reference(cloneMethod.DeclaringType)}).").
IncrementIndent().
AppendLine($"GetMethod(""Clone"", BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly).").
AppendLine($"Invoke({code.Reference(typeMapping.GetType())}.Default, {{").
IncrementIndent()

mainBuilder.Append("comparer:=")
Create(If(valueComparer, relationalTypeMapping.Comparer), parameters, code)
Dim first = True
For Each p In cloneMethod.GetParameters()
If first Then
first = False
Else
mainBuilder.AppendLine(","c)
End If

mainBuilder.
AppendLine(","c).
Append("keyComparer:=")
Select Case p.Name
Case "comparer"
Create(If(valueComparer, relationalTypeMapping.Comparer), parameters, code)

Create(If(keyValueComparer, relationalTypeMapping.KeyComparer), parameters, code)
Case "keyComparer"
Create(If(keyValueComparer, relationalTypeMapping.KeyComparer), parameters, code)

mainBuilder.
AppendLine(","c).
Append("providerValueComparer:=")

Create(If(providerValueComparer, relationalTypeMapping.ProviderValueComparer), parameters, code)
Case "providerValueComparer"
Create(If(providerValueComparer, relationalTypeMapping.ProviderValueComparer), parameters, code)

Dim storeTypeDifferent = relationalTypeMapping.StoreType <> defaultInstance.StoreType
Case "mappingInfo"
Dim storeTypeDifferent = relationalTypeMapping.StoreType <> defaultInstance.StoreType

Dim sizeDifferent = relationalTypeMapping.Size.HasValue AndAlso
(Not defaultInstance.Size.HasValue OrElse relationalTypeMapping.Size.Value <> defaultInstance.Size.Value)
Dim sizeDifferent = relationalTypeMapping.Size.HasValue AndAlso
(Not defaultInstance.Size.HasValue OrElse relationalTypeMapping.Size.Value <> defaultInstance.Size.Value)

Dim precisionDifferent = relationalTypeMapping.Precision.HasValue AndAlso
(Not defaultInstance.Precision.HasValue OrElse relationalTypeMapping.Precision.Value <> defaultInstance.Precision.Value)
Dim precisionDifferent = relationalTypeMapping.Precision.HasValue AndAlso
(Not defaultInstance.Precision.HasValue OrElse relationalTypeMapping.Precision.Value <> defaultInstance.Precision.Value)

Dim scaleDifferent = relationalTypeMapping.Scale.HasValue AndAlso
(Not defaultInstance.Scale.HasValue OrElse relationalTypeMapping.Scale.Value <> defaultInstance.Scale.Value)
Dim scaleDifferent = relationalTypeMapping.Scale.HasValue AndAlso
(Not defaultInstance.Scale.HasValue OrElse relationalTypeMapping.Scale.Value <> defaultInstance.Scale.Value)

Dim dbTypeDifferent = relationalTypeMapping.DbType.HasValue AndAlso
(Not defaultInstance.DbType.HasValue OrElse relationalTypeMapping.DbType.Value <> defaultInstance.DbType.Value)
Dim dbTypeDifferent = relationalTypeMapping.DbType.HasValue AndAlso
(Not defaultInstance.DbType.HasValue OrElse relationalTypeMapping.DbType.Value <> defaultInstance.DbType.Value)

If storeTypeDifferent OrElse sizeDifferent OrElse precisionDifferent OrElse scaleDifferent OrElse dbTypeDifferent Then
If storeTypeDifferent OrElse sizeDifferent OrElse precisionDifferent OrElse scaleDifferent OrElse dbTypeDifferent Then

AddNamespace(GetType(RelationalTypeMappingInfo), parameters.Namespaces)
mainBuilder.
AppendLine(","c).
AppendLine("mappingInfo:=New RelationalTypeMappingInfo(").
IncrementIndent()
AddNamespace(GetType(RelationalTypeMappingInfo), parameters.Namespaces)
mainBuilder.
AppendLine("New RelationalTypeMappingInfo(").
IncrementIndent()

Dim firstParameter = True
If storeTypeDifferent Then
GenerateArgument(
"storeTypeName", code.Literal(relationalTypeMapping.StoreType), mainBuilder, firstParameter)
End If
Dim firstParameter = True
If storeTypeDifferent Then
GenerateArgument(
"storeTypeName", code.Literal(relationalTypeMapping.StoreType), mainBuilder, firstParameter)
End If

If sizeDifferent Then
GenerateArgument(
"size", code.Literal(relationalTypeMapping.Size), mainBuilder, firstParameter)
End If
If sizeDifferent Then
GenerateArgument(
"size", code.Literal(relationalTypeMapping.Size), mainBuilder, firstParameter)
End If

If precisionDifferent Then
GenerateArgument(
"precision", code.Literal(relationalTypeMapping.Precision), mainBuilder, firstParameter)
End If
If precisionDifferent Then
GenerateArgument(
"precision", code.Literal(relationalTypeMapping.Precision), mainBuilder, firstParameter)
End If

If scaleDifferent Then
GenerateArgument(
"scale", code.Literal(relationalTypeMapping.Scale), mainBuilder, firstParameter)
End If
If scaleDifferent Then
GenerateArgument(
"scale", code.Literal(relationalTypeMapping.Scale), mainBuilder, firstParameter)
End If

If dbTypeDifferent Then
GenerateArgument(
"dbType", code.Literal(relationalTypeMapping.DbType.Value, fullName:=True), mainBuilder, firstParameter)
End If
If dbTypeDifferent Then
GenerateArgument(
"dbType", code.Literal(relationalTypeMapping.DbType.Value, fullName:=True), mainBuilder, firstParameter)
End If

mainBuilder.
Append(")"c).
DecrementIndent()
End If
mainBuilder.
Append(")"c).
DecrementIndent()
Else
mainBuilder.Append("Type.Missing")
End If

If relationalTypeMapping.Converter IsNot Nothing AndAlso
relationalTypeMapping.Converter IsNot defaultInstance.Converter Then
mainBuilder.
AppendLine(","c).
Append("converter:=")
Case "converter"
If relationalTypeMapping.Converter IsNot Nothing AndAlso
relationalTypeMapping.Converter IsNot defaultInstance.Converter Then

Create(relationalTypeMapping.Converter, parameters, code)
End If
Create(relationalTypeMapping.Converter, parameters, code)
Else
mainBuilder.Append("Type.Missing")
End If

Dim typeDifferent = relationalTypeMapping.Converter Is Nothing AndAlso
Case "clrType"
Dim typeDifferent = relationalTypeMapping.Converter Is Nothing AndAlso
relationalTypeMapping.ClrType <> defaultInstance.ClrType

If typeDifferent Then
mainBuilder.
AppendLine(","c).
Append($"clrType:={code.Literal(relationalTypeMapping.ClrType)}")
End If

Dim storeTypePostfixDifferent = relationalTypeMapping.StoreTypePostfix <> defaultInstance.StoreTypePostfix

If storeTypePostfixDifferent Then
mainBuilder.
AppendLine(","c).
Append($"storeTypePostfix:={code.Literal(DirectCast(relationalTypeMapping.StoreTypePostfix, [Enum]))}")
End If

If relationalTypeMapping.JsonValueReaderWriter IsNot Nothing AndAlso
relationalTypeMapping.JsonValueReaderWriter IsNot defaultInstance.JsonValueReaderWriter Then
mainBuilder.
AppendLine(","c).
Append("jsonValueReaderWriter:=")

CreateJsonValueReaderWriter(relationalTypeMapping.JsonValueReaderWriter, parameters, code)
End If

If relationalTypeMapping.ElementTypeMapping IsNot Nothing AndAlso
relationalTypeMapping.ElementTypeMapping IsNot defaultInstance.ElementTypeMapping Then

mainBuilder.
AppendLine(","c).
Append("elementMapping:=")

Create(relationalTypeMapping.ElementTypeMapping, parameters)
End If
If typeDifferent Then
mainBuilder.
Append(code.Literal(relationalTypeMapping.ClrType))
Else
mainBuilder.Append("Type.Missing")
End If

Case "storeTypePostfix"
Dim storeTypePostfixDifferent = relationalTypeMapping.StoreTypePostfix <> defaultInstance.StoreTypePostfix

If storeTypePostfixDifferent Then
mainBuilder.
Append(code.Literal(DirectCast(relationalTypeMapping.StoreTypePostfix, [Enum])))
Else
mainBuilder.Append("Type.Missing")
End If

Case "jsonValueReaderWriter"
If relationalTypeMapping.JsonValueReaderWriter IsNot Nothing AndAlso
relationalTypeMapping.JsonValueReaderWriter IsNot defaultInstance.JsonValueReaderWriter Then

CreateJsonValueReaderWriter(relationalTypeMapping.JsonValueReaderWriter, parameters, code)
Else
mainBuilder.Append("Type.Missing")
End If

Case "elementMapping"
If relationalTypeMapping.ElementTypeMapping IsNot Nothing AndAlso
relationalTypeMapping.ElementTypeMapping IsNot defaultInstance.ElementTypeMapping Then

Create(relationalTypeMapping.ElementTypeMapping, parameters)
Else
mainBuilder.Append("Type.Missing")
End If

Case Else
mainBuilder.Append("Type.Missing")
End Select
Next

mainBuilder.
Append(")"c).
Append("}), CoreTypeMapping)").
DecrementIndent().
DecrementIndent()

Return True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Namespace Design.AnnotationCodeGeneratorProvider
End If

MyBase.Generate(index, parameters)
End Sub
End Sub

''' <inheritdoc />
Public Overrides Sub Generate(aKey As IKey, parameters As VisualBasicRuntimeAnnotationCodeGeneratorParameters)
Expand Down
Loading

0 comments on commit 6912fc0

Please sign in to comment.