Play

Check-in [a7c9bebc32]
Login
Overview
Comment:Prepare data structures and add test for returning modules to load from qualifier step.
Timelines: family | ancestors | descendants | both | modules
Files: files | file ages | folders
SHA3-256: a7c9bebc321bb95e27b0102ef93ac19a4dbed24256ad05880403a7ce904eb019
User & Date: robin.hansen on 2021-02-09 09:40:10
Other Links: branch diff | manifest | tags
Context
2021-02-09
11:27
Turn tuple into record in preperation of registering words which requires loading additional modules... check-in: 7eff2f2dbd user: robin.hansen tags: modules
09:40
Prepare data structures and add test for returning modules to load from qualifier step. check-in: a7c9bebc32 user: robin.hansen tags: modules
2021-02-07
12:02
Qualify member types of structs. check-in: e503e3ec36 user: robin.hansen tags: modules
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/Qualifier.elm from [661a5ac53d] to [caaf815568].

11
12
13
14
15
16
17



18
19
20
21
22
23
24
..
90
91
92
93
94
95
96



97
98
99
100
101
102
103
import Result.Extra as Result
import Set exposing (Set)


type alias AST =
    { types : Dict String TypeDefinition
    , words : Dict String WordDefinition



    }


type TypeDefinition
    = CustomTypeDef String SourceLocationRange (List String) (List ( String, Type ))
    | UnionTypeDef String SourceLocationRange (List String) (List Type)

................................................................................
            Dict.foldl (\_ val acc -> qualifyDefinition config qualifiedTypes val acc) ( [], Dict.empty ) config.ast.words
    in
    case ( typeErrors, wordErrors ) of
        ( [], [] ) ->
            Ok
                { types = qualifiedTypes
                , words = qualifiedWords



                }

        _ ->
            Err <| typeErrors ++ wordErrors


resolveUnionInTypeDefs : Dict String TypeDefinition -> TypeDefinition -> TypeDefinition







>
>
>







 







>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import Result.Extra as Result
import Set exposing (Set)


type alias AST =
    { types : Dict String TypeDefinition
    , words : Dict String WordDefinition
    , additionalModulesRequired : Set String
    , checkForExistingTypes : Set String
    , checkForExistingWords : Set String
    }


type TypeDefinition
    = CustomTypeDef String SourceLocationRange (List String) (List ( String, Type ))
    | UnionTypeDef String SourceLocationRange (List String) (List Type)

................................................................................
            Dict.foldl (\_ val acc -> qualifyDefinition config qualifiedTypes val acc) ( [], Dict.empty ) config.ast.words
    in
    case ( typeErrors, wordErrors ) of
        ( [], [] ) ->
            Ok
                { types = qualifiedTypes
                , words = qualifiedWords
                , additionalModulesRequired = Set.empty
                , checkForExistingTypes = Set.empty
                , checkForExistingWords = Set.empty
                }

        _ ->
            Err <| typeErrors ++ wordErrors


resolveUnionInTypeDefs : Dict String TypeDefinition -> TypeDefinition -> TypeDefinition

Modified src/Play/TypeChecker.elm from [fec5dbde4e] to [2a58b70563].

70
71
72
73
74
75
76
77







78
79
80
81
82
83
84
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147


type StackEffect
    = Push Type
    | Pop Type


initContext : Qualifier.AST -> Context







initContext ast =
    let
        concreteTypes =
            Dict.map
                (\_ t ->
                    case t of
                        Qualifier.CustomTypeDef name range generics members ->
................................................................................
    , boundGenerics = Dict.empty
    , boundStackRanges = Dict.empty
    , callStack = Set.empty
    , errors = List.concatMap genericErrors (Dict.values concreteTypes)
    }


run : Qualifier.AST -> Result (List Problem) AST
run ast =
    typeCheckHelper (initContext ast) ast


typeCheckHelper : Context -> Qualifier.AST -> Result (List Problem) AST
typeCheckHelper context ast =
    let
        updatedContext =
            Dict.foldl (\_ v acc -> typeCheckDefinition v acc) context ast.words
    in
    if List.isEmpty updatedContext.errors then
        Ok <|







|
>
>
>
>
>
>
>







 







|




|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154


type StackEffect
    = Push Type
    | Pop Type


type alias LoadedQualifierAST a =
    { a
        | types : Dict String Qualifier.TypeDefinition
        , words : Dict String Qualifier.WordDefinition
    }


