Play

Check-in [f4459e72ea]
Login
Overview
Comment:Can now resolve package references in multiword definitions.
Timelines: family | ancestors | descendants | both | modules
Files: files | file ages | folders
SHA3-256: f4459e72ea605a93afb2809c0ade967217b86a53e857f356420c1a1b99e2fb4b
User & Date: robin.hansen on 2021-02-10 13:44:17
Other Links: branch diff | manifest | tags
Context
2021-02-11
09:27
Require a list of external modules, so qualifier can validate external module references. check-in: 18c7d0bfa4 user: robin.hansen tags: modules
2021-02-10
13:44
Can now resolve package references in multiword definitions. check-in: f4459e72ea user: robin.hansen tags: modules
11:04
Update elm-format. check-in: a4e1d24585 user: robin.hansen tags: modules
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/Qualifier.elm from [0057c74a3e] to [306edcadda].

259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281


282
283
284
285
286
287
288
289
...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405

406
407
408
409
410

411
412
413
414
415
416
417
            case unqualifiedWord.implementation of
                Parser.SoloImpl defImpl ->
                    ( [], defImpl )

                Parser.MultiImpl whenImpl defImpl ->
                    ( whenImpl, defImpl )

        ( newWordsAfterWhens, qualifiedWhensResult ) =
            List.foldr (qualifyWhen config qualifiedTypes unqualifiedWord.name) ( acc, [] ) whens
                |> Tuple.mapSecond Result.combine

        ( newWordsAfterImpl, externalWordsAfterImpl, qualifiedImplementationResult ) =
            initQualifyNode unqualifiedWord.name config newWordsAfterWhens impl

        qualifiedMetadataResult =
            qualifyMetadata config qualifiedTypes unqualifiedWord.metadata

        qualifiedName =
            qualifyName config unqualifiedWord.name
    in
    case ( qualifiedWhensResult, qualifiedImplementationResult, qualifiedMetadataResult ) of
        ( Ok qualifiedWhens, Ok qualifiedImplementation, Ok qualifiedMetadata ) ->
            ( errors


            , Set.union externalWords externalWordsAfterImpl
            , Dict.insert qualifiedName
                { name = qualifiedName
                , metadata = qualifiedMetadata
                , implementation =
                    if List.isEmpty qualifiedWhens then
                        SoloImpl qualifiedImplementation

................................................................................


qualifyWhen :
    RunConfig
    -> Dict String TypeDefinition
    -> String
    -> ( Parser.TypeMatch, List Parser.AstNode )
    -> ( Dict String WordDefinition, List (Result Problem ( TypeMatch, List Node )) )
    -> ( Dict String WordDefinition, List (Result Problem ( TypeMatch, List Node )) )
qualifyWhen config qualifiedTypes wordName ( typeMatch, impl ) ( qualifiedWords, result ) =
    let
        ( newWords, externalWords, qualifiedImplementationResult ) =
            initQualifyNode wordName config qualifiedWords impl

        qualifiedMatchResult =
            qualifyMatch config qualifiedTypes typeMatch
    in
    case ( qualifiedImplementationResult, qualifiedMatchResult ) of
        ( Err err, _ ) ->
            ( newWords

            , Err err :: result
            )

        ( _, Err err ) ->
            ( newWords

            , Err err :: result
            )

        ( Ok qualifiedImplementation, Ok qualifiedMatch ) ->
            ( newWords

            , Ok ( qualifiedMatch, qualifiedImplementation ) :: result
            )


qualifyMatch : RunConfig -> Dict String TypeDefinition -> Parser.TypeMatch -> Result Problem TypeMatch
qualifyMatch config qualifiedTypes typeMatch =
    case typeMatch of







|
|
|













>
>
|







 







|
|
|

|








>





>





>







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
            case unqualifiedWord.implementation of
                Parser.SoloImpl defImpl ->
                    ( [], defImpl )

                Parser.MultiImpl whenImpl defImpl ->
                    ( whenImpl, defImpl )

        ( newWordsAfterWhens, externalWordsAfterWhens, qualifiedWhensResult ) =
            List.foldr (qualifyWhen config qualifiedTypes unqualifiedWord.name) ( acc, Set.empty, [] ) whens
                |> (\( a, b, nodes ) -> ( a, b, Result.combine nodes ))

        ( newWordsAfterImpl, externalWordsAfterImpl, qualifiedImplementationResult ) =
            initQualifyNode unqualifiedWord.name config newWordsAfterWhens impl

        qualifiedMetadataResult =
            qualifyMetadata config qualifiedTypes unqualifiedWord.metadata

        qualifiedName =
            qualifyName config unqualifiedWord.name
    in
    case ( qualifiedWhensResult, qualifiedImplementationResult, qualifiedMetadataResult ) of
        ( Ok qualifiedWhens, Ok qualifiedImplementation, Ok qualifiedMetadata ) ->
            ( errors
            , externalWords
                |> Set.union externalWordsAfterWhens
                |> Set.union externalWordsAfterImpl
            , Dict.insert qualifiedName
                { name = qualifiedName
                , metadata = qualifiedMetadata
                , implementation =
                    if List.isEmpty qualifiedWhens then
                        SoloImpl qualifiedImplementation

................................................................................


qualifyWhen :
    RunConfig
    -> Dict String TypeDefinition
    -> String
    -> ( Parser.TypeMatch, List Parser.AstNode )
    -> ( Dict String WordDefinition, Set ( String, String ), List (Result Problem ( TypeMatch, List Node )) )
    -> ( Dict String WordDefinition, Set ( String, String ), List (Result Problem ( TypeMatch, List Node )) )
qualifyWhen config qualifiedTypes wordName ( typeMatch, impl ) ( qualifiedWords, externalWords, result ) =
    let
        ( newWords, externalWordsAfterImpl, qualifiedImplementationResult ) =
            initQualifyNode wordName config qualifiedWords impl

        qualifiedMatchResult =
            qualifyMatch config qualifiedTypes typeMatch
    in
    case ( qualifiedImplementationResult, qualifiedMatchResult ) of
        ( Err err, _ ) ->
            ( newWords
            , externalWords
            , Err err :: result
            )

        ( _, Err err ) ->
            ( newWords
            , externalWords
            , Err err :: result
            )

        ( Ok qualifiedImplementation, Ok qualifiedMatch ) ->
            ( newWords
            , Set.union externalWords externalWordsAfterImpl
            , Ok ( qualifiedMatch, qualifiedImplementation ) :: result
            )


qualifyMatch : RunConfig -> Dict String TypeDefinition -> Parser.TypeMatch -> Result Problem TypeMatch
qualifyMatch config qualifiedTypes typeMatch =
    case typeMatch of

Modified tests/Test/Qualifier.elm from [d8f0c7e9d7] to [7932be559f].

891
892
893
894
895
896
897





























































898
899
900
901
902
903
904
                                            SoloImpl
                                                [ Integer emptyRange 1
                                                , Word emptyRange "/play/test/package/module/sample"
                                                ]
                                      }
                                    ]
                            }






























































                        result =
                            run
                                { packageName = "play/test"
                                , modulePath = "package/tests"
                                , ast = unqualifiedAst
                                }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
                                            SoloImpl
                                                [ Integer emptyRange 1
                                                , Word emptyRange "/play/test/package/module/sample"
                                                ]
                                      }
                                    ]
                            }

                        result =
                            run
                                { packageName = "play/test"
                                , modulePath = "package/tests"
                                , ast = unqualifiedAst
                                }
                    in
                    case result of
                        Err err ->
                            Expect.fail <| "Did not expect qualification to fail with error: " ++ Debug.toString err

                        Ok actualAst ->
                            Expect.equal expectedAst actualAst
            , test "Detects package reference in multiword" <|
                \_ ->
                    let
                        unqualifiedAst =
                            { types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "call-external"
                                      , metadata = Metadata.default
                                      , implementation =
                                            AST.MultiImpl
                                                [ ( AST.TypeMatch emptyRange Type.Int [ ( "value", AST.LiteralInt 1 ) ]
                                                  , [ AST.PackageWord emptyRange [ "package", "module" ] "when-one"
                                                    ]
                                                  )
                                                ]
                                                [ AST.PackageWord emptyRange [ "package", "module" ] "when-other-one" ]
                                      }
                                    ]
                            }

                        expectedAst =
                            { additionalModulesRequired =
                                Set.fromList
                                    [ "/play/test/package/module" ]
                            , checkForExistingTypes = Set.empty
                            , checkForExistingWords =
                                Set.fromList
                                    [ "/play/test/package/module/when-one"
                                    , "/play/test/package/module/when-other-one"
                                    ]
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "/play/test/package/tests/call-external"
                                      , metadata = Metadata.default
                                      , implementation =
                                            MultiImpl
                                                [ ( TypeMatch emptyRange Type.Int [ ( "value", LiteralInt 1 ) ]
                                                  , [ Word emptyRange "/play/test/package/module/when-one"
                                                    ]
                                                  )
                                                ]
                                                [ Word emptyRange "/play/test/package/module/when-other-one" ]
                                      }
                                    ]
                            }

                        result =
                            run
                                { packageName = "play/test"
                                , modulePath = "package/tests"
                                , ast = unqualifiedAst
                                }