Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish runtime model stuff #99

Merged
merged 2 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions EFCore.VisualBasic/Design/Internal/VisualBasicHelper.vb
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,15 @@ Namespace Design.Internal
For i = 0 To name.Length - 1
If Not IsIdentifierPartCharacter(name(i)) Then
If partStart <> i Then
builder.Append(name.Substring(partStart, i - partStart))
builder.Append(name.AsSpan(partStart, i - partStart))
End If

partStart = i + 1
End If
Next

If partStart <> name.Length Then
builder.Append(name.Substring(partStart))
builder.Append(name.AsSpan(partStart))
End If

If builder.Length = 0 Then
Expand All @@ -178,7 +178,9 @@ Namespace Design.Internal
If scope IsNot Nothing Then
Dim uniqueIdentifier = baseIdentifier
Dim qualifier = 0
While scope.Contains(uniqueIdentifier, StringComparer.Create(CultureInfo.InvariantCulture, ignoreCase:=True))

Dim ordinalIgnoreCaseScope As New HashSet(Of String)(scope, StringComparer.OrdinalIgnoreCase)
While ordinalIgnoreCaseScope.Contains(uniqueIdentifier)
uniqueIdentifier = baseIdentifier & qualifier.ToString(CultureInfo.InvariantCulture)
qualifier += 1
End While
Expand Down Expand Up @@ -234,6 +236,7 @@ Namespace Design.Internal
If value Is Nothing Then Return "Nothing"

