Skip to content

Commit

Permalink
[fix] fixed type solver
Browse files Browse the repository at this point in the history
  • Loading branch information
MchKosticyn authored and gsvgit committed Aug 21, 2023
1 parent ab88520 commit e17a434
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 55 deletions.
115 changes: 61 additions & 54 deletions VSharp.SILI.Core/State.fs
Original file line number Diff line number Diff line change
Expand Up @@ -335,69 +335,76 @@ and typeStorage private (constraints, addressesTypes, typeMocks, classesParams,

member x.IsValid with get() = addressesTypes.Count = constraints.Count

and
candidates private(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, mock, userAssembly) =
let orderedTypes = seq {
yield! publicBuiltInTypes
yield! publicUserTypes
yield! privateUserTypes
yield! rest
}
and candidates private(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, mock, userAssembly) =
let orderedTypes = seq {
yield! publicBuiltInTypes
yield! publicUserTypes
yield! privateUserTypes
yield! rest
}

new(types : Type seq, mock: ITypeMock option, userAssembly : Reflection.Assembly) =
let types = Seq.distinct types
let isPublicBuiltIn (t : Type) = TypeUtils.isPublic t && Reflection.isBuiltInType t
let isPublicUser (t: Type) = TypeUtils.isPublic t && t.Assembly = userAssembly
let isPrivateUser (t: Type) = not (TypeUtils.isPublic t) && t.Assembly = userAssembly
let publicBuiltInTypes = types |> Seq.filter isPublicBuiltIn
let publicUserTypes = types |> Seq.filter isPublicUser
let privateUserTypes = types |> Seq.filter isPrivateUser
let predicates = [isPublicBuiltIn; isPublicUser; isPrivateUser]
let rest = List.fold (fun types predicate -> Seq.filter (predicate >> not) types) types predicates
let rest = types |> Seq.filter (isPublicBuiltIn >> not)
let publicUserTypes = rest |> Seq.filter isPublicUser
let rest = rest |> Seq.filter (isPublicUser >> not)
let privateUserTypes = rest |> Seq.filter isPrivateUser
let rest = rest |> Seq.filter (isPrivateUser >> not)
candidates(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, mock, userAssembly)

member x.IsEmpty
with get() =
match mock with
| Some _ -> false
| None -> Seq.isEmpty x.Types

member x.Types =
seq {
yield! orderedTypes |> Seq.map ConcreteType
if mock.IsSome then yield mock.Value |> MockType
}

static member Empty() =
candidates(Seq.empty, None, Reflection.mscorlibAssembly)

member x.Copy(changeMock: ITypeMock -> ITypeMock) =
let newMock =
match mock with
| Some m -> Some (changeMock m)
| None -> None
candidates(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, newMock, userAssembly)

member x.Pick() =
Seq.head x.Types

member x.Filter(typesPredicate, refineMock : ITypeMock -> ITypeMock option) =
let publicBuiltInTypes = Seq.filter typesPredicate publicBuiltInTypes
let publicUserTypes = Seq.filter typesPredicate publicUserTypes
let privateUserTypes = Seq.filter typesPredicate privateUserTypes
let rest = Seq.filter typesPredicate rest
let mock =
match mock with
| Some typeMock -> refineMock typeMock
| None -> None
candidates(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, mock, userAssembly)

member x.IsEmpty
with get() =
match mock with
| Some _ -> false
| None -> Seq.isEmpty x.Types

member x.Types =
seq {
yield! orderedTypes |> Seq.map ConcreteType
if mock.IsSome then yield mock.Value |> MockType
}

static member Empty() =
candidates(Seq.empty, None, Reflection.mscorlibAssembly)

member x.Copy(changeMock: ITypeMock -> ITypeMock) =
let newMock =
match mock with
| Some m -> Some (changeMock m)
| None -> None
candidates(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, newMock, userAssembly)

member x.Pick() =
Seq.head x.Types

member x.Filter(typesPredicate, refineMock : ITypeMock -> ITypeMock option) =
let publicBuiltInTypes = Seq.filter typesPredicate publicBuiltInTypes
let publicUserTypes = Seq.filter typesPredicate publicUserTypes
let privateUserTypes = Seq.filter typesPredicate privateUserTypes
let rest = Seq.filter typesPredicate rest
let mock =
match mock with
| Some typeMock -> refineMock typeMock
| None -> None
candidates(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, mock, userAssembly)

member x.Take(count) =
let types =
match mock with
| Some _ -> Seq.truncate (count - 1) orderedTypes
| None -> Seq.truncate count orderedTypes
candidates(types, mock, userAssembly)
member x.Take(count) =
let types =
match mock with
| Some _ -> Seq.truncate (count - 1) orderedTypes
| None -> Seq.truncate count orderedTypes
candidates(types, mock, userAssembly)

member x.Eval() =
let publicBuiltInTypes = Seq.toList publicBuiltInTypes
let publicUserTypes = Seq.toList publicUserTypes
let privateUserTypes = Seq.toList privateUserTypes
let rest = Seq.toList rest
candidates(publicBuiltInTypes, publicUserTypes, privateUserTypes, rest, mock, userAssembly)

and
[<ReferenceEquality>]
Expand Down
2 changes: 1 addition & 1 deletion VSharp.SILI.Core/TypeSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ module TypeSolver =
let optionMock m = Some m
let filtered = candidates.Filter(checkOverrides, optionMock)
let truncated = filtered.Take(5)
typeStorage[thisAddress] <- truncated
typeStorage[thisAddress] <- truncated.Eval()
truncated.Types
| TypeUnsat -> Seq.empty
| Ref address when Reflection.typeImplementsMethod thisType (ancestorMethod.MethodBase :?> MethodInfo) ->
Expand Down

0 comments on commit e17a434

Please sign in to comment.