initContext : LoadedQualifierAST a -> Context
initContext ast =
    let
        concreteTypes =
            Dict.map
                (\_ t ->
                    case t of
                        Qualifier.CustomTypeDef name range generics members ->
................................................................................
    , boundGenerics = Dict.empty
    , boundStackRanges = Dict.empty
    , callStack = Set.empty
    , errors = List.concatMap genericErrors (Dict.values concreteTypes)
    }


run : LoadedQualifierAST a -> Result (List Problem) AST
run ast =
    typeCheckHelper (initContext ast) ast


typeCheckHelper : Context -> LoadedQualifierAST a -> Result (List Problem) AST
typeCheckHelper context ast =
    let
        updatedContext =
            Dict.foldl (\_ v acc -> typeCheckDefinition v acc) context ast.words
    in
    if List.isEmpty updatedContext.errors then
        Ok <|

Modified tests/Test/Qualifier.elm from [b90b645b36] to [878063bcf2].

850
851
852
853
854
855
856














857










                                        SoloImpl
                                            [ GetMember "/play/test/some/module/Cent" "cent-value" ]
                                  }
                                ]
                        }
                in
                QualifierUtil.expectModuleOutput unqualifiedAst expectedAst














        ]

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
                                        SoloImpl
                                            [ GetMember "/play/test/some/module/Cent" "cent-value" ]
                                  }
                                ]
                        }
                in
                QualifierUtil.expectModuleOutput unqualifiedAst expectedAst
        , describe "Module loading"
            [ test "Detects external reference in simple word" <|
                \_ ->
                    let
                        unqualifiedAst =
                            { types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "call-external"
                                      , metadata = Metadata.default
                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.ExternalWord emptyRange [ "external", "module" ] "sample"
                                                ]
                                      }
                                    ]
                            }
                    in
                    QualifierUtil.expectModuleRequirements unqualifiedAst
                        [ "/external/module" ]
                        []
                        [ "/external/module/sample" ]
            ]
        ]

Modified tests/Test/Qualifier/Util.elm from [14665d6907] to [d0efb594d1].

1
2
3

4
5
6
7
8
9
10
11
12
13
14

15
16






17
18
19
20
21
22
23
24
..
25
26
27
28
29
30
31
32


33
34

35
36
37
38
39
40
41
42
..
43
44
45
46
47
48
49
50


51
52



























53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
module Test.Qualifier.Util exposing
    ( addFunctionsForStructs
    , expectModuleOutput

    , expectOutput
    )

import Dict
import Dict.Extra as Dict
import Expect exposing (Expectation)
import Play.Data.Metadata as Metadata
import Play.Data.Type as Type exposing (Type)
import Play.Parser as Parser
import Play.Qualifier as AST exposing (AST)
import Play.Qualifier.Problem exposing (Problem)









expectOutput : Parser.AST -> AST -> Expectation
expectOutput parserAst expectedAst =
    let
        result =
            AST.run
                { packageName = ""
                , modulePath = ""
                , ast = parserAst
................................................................................
                }
    in
    case result of
        Err errors ->
            Expect.fail <| "Did not expect qualification to fail. Errors: " ++ Debug.toString errors

        Ok actualAst ->
            Expect.equal expectedAst actualAst





expectModuleOutput : Parser.AST -> AST -> Expectation
expectModuleOutput parserAst expectedAst =
    let
        result =
            AST.run
                { packageName = "play/test"
                , modulePath = "some/module"
                , ast = parserAst
................................................................................
                }
    in
    case result of
        Err errors ->
            Expect.fail <| "Did not expect qualification to fail. Errors: " ++ Debug.toString errors

        Ok actualAst ->
            Expect.equal expectedAst actualAst































addFunctionsForStructs : AST -> AST
addFunctionsForStructs ast =
    let
        helper _ t wipAst =
            case t of
                AST.CustomTypeDef name _ generics members ->
                    addFunctionsForStructsHelper name generics members wipAst

                _ ->
                    wipAst
    in
    Dict.foldl helper ast ast.types


addFunctionsForStructsHelper : String -> List String -> List ( String, Type ) -> AST -> AST
addFunctionsForStructsHelper name generics members ast =
    let
        selfType =
            if List.isEmpty generics then
                Type.Custom name

            else



>



|





|

>


>
>
>
>
>
>
|







 







