Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
975120b
replaced GetCombinedTypeResolution with a more general method that pe…
Mar 30, 2020
3b32b6e
one more case to handle
Mar 30, 2020
f8e68ca
doc comment
Mar 30, 2020
1554db0
add a stump for cycle verification
Mar 31, 2020
398e304
setting up some tests
Mar 31, 2020
991c0cb
found and fixed a bug
Apr 1, 2020
4cdfc53
found and fixed another edge case
Apr 1, 2020
f645786
more tests - the current setup would require checking for each node i…
Apr 1, 2020
8bc17c9
Update src/QsCompiler/Transformations/ClassicallyControlled.cs
bettinaheim Apr 6, 2020
0f85ec3
review comment
Apr 6, 2020
dd53a87
doc comment
Apr 6, 2020
20dc213
more review comments
Apr 6, 2020
74979a7
Merge branch 'beheim/typeResDicts' of https://github.com/microsoft/qs…
Apr 6, 2020
a64a849
Update src/QsCompiler/Transformations/CallGraphWalker.cs
bettinaheim Apr 6, 2020
e90082a
Update src/QsCompiler/Transformations/CallGraphWalker.cs
bettinaheim Apr 6, 2020
5454320
adapting comment
Apr 6, 2020
1b02244
Merge branch 'beheim/typeResDicts' of https://github.com/microsoft/qs…
Apr 6, 2020
0d84170
test
Apr 6, 2020
92fee03
two more tests
Apr 6, 2020
8d68acd
comments
Apr 6, 2020
9f72a99
renaming
Apr 7, 2020
3c8a874
splitting tests into individual tests
Apr 7, 2020
ea7e68e
splitting out inconsistent resolution to native check
Apr 7, 2020
1a10823
helpful comment
Apr 7, 2020
83d089d
separate loops
Apr 7, 2020
602f4d5
disabling test as not yet supported for now
Apr 7, 2020
6866ca7
conflict resolution
Apr 10, 2020
0128937
removing tests for parent independent case
Apr 10, 2020
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
2 changes: 1 addition & 1 deletion src/QsCompiler/Core/ConstructorExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ type TypedExpression with
/// the ResolvedType is set to the type constructed by resolving it using ResolveTypeParameters and the given look-up.
static member New (expr, typeParamResolutions : ImmutableDictionary<_,_>, exType, exInfo, range) = {
Expression = expr
TypeArguments = typeParamResolutions |> Seq.map (fun kv -> fst kv.Key, snd kv.Key, kv.Value) |> ImmutableArray.CreateRange
TypeArguments = typeParamResolutions |> TypedExpression.AsTypeArguments
ResolvedType = ResolvedType.ResolveTypeParameters typeParamResolutions exType
InferredInformation = exInfo
Range = range
Expand Down
5 changes: 5 additions & 0 deletions src/QsCompiler/DataStructures/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,11 @@ type TypedExpression = {
member this.TypeParameterResolutions =
this.TypeArguments.ToImmutableDictionary((fun (origin, name, _) -> origin, name), (fun (_,_,t) -> t))

/// Given a dictionary containing the type resolutions for an expression,
/// returns the corresponding ImmutableArray to initialize the TypeArguments with.
static member AsTypeArguments (typeParamResolutions : ImmutableDictionary<_,_>) =
typeParamResolutions |> Seq.map (fun kv -> fst kv.Key, snd kv.Key, kv.Value) |> ImmutableArray.CreateRange

/// Returns true if the expression is a call-like expression, and the arguments contain a missing expression.
/// Returns false otherwise.
static member public IsPartialApplication kind =
Expand Down
4 changes: 2 additions & 2 deletions src/QsCompiler/SyntaxProcessor/SyntaxExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ and private SymbolsFromExpr item : QsSymbol list * QsType list * QsExpression li
| QsExpressionKind.InvalidExpr -> [], [], [item]

let private AttributeAsCallExpr (sym : QsSymbol, ex : QsExpression) =
let compinedRange = QsPositionInfo.CombinedRange (sym.Range, ex.Range)
let combinedRange = QsPositionInfo.CombinedRange (sym.Range, ex.Range)
let id = {Expression = QsExpressionKind.Identifier (sym, Null); Range = sym.Range}
{Expression = QsExpressionKind.CallLikeExpression(id, ex); Range = compinedRange}
{Expression = QsExpressionKind.CallLikeExpression(id, ex); Range = combinedRange}

let rec private SymbolDeclarations (sym : QsSymbol) =
match sym.Symbol with
Expand Down
306 changes: 306 additions & 0 deletions src/QsCompiler/Tests.Compiler/CallGraphTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Quantum.QsCompiler.Testing

open System
open System.Collections.Generic
open System.Collections.Immutable
open Microsoft.Quantum.QsCompiler.DataTypes
open Microsoft.Quantum.QsCompiler.SyntaxExtensions
open Microsoft.Quantum.QsCompiler.SyntaxTokens
open Microsoft.Quantum.QsCompiler.SyntaxTree
open Microsoft.Quantum.QsCompiler.Transformations
open Xunit
open Xunit.Abstractions


type CallGraphTests (output:ITestOutputHelper) =

let qualifiedName name =
("NS" |> NonNullable<string>.New, name |> NonNullable<string>.New) |> QsQualifiedName.New

let typeParameter (id : string) =
let pieces = id.Split(".")
Assert.True(pieces.Length = 2)
let parent = qualifiedName pieces.[0]
let name = pieces.[1] |> NonNullable<string>.New
QsTypeParameter.New (parent, name, Null)

let resolution (res : (QsTypeParameter * QsTypeKind<_,_,_,_>) list) =
res.ToImmutableDictionary((fun (tp,_) -> tp.Origin, tp.TypeName), snd >> ResolvedType.New)

let Foo = qualifiedName "Foo"
let Bar = qualifiedName "Bar"

let FooA = typeParameter "Foo.A"
let FooB = typeParameter "Foo.B"
let BarA = typeParameter "Bar.A"
let BarC = typeParameter "Bar.C"
let BazA = typeParameter "Baz.A"

static member CheckResolution (parent, expected : IDictionary<_,_>, [<ParamArray>] resolutions) =
let expectedKeys = ImmutableHashSet.CreateRange(expected.Keys)
let compareWithExpected (d : ImmutableDictionary<_,_>) =
let keysMismatch = expectedKeys.SymmetricExcept d.Keys
keysMismatch.Count = 0 && expected |> Seq.exists (fun kv -> d.[kv.Key] <> kv.Value) |> not
let mutable combined = ImmutableDictionary.Empty
let success = CallGraph.TryCombineTypeResolutions(parent, &combined, resolutions)
Assert.True(compareWithExpected combined, "combined resolutions did not match the expected ones")
success

static member AssertResolution (parent, expected, [<ParamArray>] resolutions) =
let success = CallGraphTests.CheckResolution (parent, expected, resolutions)
Assert.True(success, "Combining type resolutions was not successful.")

static member AssertResolutionFailure (parent, expected, [<ParamArray>] resolutions) =
let success = CallGraphTests.CheckResolution (parent, expected, resolutions)
Assert.False(success, "Combining type resolutions should have failed.")


[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: resolution to concrete`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
(FooB, Int)
]
let res2 = resolution [
(BarA, Int)
]
let expected = resolution [
(FooA, Int)
(FooB, Int)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: resolution to type parameter`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, BazA |> TypeParameter)
]
let expected = resolution [
(FooA, BazA |> TypeParameter)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: resolution via identity mapping`` () =

let res1 = resolution [
(FooA, FooA |> TypeParameter)
]
let res2 = resolution [
(FooA, Int)
]
let expected = resolution [
(FooA, Int)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: multi-stage resolution`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, Int)
(FooB, Int)
]
let expected = resolution [
(FooA, Int)
(FooB, Int)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: multiple resolutions to concrete`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
(FooB, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, Int)
]
let expected = resolution [
(FooA, Int)
(FooB, Int)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: multiple resolutions to type parameter`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
(FooB, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, BazA |> TypeParameter)
]
let res3 = resolution [
(BazA, Double)
]
let expected = resolution [
(FooA, Double)
(FooB, Double)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2, res3)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: multi-stage resolution of multiple resolutions to concrete`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(FooB, BarA |> TypeParameter)
]
let res3 = resolution [
(BarA, Int)
]
let expected = resolution [
(FooA, Int)
(FooB, Int)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2, res3)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: redundant resolution to concrete`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, Int)
(FooA, Int)
]
let expected = resolution [
(FooA, Int)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: redundant resolution to type parameter`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, BazA |> TypeParameter)
]
let res3 = resolution [
(FooA, BazA |> TypeParameter)
]
let expected = resolution [
(FooA, BazA |> TypeParameter)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2, res3)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: conflicting resolution to concrete`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, Int)
(FooA, Double)
]
let expected = resolution [
(FooA, Double)
]
CallGraphTests.AssertResolutionFailure(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: conflicting resolution to type parameter`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, BazA |> TypeParameter)
(FooA, BarC |> TypeParameter)
]
let expected = resolution [
(FooA, BarC |> TypeParameter)
]
CallGraphTests.AssertResolutionFailure(Foo, expected, res1, res2)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: direct resolution to native`` () =