Return """" & value.Replace("""", """""").
Replace(ChrW(0), """ & ChrW(0) & """).
Replace(vbCrLf, """ & vbCrLf & """).
Replace(vbCr, """ & vbCr & """).
Replace(vbLf, """ & vbLf & """) & """"
Expand All @@ -260,7 +263,18 @@ Namespace Design.Internal
''' directly from your code. This API may change Or be removed in future releases.
''' </summary>
Public Overridable Function Literal(value As Char) As String Implements IVisualBasicHelper.Literal
Return """" & If(value = """", """""", value.ToString()) & """c"
Select Case value
Case """"c
Return """""""""c"
Case ChrW(0)
Return "ChrW(0)"
Case ChrW(10)
Return "ChrW(10)"
Case ChrW(13)
Return "ChrW(13)"
Case Else
Return $"""{value}""c"
End Select
End Function

''' <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ Namespace Design.Query.Internal
Private Shared _activatorCreateInstanceMethod As MethodInfo
Private Shared _typeGetFieldMethod As MethodInfo
Private Shared _fieldGetValueMethod As MethodInfo
Private Shared _AscW As MethodInfo
Private Shared _ChrW As MethodInfo

Private ReadOnly _sideEffectDetector As New SideEffectDetectionSyntaxWalker
Private ReadOnly _g As SyntaxGenerator
Expand Down Expand Up @@ -300,26 +302,11 @@ Namespace Design.Query.Internal

Select Case binary.NodeType
Case ExpressionType.Equal
If Not IsReferenceEqualitySemantics(binary.Left, binary.Right) AndAlso
(binary.Method?.Name = "op_Equality" OrElse binary.Left.Type.IsValueType) Then
Result = New GeneratedSyntaxNodes(
SF.EqualsExpression(left, right))
Else
Result = New GeneratedSyntaxNodes(
SF.IsExpression(left, right))
End If

Result = TranslateEqual(binary, left, right)
Return binary
Case ExpressionType.NotEqual
If Not IsReferenceEqualitySemantics(binary.Left, binary.Right) AndAlso
(binary.Method?.Name = "op_Inequality" OrElse binary.Left.Type.IsValueType) Then
Result = New GeneratedSyntaxNodes(
SF.NotEqualsExpression(left, right))
Else
Result = New GeneratedSyntaxNodes(
SF.IsNotExpression(left, right))
End If

Case ExpressionType.NotEqual
Result = TranslateNotEqual(binary, left, right)
Return binary
End Select

Expand Down Expand Up @@ -476,6 +463,50 @@ Namespace Design.Query.Internal
End Using
End Function

Private Shared Function TranslateEqual(binary As BinaryExpression, left As ExpressionSyntax, right As ExpressionSyntax) As GeneratedSyntaxNodes
If IsNullableValueTypeTestedWithNothing(binary) Then
Return New GeneratedSyntaxNodes(
SF.IsExpression(left, right))
End If

If Not IsReferenceEqualitySemantics(binary.Left, binary.Right) AndAlso
(binary.Method?.Name = "op_Equality" OrElse binary.Left.Type.IsValueType) Then

Return New GeneratedSyntaxNodes(
SF.EqualsExpression(left, right))
End If

Return New GeneratedSyntaxNodes(
SF.IsExpression(left, right))
End Function

Private Shared Function TranslateNotEqual(binary As BinaryExpression, left As ExpressionSyntax, right As ExpressionSyntax) As GeneratedSyntaxNodes
If IsNullableValueTypeTestedWithNothing(binary) Then
Return New GeneratedSyntaxNodes(
SF.IsNotExpression(left, right))
End If

If Not IsReferenceEqualitySemantics(binary.Left, binary.Right) AndAlso
(binary.Method?.Name = "op_Inequality" OrElse binary.Left.Type.IsValueType) Then

Return New GeneratedSyntaxNodes(
SF.NotEqualsExpression(left, right))
End If

Return New GeneratedSyntaxNodes(
SF.IsNotExpression(left, right))
End Function

Private Shared Function IsNullableValueTypeTestedWithNothing(binary As BinaryExpression) As Boolean
Return (binary.Left.Type.IsNullableValueType AndAlso
binary.Right.NodeType = ExpressionType.Constant AndAlso
DirectCast(binary.Right, ConstantExpression).Value Is Nothing) _
OrElse
(binary.Right.Type.IsNullableValueType AndAlso
binary.Left.NodeType = ExpressionType.Constant AndAlso
DirectCast(binary.Left, ConstantExpression).Value Is Nothing)
End Function

Private Function VisitAssignment(assignment As BinaryExpression) As Expression

Dim translatedLeft = Translate(Of ExpressionSyntax)(assignment.Left)
Expand Down Expand Up @@ -2172,9 +2203,9 @@ Namespace Design.Query.Internal
Case ExpressionType.ArrayLength
Result = New GeneratedSyntaxNodes(_g.MemberAccessExpression(operand, "Length"))
Case ExpressionType.Convert
Result = New GeneratedSyntaxNodes(_g.ConvertExpression(Translate(unary.Type), operand))
Result = TranslateConvert(unary, operand)
Case ExpressionType.ConvertChecked
Result = New GeneratedSyntaxNodes(_g.ConvertExpression(Translate(unary.Type), operand))
Result = TranslateConvert(unary, operand)
Case ExpressionType.Throw
Result = New GeneratedSyntaxNodes(_g.ThrowExpression(operand))
Case ExpressionType.TypeAs
Expand Down Expand Up @@ -2216,6 +2247,33 @@ Namespace Design.Query.Internal
Return New GeneratedSyntaxNodes(SF.TryCastExpression(operand, Translate(unary.Type)))
End Function

Private Function TranslateConvert(unary As UnaryExpression, operand As ExpressionSyntax) As GeneratedSyntaxNodes

If unary.Type Is GetType(Integer) AndAlso
unary.Operand.Type Is GetType(Char) Then

If _AscW Is Nothing Then
_AscW = GetType(Strings).GetMethod(NameOf(Microsoft.VisualBasic.AscW), {GetType(Char)})
End If

Return Translate(E.Call(_AscW, unary.Operand))
End If

If unary.Type Is GetType(Char) AndAlso
unary.Operand.Type Is GetType(Integer) Then

If _ChrW Is Nothing Then
_ChrW = GetType(Strings).GetMethod(NameOf(Microsoft.VisualBasic.ChrW), {GetType(Integer)})
End If

Return Translate(E.Call(_ChrW, unary.Operand))
End If

Return New GeneratedSyntaxNodes(
SF.CTypeExpression(operand, Translate(unary.Type)).
WithAdditionalAnnotations(Simplification.Simplifier.Annotation))
End Function

''' <inheritdoc/>
Protected Overrides Function VisitMemberInit(memberInit As MemberInitExpression) As Expression
Dim objectCreation = Translate(Of ObjectCreationExpressionSyntax)(memberInit.NewExpression)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ Namespace Design.AnnotationCodeGeneratorProvider
GenerateSimpleAnnotation(RelationalAnnotationNames.RelationalModel, "CreateRelationalModel()", parameters)

Dim MethodBuilder As New IndentedStringBuilder()
Create(relationalModel,
parameters.Cloner.
WithMainBuilder(parameters.MethodBuilder).
WithMethodBuilder(MethodBuilder).
WithScopeVariables(New HashSet(Of String)).
Clone)
Create(
relationalModel,
parameters.Cloner.
WithMainBuilder(parameters.MethodBuilder).
WithMethodBuilder(MethodBuilder).
WithScopeVariables(New HashSet(Of String)).
Clone)

Dim methods = MethodBuilder.ToString()
If Not String.IsNullOrEmpty(methods) Then
Expand Down Expand Up @@ -233,7 +234,8 @@ Namespace Design.AnnotationCodeGeneratorProvider
AppendLine().
AppendLine($"Dim {deleteSprocMappingsVariable} As New List(Of StoredProcedureMapping)()").
Append($"{typeBaseVariable}.SetRuntimeAnnotation(").
AppendLine($"{VBCode.Literal(RelationalAnnotationNames.DeleteStoredProcedureMappings)}, {deleteSprocMappingsVariable})")
AppendLine(
$"{VBCode.Literal(RelationalAnnotationNames.DeleteStoredProcedureMappings)}, {deleteSprocMappingsVariable})")
For Each mapping In typeBase.GetDeleteStoredProcedureMappings()
Create(
mapping,
Expand All @@ -250,7 +252,8 @@ Namespace Design.AnnotationCodeGeneratorProvider
AppendLine().
AppendLine($"Dim {insertSprocMappingsVariable} As New List(Of StoredProcedureMapping)()").
Append($"{typeBaseVariable}.SetRuntimeAnnotation(").
AppendLine($"{VBCode.Literal(RelationalAnnotationNames.InsertStoredProcedureMappings)}, {insertSprocMappingsVariable})")
AppendLine(
$"{VBCode.Literal(RelationalAnnotationNames.InsertStoredProcedureMappings)}, {insertSprocMappingsVariable})")
For Each mapping In typeBase.GetInsertStoredProcedureMappings()
Create(
mapping,
Expand All @@ -267,7 +270,8 @@ Namespace Design.AnnotationCodeGeneratorProvider
AppendLine().
AppendLine($"Dim {updateSprocMappingsVariable} As New List(Of StoredProcedureMapping)()").
Append($"{typeBaseVariable}.SetRuntimeAnnotation(").
AppendLine($"{VBCode.Literal(RelationalAnnotationNames.UpdateStoredProcedureMappings)}, {updateSprocMappingsVariable})")
AppendLine(
$"{VBCode.Literal(RelationalAnnotationNames.UpdateStoredProcedureMappings)}, {updateSprocMappingsVariable})")
For Each mapping In typeBase.GetUpdateStoredProcedureMappings()
Create(
mapping,
Expand Down Expand Up @@ -639,7 +643,8 @@ Namespace Design.AnnotationCodeGeneratorProvider

mainBuilder.
Append($"{parameters.TargetName}.StoredProcedures.Add(").
AppendLine($"({code.Literal(storeStoredProcedure.Name)}, {code.Literal(storeStoredProcedure.Schema)}), {storedProcedureVariable})")
AppendLine(
$"({code.Literal(storeStoredProcedure.Name)}, {code.Literal(storeStoredProcedure.Schema)}), {storedProcedureVariable})")

Return storedProcedureVariable
End Function
Expand Down Expand Up @@ -1039,9 +1044,10 @@ Namespace Design.AnnotationCodeGeneratorProvider
AppendLine($"Dim {tableIndexVariable} = RelationalModel.GetIndex(Me,").
IncrementIndent().
AppendLine($"{code.Literal(mappedIndex.DeclaringEntityType.Name)},").
AppendLine($"{If(mappedIndex.Name Is Nothing,
code.Literal(mappedIndex.Properties.Select(Function(p) p.Name).ToArray()),
code.Literal(mappedIndex.Name))})").
AppendLine(
$"{If(mappedIndex.Name Is Nothing,
code.Literal(mappedIndex.Properties.Select(Function(p) p.Name).ToArray()),
code.Literal(mappedIndex.Name))})").
DecrementIndent()

mainBuilder.AppendLine($"{indexVariable}.MappedIndexes.Add({tableIndexVariable})")
Expand Down Expand Up @@ -1103,13 +1109,15 @@ Namespace Design.AnnotationCodeGeneratorProvider
AppendLine($"{code.Literal(mappedForeignKey.PrincipalKey.Properties.Select(Function(p) p.Name).ToArray())})").
DecrementIndent()

mainBuilder.AppendLine($"{foreignKeyConstraintVariable}.MappedForeignKeys.Add({foreignKeyVariable})")
mainBuilder.AppendLine($"RelationalModel.GetOrCreateForeignKeyConstraints({foreignKeyVariable}).Add({foreignKeyConstraintVariable})")
mainBuilder.
AppendLine($"{foreignKeyConstraintVariable}.MappedForeignKeys.Add({foreignKeyVariable})").
AppendLine(
$"RelationalModel.GetOrCreateForeignKeyConstraints({foreignKeyVariable}).Add({foreignKeyConstraintVariable})")
Next

mainBuilder.
AppendLine($"{metadataVariables(foreignKey.Table)}.ForeignKeyConstraints.Add({foreignKeyConstraintVariable})").
AppendLine($"{principalTableVariable}.ReferencingForeignKeyConstraints.Add({foreignKeyConstraintVariable})")
AppendLine($"{metadataVariables(foreignKey.Table)}.ForeignKeyConstraints.Add({foreignKeyConstraintVariable})").
AppendLine($"{principalTableVariable}.ReferencingForeignKeyConstraints.Add({foreignKeyConstraintVariable})")
End Sub

''' <summary>
Expand Down Expand Up @@ -1153,7 +1161,7 @@ Namespace Design.AnnotationCodeGeneratorProvider

For Each columnMapping In tableMapping.ColumnMappings
mainBuilder.
Append($"RelationalModel.CreateColumnMapping(").
Append("RelationalModel.CreateColumnMapping(").
Append($"DirectCast({metadataVariables(columnMapping.Column)}, ColumnBase(Of ColumnMappingBase)), ").
Append($"{typeBaseVariable}.FindProperty({code.Literal(columnMapping.Property.Name)}), ").
Append(tableMappingVariable).AppendLine(")"c)
Expand Down Expand Up @@ -1512,7 +1520,7 @@ Namespace Design.AnnotationCodeGeneratorProvider
For Each internalForeignKey In table.GetRowInternalForeignKeys(entityType)
mainBuilder.
Append(tableVariable).Append($".AddRowInternalForeignKey({entityTypeVariable}, ").
AppendLine($"RelationalModel.GetForeignKey(Me,").
AppendLine("RelationalModel.GetForeignKey(Me,").
IncrementIndent().
AppendLine($"{code.Literal(internalForeignKey.DeclaringEntityType.Name)},").
AppendLine($"{code.Literal(internalForeignKey.Properties.Select(Function(p) p.Name).ToArray())},").
Expand Down Expand Up @@ -2290,7 +2298,17 @@ Namespace Design.AnnotationCodeGeneratorProvider
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
Dim isUnicodeDifferent = relationalTypeMapping.IsUnicode <> defaultInstance.IsUnicode

Dim isFixedLengthDifferent = relationalTypeMapping.IsFixedLength <> defaultInstance.IsFixedLength

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

AddNamespace(GetType(RelationalTypeMappingInfo), parameters.Namespaces)
mainBuilder.
Expand All @@ -2308,6 +2326,16 @@ Namespace Design.AnnotationCodeGeneratorProvider
"size", code.Literal(relationalTypeMapping.Size), mainBuilder, firstParameter)
End If

If isUnicodeDifferent Then
GenerateArgument(
"unicode", code.Literal(relationalTypeMapping.IsUnicode), mainBuilder, firstParameter)
End If

If isFixedLengthDifferent Then
GenerateArgument(
"fixedLength", code.Literal(relationalTypeMapping.IsFixedLength), mainBuilder, firstParameter)
End If

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