|
>
>
|

>
|







 







|
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
module Test.Qualifier.Util exposing
    ( addFunctionsForStructs
    , expectModuleOutput
    , expectModuleRequirements
    , expectOutput
    )

import Dict exposing (Dict)
import Dict.Extra as Dict
import Expect exposing (Expectation)
import Play.Data.Metadata as Metadata
import Play.Data.Type as Type exposing (Type)
import Play.Parser as Parser
import Play.Qualifier as AST exposing (AST, TypeDefinition, WordDefinition)
import Play.Qualifier.Problem exposing (Problem)
import Set


type alias FullyLoadedAST =
    { types : Dict String TypeDefinition
    , words : Dict String WordDefinition
    }


expectOutput : Parser.AST -> FullyLoadedAST -> Expectation
expectOutput parserAst expectedAst =
    let
        result =
            AST.run
                { packageName = ""
                , modulePath = ""
                , ast = parserAst
................................................................................
                }
    in
    case result of
        Err errors ->
            Expect.fail <| "Did not expect qualification to fail. Errors: " ++ Debug.toString errors

        Ok actualAst ->
            Expect.equal expectedAst
                { types = actualAst.types
                , words = actualAst.words
                }


expectModuleOutput : Parser.AST -> FullyLoadedAST -> Expectation
expectModuleOutput parserAst expectedAst =
    let
        result =
            AST.run
                { packageName = "play/test"
                , modulePath = "some/module"
                , ast = parserAst
................................................................................
                }
    in
    case result of
        Err errors ->
            Expect.fail <| "Did not expect qualification to fail. Errors: " ++ Debug.toString errors

        Ok actualAst ->
            Expect.equal expectedAst
                { types = actualAst.types
                , words = actualAst.words
                }


expectModuleRequirements : Parser.AST -> List String -> List String -> List String -> Expectation
expectModuleRequirements parserAst expectedModulesToLoad expectedTypesToCheck expectedWordsToCheck =
    let
        result =
            AST.run
                { packageName = ""
                , modulePath = ""
                , ast = parserAst
                }
    in
    case result of
        Err errors ->
            Expect.fail <| "Did not expect qualification to fail. Errors: " ++ Debug.toString errors

        Ok actualAst ->
            Expect.equal
                { additionalModulesRequired = Set.fromList expectedModulesToLoad
                , checkForExistingTypes = Set.fromList expectedTypesToCheck
                , checkForExistingWords = Set.fromList expectedWordsToCheck
                }
                { additionalModulesRequired = actualAst.additionalModulesRequired
                , checkForExistingTypes = actualAst.checkForExistingTypes
                , checkForExistingWords = actualAst.checkForExistingWords
                }


addFunctionsForStructs : FullyLoadedAST -> FullyLoadedAST
addFunctionsForStructs ast =
    let
        helper _ t wipAst =
            case t of
                AST.CustomTypeDef name _ generics members ->
                    addFunctionsForStructsHelper name generics members wipAst

                _ ->
                    wipAst
    in
    Dict.foldl helper ast ast.types


addFunctionsForStructsHelper : String -> List String -> List ( String, Type ) -> FullyLoadedAST -> FullyLoadedAST
addFunctionsForStructsHelper name generics members ast =
    let
        selfType =
            if List.isEmpty generics then
                Type.Custom name

            else

Modified tests/Test/TypeChecker/Error.elm from [6a887ebaba] to [59a5248785].

616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
                                    False
                    in
                    checkForError inexhaustiveError input
            ]
        ]


checkForError : (Problem.Problem -> Bool) -> AST -> Expectation
checkForError fn source =
    case TypeChecker.run source of
        Err errors ->
            if List.any fn errors then
                Expect.pass

            else
                Expect.fail <| "Failed for unexpected reason: " ++ Debug.toString errors

        Ok _ ->
            Expect.fail "Did not expect type checking to succeed"







|











616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
                                    False
                    in
                    checkForError inexhaustiveError input
            ]
        ]


checkForError : (Problem.Problem -> Bool) -> TypeChecker.LoadedQualifierAST a -> Expectation
checkForError fn source =
    case TypeChecker.run source of
        Err errors ->
            if List.any fn errors then
                Expect.pass

            else
                Expect.fail <| "Failed for unexpected reason: " ++ Debug.toString errors

        Ok _ ->
            Expect.fail "Did not expect type checking to succeed"