let res1 = resolution [
(FooA, FooA |> TypeParameter)
]
let expected = resolution [
(FooA, FooA |> TypeParameter)
]
CallGraphTests.AssertResolution(Foo, expected, res1)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: indirect resolution to native`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, BazA |> TypeParameter)
]
let res3 = resolution [
(BazA, FooA |> TypeParameter)
]
let expected = resolution [
(FooA, FooA |> TypeParameter)
]
CallGraphTests.AssertResolution(Foo, expected, res1, res2, res3)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: direct resolution constrains native`` () =

let res1 = resolution [
(FooA, FooB |> TypeParameter)
]
let expected = resolution [
(FooA, FooB |> TypeParameter)
]
CallGraphTests.AssertResolutionFailure(Foo, expected, res1)

[<Fact>]
[<Trait("Category","Type resolution")>]
member this.``Type resolution: indirect resolution constrains native`` () =

let res1 = resolution [
(FooA, BarA |> TypeParameter)
]
let res2 = resolution [
(BarA, BazA |> TypeParameter)
]
let res3 = resolution [
(BazA, FooB |> TypeParameter)
]
let expected = resolution [
(FooA, FooB |> TypeParameter)
]
CallGraphTests.AssertResolutionFailure(Foo, expected, res1, res2, res3)

5 changes: 2 additions & 3 deletions src/QsCompiler/Tests.Compiler/Tests.Compiler.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
<Compile Include="TransformationTests.fs" />
<Compile Include="ExecutionTests.fs" />
<Compile Include="LinkingTests.fs" />
<Compile Include="CallGraphTests.fs" />
<Compile Include="ClassicalControlTests.fs" />
<Compile Include="RegexTests.fs" />
<Compile Include="SerializationTests.fs" />
Expand Down Expand Up @@ -179,9 +180,7 @@
<ExecutionTarget>$(MSBuildThisFileDirectory)..\TestTargets\Simulation\Example\bin\$(Configuration)\netcoreapp3.1\Example.dll</ExecutionTarget>
<LibraryTarget>$(MSBuildThisFileDirectory)..\TestTargets\Libraries\Library1\bin\$(Configuration)\netcoreapp3.1\Library1.dll</LibraryTarget>
</PropertyGroup>
<WriteLinesToFile File="$(OutputPath)ReferenceTargets.txt"
Lines="$(ExecutionTarget); $(LibraryTarget)"
Overwrite="true" />
<WriteLinesToFile File="$(OutputPath)ReferenceTargets.txt" Lines="$(ExecutionTarget); $(LibraryTarget)" Overwrite="true" />
</Target>

</Project>
2 changes: 1 addition & 1 deletion src/QsCompiler/TextProcessor/QsKeywords.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let private addFragmentHeader word =
_FragmentHeaders.Add word |> ignore
qsKeyword word

/// Given the keyword for two functors, constructs and returns the keyword for the compined functor
/// Given the keyword for two functors, constructs and returns the keyword for the combined functor
/// under the assumption tha the order of the functors does not matter.
/// Adds the keyword for the combined functor to the list of QsReservedKeywords, QsLanguageKeywords and QsFragmentHeaders.
let private addFunctorCombination (word1 : QsKeyword, word2 : QsKeyword) =
Expand Down
4 changes: 2 additions & 2 deletions src/QsCompiler/TextProcessor/QsTypeParsing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ let private characteristicsExpression = new OperatorPrecedenceParser<Characteris
/// builds the corresponding expression with its range set to the combined range.
/// If either one of given ranges is Null, builds an invalid expression with its range set to Null.
let private buildCombinedExpression kind (lRange, rRange) =
QsPositionInfo.WithCombinedRange (lRange, rRange) kind InvalidSetExpr |> Characteristics.New // *needs* to be invalid if the compined range is Null!
QsPositionInfo.WithCombinedRange (lRange, rRange) kind InvalidSetExpr |> Characteristics.New // *needs* to be invalid if the combined range is Null!

let private applyBinary operator _ (left : Characteristics) (right : Characteristics) =
buildCombinedExpression (operator (left, right)) (left.Range, right.Range)
Expand Down Expand Up @@ -186,7 +186,7 @@ let internal typeParser tupleType =
]
let buildArrays p =
let combine kind (lRange, rRange) =
QsPositionInfo.WithCombinedRange (lRange, rRange) kind InvalidType |> QsType.New // *needs* to be invalid if the compined range is Null!
QsPositionInfo.WithCombinedRange (lRange, rRange) kind InvalidType |> QsType.New // *needs* to be invalid if the combined range is Null!
let rec applyArrays (t : QsType, item) =
match item with
| [] -> t
Expand Down
2 changes: 1 addition & 1 deletion src/QsCompiler/TextProcessor/SyntaxExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type QsPositionInfo with
static member Range (pos1, pos2) =
Value (QsPositionInfo.New pos1, QsPositionInfo.New pos2)

/// If the given right and left range both have contain a Value, returns the given kind as well as a Value with the compined range.
/// If the given right and left range both have contain a Value, returns the given kind as well as a Value with the combined range.
/// Returns the given fallback and Null otherwise.
static member WithCombinedRange (lRange, rRange) kind fallback =
match (lRange, rRange) with
Expand Down
Loading