Stabel

Check-in [6b7f3c4739]
Login
Overview
Comment:Parser word definitions no longer uses the common Metadata type, or the common Type type. Everything is now defined locally. Parser types now supports module paths, although it's not being used. Tests are broken.
Timelines: family | ancestors | descendants | both | module-definition
Files: files | file ages | folders
SHA3-256: 6b7f3c473979ed14c664620253411715e90326545c49b32334ce381955a86374
User & Date: robin.hansen on 2021-05-14 09:12:02
Other Links: branch diff | manifest | tags
Context
2021-05-19
07:07
Fix compile errors in Test/Qualifier.elm check-in: d6a12d5f79 user: robin.hansen tags: module-definition
2021-05-14
09:12
Parser word definitions no longer uses the common Metadata type, or the common Type type. Everything... check-in: 6b7f3c4739 user: robin.hansen tags: module-definition
2021-05-07
09:07
Qualifier now throws an error if trying to call an unexposed function in a different module. check-in: fa15a3e3bd user: robin.hansen tags: module-definition
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/Data/Metadata.elm from [3dff0edb1c] to [4a5e9363a6].

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
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74


type alias Metadata =
    { isEntryPoint : Bool
    , type_ : TypeSignature
    , isQuoted : Bool
    , sourceLocationRange : Maybe SourceLocationRange
    , aliases : Dict String String
    , imports : Dict String (List String)
    , isExposed : Bool
    }


default : Metadata
default =
    { isEntryPoint = False
    , type_ = NotProvided
    , isQuoted = False
    , sourceLocationRange = Nothing
    , aliases = Dict.empty
    , imports = Dict.empty
    , isExposed = True
    }


asEntryPoint : Metadata -> Metadata
asEntryPoint meta =
    { meta | isEntryPoint = True }
................................................................................
    { meta | sourceLocationRange = Just range }


clearSourceLocationRange : Metadata -> Metadata
clearSourceLocationRange meta =
    { meta | sourceLocationRange = Nothing }


withAlias : String -> String -> Metadata -> Metadata
withAlias ali val meta =
    { meta | aliases = Dict.insert ali val meta.aliases }


withImport : String -> List String -> Metadata -> Metadata
withImport ns vals meta =
    { meta | imports = Dict.insert ns vals meta.imports }


isExposed : Bool -> Metadata -> Metadata
isExposed val meta =
    { meta | isExposed = val }







<
<










<
<







 







<
<
<
<
<
<
<
<
<
<




7
8
9
10
11
12
13


14
15
16
17
18
19
20
21
22
23


24
25
26
27
28
29
30
..
50
51
52
53
54
55
56










57
58
59
60


type alias Metadata =
    { isEntryPoint : Bool
    , type_ : TypeSignature
    , isQuoted : Bool
    , sourceLocationRange : Maybe SourceLocationRange


    , isExposed : Bool
    }


default : Metadata
default =
    { isEntryPoint = False
    , type_ = NotProvided
    , isQuoted = False
    , sourceLocationRange = Nothing


    , isExposed = True
    }


asEntryPoint : Metadata -> Metadata
asEntryPoint meta =
    { meta | isEntryPoint = True }
................................................................................
    { meta | sourceLocationRange = Just range }


clearSourceLocationRange : Metadata -> Metadata
clearSourceLocationRange meta =
    { meta | sourceLocationRange = Nothing }












isExposed : Bool -> Metadata -> Metadata
isExposed val meta =
    { meta | isExposed = val }

Modified src/Play/Parser.elm from [824d248e3d] to [a554f04633].

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
..
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
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
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
418
419
420
421
422
...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612





613
614
615
616
617
618
619
620
621





622
623
624
625
626
627
628
629





630
631
632
633
634
635
636
...
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657



658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720



721
722
723
724
725
726
727
...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
...
800
801
802
803
804
805
806


807
808
809
810
811
812
813
814
...
832
833
834
835
836
837
838
839


840
841
842
843
844
845
846
847
848
849
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
882
...
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
module Play.Parser exposing
    ( AST
    , AstNode(..)
    , ModuleDefinition(..)

    , TypeDefinition(..)
    , TypeMatch(..)
    , TypeMatchValue(..)

    , WordDefinition
    , WordImplementation(..)
    , emptyModuleDefinition
    , run
    , typeDefinitionName

    )

import Dict exposing (Dict)
import Dict.Extra as Dict
import Parser.Advanced as Parser exposing ((|.), (|=), Token(..))
import Play.Data.Metadata as Metadata exposing (Metadata)
import Play.Data.SourceLocation exposing (SourceLocation, SourceLocationRange)
import Play.Data.Type as Type exposing (Type, WordType)
import Play.Data.TypeSignature as TypeSignature
import Play.Parser.Problem exposing (..)
import Set exposing (Set)


type alias Parser a =
    Parser.Parser () Problem a

................................................................................
    { aliases : Dict String String
    , imports : Dict String (List String)
    , exposes : Set String
    }


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


type alias WordDefinition =
    { name : String
    , metadata : Metadata



    , implementation : WordImplementation
    }




































type WordImplementation
    = SoloImpl (List AstNode)
    | MultiImpl (List ( TypeMatch, List AstNode )) (List AstNode)


type TypeMatch
    = TypeMatch SourceLocationRange Type (List ( String, TypeMatchValue ))


type TypeMatchValue
    = LiteralInt Int
    | LiteralType Type
    | RecursiveMatch TypeMatch


type AstNode
    = Integer SourceLocationRange Int
    | Word SourceLocationRange String
    | PackageWord SourceLocationRange (List String) String
................................................................................
        , inner = validSymbolChar
        , reserved = Set.empty
        , expecting = NotType
        }
        |. noiseParser


genericOrRangeParser : Parser Type
genericOrRangeParser =
    let
        helper value =
            Parser.oneOf
                [ Parser.succeed (Type.StackRange value)
                    |. Parser.symbol (Token "..." NoProblem)
                    |. noiseParser
                , Parser.succeed (Type.Generic value)
                ]
    in
    Parser.andThen helper genericParser


typeParser : Parser Type
typeParser =
    Parser.oneOf
        [ Parser.succeed Type.Int
            |. Parser.keyword (Token "Int" NoProblem)
            |. noiseParser
        , Parser.succeed Type.Custom
            |= typeNameParser
        ]


typeRefParser : Parser Type
typeRefParser =
    let
        helper name binds =
            case binds of
                [] ->
                    Type.Custom name

                _ ->
                    Type.CustomGeneric name binds
    in
    Parser.oneOf
        [ Parser.succeed Type.Int
            |. Parser.keyword (Token "Int" NoProblem)
            |. noiseParser
        , Parser.succeed helper
            |= typeNameParser
            |= Parser.loop [] typeOrGenericParser
        , Parser.succeed Type.Generic
            |= genericParser
        , Parser.succeed identity
            |. Parser.symbol (Token "(" ExpectedLeftParen)
            |. noiseParser
            |= Parser.lazy (\_ -> typeRefParser)
            |. Parser.symbol (Token ")" ExpectedRightParen)
            |. noiseParser
        ]


typeOrGenericParser : List Type -> Parser (Parser.Step (List Type) (List Type))
typeOrGenericParser types =
    Parser.oneOf
        [ Parser.succeed (\name -> Parser.Loop (Type.Custom name :: types))
            |= typeNameParser
        , Parser.succeed (\name -> Parser.Loop (Type.Generic name :: types))
            |= genericParser
        , Parser.succeed (Parser.Done (List.reverse types))
        ]


noiseParser : Parser ()
noiseParser =
................................................................................
                        |> Parser.succeed

        maybeInsertWordProblem wordDef =
            Dict.get wordDef.name ast.words
                |> Maybe.map
                    (\prevDef ->
                        WordAlreadyDefined wordDef.name
                            prevDef.metadata.sourceLocationRange
                            wordDef.metadata.sourceLocationRange
                    )

        insertType typeDef =
            let
                typeName =
                    typeDefinitionName typeDef
            in
................................................................................
    case typeDef of
        UnionTypeDef _ _ _ _ ->
            []

        CustomTypeDef _ typeName binds typeMembers ->
            let
                typeOfType =
                    case binds of
                        [] ->
                            Type.Custom typeName

                        _ ->
                            Type.CustomGeneric typeName (List.map Type.Generic binds)

                ctorDef =
                    { name =
                        if List.isEmpty typeMembers then
                            typeName

                        else
                            ">" ++ typeName
                    , metadata =
                        Metadata.default
                            |> Metadata.withVerifiedType (List.map Tuple.second typeMembers) [ typeOfType ]





                    , implementation =
                        SoloImpl [ ConstructType typeName ]
                    }

                setterGetterPair ( memberName, memberType ) =
                    [ { name = ">" ++ memberName
                      , metadata =
                            Metadata.default
                                |> Metadata.withVerifiedType [ typeOfType, memberType ] [ typeOfType ]





                      , implementation =
                            SoloImpl
                                [ SetMember typeName memberName ]
                      }
                    , { name = memberName ++ ">"
                      , metadata =
                            Metadata.default
                                |> Metadata.withVerifiedType [ typeOfType ] [ memberType ]





                      , implementation =
                            SoloImpl
                                [ GetMember typeName memberName ]
                      }
                    ]
            in
            typeMembers
................................................................................

wordDefinitionParser : SourceLocation -> Parser WordDefinition
wordDefinitionParser startLocation =
    let
        joinParseResults name def endLocation =
            { def
                | name = name
                , metadata =
                    Metadata.withSourceLocationRange
                        { start = startLocation
                        , end = endLocation
                        }
                        def.metadata
            }

        emptyDef =
            { name = ""
            , metadata = Metadata.default



            , implementation = SoloImpl []
            }
    in
    Parser.succeed joinParseResults
        |= symbolParser
        |= Parser.loop emptyDef wordMetadataParser
        |= sourceLocationParser


wordMetadataParser : WordDefinition -> Parser (Parser.Step WordDefinition WordDefinition)
wordMetadataParser def =
    let
        metadata =
            def.metadata
    in
    Parser.oneOf
        [ Parser.succeed (\typeSign -> Parser.Loop { def | metadata = { metadata | type_ = TypeSignature.UserProvided typeSign } })
            |. Parser.keyword (Token "type:" NoProblem)
            |. noiseParser
            |= typeSignatureParser
        , Parser.succeed (\alias value -> Parser.Loop { def | metadata = Metadata.withAlias alias value def.metadata })
            |. Parser.keyword (Token "alias:" NoProblem)
            |. noiseParser
            |= symbolParser
            |. noiseParser
            |= modulePathStringParser
            |. noiseParser
        , Parser.succeed (\mod vals -> Parser.Loop { def | metadata = Metadata.withImport mod vals def.metadata })
            |. Parser.keyword (Token "import:" NoProblem)
            |. noiseParser
            |= modulePathStringParser
            |. noiseParser
            |= Parser.loop [] symbolImplListParser
            |. noiseParser
        , Parser.succeed (\impl -> Parser.Loop { def | implementation = SoloImpl impl })
................................................................................
multiWordDefinitionParser : SourceLocation -> Parser WordDefinition
multiWordDefinitionParser startLocation =
    let
        joinParseResults name def endLocation =
            reverseWhens <|
                { def
                    | name = name
                    , metadata =
                        Metadata.withSourceLocationRange
                            { start = startLocation
                            , end = endLocation
                            }
                            def.metadata
                }

        emptyDef =
            { name = ""
            , metadata = Metadata.default



            , implementation = SoloImpl []
            }

        reverseWhens def =
            case def.implementation of
                SoloImpl _ ->
                    def
................................................................................
        |= Parser.loop emptyDef multiWordMetadataParser
        |= sourceLocationParser


multiWordMetadataParser : WordDefinition -> Parser (Parser.Step WordDefinition WordDefinition)
multiWordMetadataParser def =
    let
        metadata =
            def.metadata

        addWhenImpl impl =
            case def.implementation of
                MultiImpl whens default ->
                    MultiImpl (impl :: whens) default

                SoloImpl default ->
                    MultiImpl [ impl ] default
................................................................................
                MultiImpl whens _ ->
                    MultiImpl whens impl

                SoloImpl _ ->
                    MultiImpl [] impl
    in
    Parser.oneOf
        [ Parser.succeed (\typeSign -> Parser.Loop { def | metadata = { metadata | type_ = TypeSignature.UserProvided typeSign } })
            |. Parser.keyword (Token "type:" NoProblem)
            |. noiseParser
            |= typeSignatureParser
        , Parser.succeed (\impl -> Parser.Loop { def | implementation = setDefaultImpl impl })
            |. Parser.keyword (Token "else:" NoProblem)
            |. noiseParser
            |= implementationParser
................................................................................
    Parser.oneOf
        [ Parser.succeed (\name -> Parser.Loop (name :: generics))
            |= genericParser
        , Parser.succeed (Parser.Done (List.reverse generics))
        ]




typeMemberParser : List ( String, Type ) -> Parser (Parser.Step (List ( String, Type )) (List ( String, Type )))
typeMemberParser types =
    Parser.oneOf
        [ Parser.succeed (\name type_ -> Parser.Loop (( name, type_ ) :: types))
            |. Parser.symbol (Token ":" NoProblem)
            |. noiseParser
            |= symbolParser
            |= typeRefParser
................................................................................
    Parser.succeed ctor
        |= typeNameParser
        |= Parser.loop [] typeGenericParser
        |= Parser.loop [] unionTypeMemberParser
        |= sourceLocationParser


unionTypeMemberParser : List Type -> Parser (Parser.Step (List Type) (List Type))


unionTypeMemberParser types =
    Parser.oneOf
        [ Parser.succeed (\type_ -> Parser.Loop (type_ :: types))
            |. Parser.symbol (Token ":" NoProblem)
            |. noiseParser
            |= typeRefParser
        , Parser.succeed UnknownMetadata
            |= definitionMetadataParser
            |> Parser.andThen Parser.problem
        , Parser.succeed (Parser.Done (List.reverse types))
        ]


typeSignatureParser : Parser WordType
typeSignatureParser =
    Parser.succeed (\input output -> { input = input, output = output })
        |= Parser.loop [] typeLoopParser
        |. Parser.symbol (Token "--" ExpectedTypeSeperator)
        |. noiseParser
        |= Parser.loop [] typeLoopParser




typeLoopParser : List Type -> Parser (Parser.Step (List Type) (List Type))
typeLoopParser reverseTypes =
    let
        step type_ =
            Parser.Loop (type_ :: reverseTypes)
    in
    Parser.oneOf
        [ Parser.succeed step
            |= typeParser
        , Parser.succeed step
            |= genericOrRangeParser
        , Parser.succeed step
            |= typeRefParser
        , Parser.succeed (\wordType -> step (Type.Quotation wordType))
            |. Parser.symbol (Token "[" ExpectedLeftBracket)
            |. noiseParser
            |= typeSignatureParser
            |. Parser.symbol (Token "]" ExpectedRightBracket)
            |. noiseParser
        , Parser.succeed (Parser.Done (List.reverse reverseTypes))
        ]
................................................................................
                    |. noiseParser
                    |= Parser.loop [] typeMatchConditionParser
                    |. Parser.symbol (Token ")" ExpectedRightParen)
                , Parser.succeed []
                ]
            |= sourceLocationParser
            |. noiseParser
        , Parser.succeed (\startLoc sym endLoc -> TypeMatch (SourceLocationRange startLoc endLoc) (Type.Generic sym) [])
            |= sourceLocationParser
            |= genericParser
            |= sourceLocationParser
        , Parser.succeed (\startLoc typ endLoc -> TypeMatch (SourceLocationRange startLoc endLoc) typ [])
            |= sourceLocationParser
            |= typeRefParser
            |= sourceLocationParser




>



>





>





<

<
<







 







|
|




|
>
>
>



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







|




|







 







|




|


|





|

<
|
<
<
<
|
|

<
|

<
<
<
<
<
<
<
<
<

|
<
<
<


|










|


|

|







 







|
|







 







<
<
<
<
<
|








|
|
|
>
>
>
>
>






|
|
|
>
>
>
>
>





|
|
|
>
>
>
>
>







 







|
|



<




|
>
>
>











<
<
<
<

|



|






|







 







|
|



<




|
>
>
>







 







<
<
<







 







|







 







>
>
|







 







|
>
>













|








>
>
|












|







 







|







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
..
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
115
116
...
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
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
...
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
...
609
610
611
612
613
614
615





616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
...
670
671
672
673
674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700




701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
...
731
732
733
734
735
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
...
764
765
766
767
768
769
770



771
772
773
774
775
776
777
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
...
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
...
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
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
...
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
module Play.Parser exposing
    ( AST
    , AstNode(..)
    , ModuleDefinition(..)
    , PossiblyQualifiedType(..)
    , TypeDefinition(..)
    , TypeMatch(..)
    , TypeMatchValue(..)
    , TypeSignature(..)
    , WordDefinition
    , WordImplementation(..)
    , emptyModuleDefinition
    , run
    , typeDefinitionName
    , typeSignatureToMaybe
    )

import Dict exposing (Dict)
import Dict.Extra as Dict
import Parser.Advanced as Parser exposing ((|.), (|=), Token(..))

import Play.Data.SourceLocation exposing (SourceLocation, SourceLocationRange)


import Play.Parser.Problem exposing (..)
import Set exposing (Set)


type alias Parser a =
    Parser.Parser () Problem a

................................................................................
    { aliases : Dict String String
    , imports : Dict String (List String)
    , exposes : Set String
    }


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


type alias WordDefinition =
    { name : String
    , typeSignature : TypeSignature
    , sourceLocationRange : Maybe SourceLocationRange
    , aliases : Dict String String
    , imports : Dict String (List String)
    , implementation : WordImplementation
    }


type alias ParserWordType =
    { input : List PossiblyQualifiedType
    , output : List PossiblyQualifiedType
    }


type TypeSignature
    = NotProvided
    | UserProvided ParserWordType
    | Verified ParserWordType


typeSignatureToMaybe : TypeSignature -> Maybe ParserWordType
typeSignatureToMaybe ts =
    case ts of
        NotProvided ->
            Nothing

        UserProvided wt ->
            Just wt

        Verified wt ->
            Just wt


type PossiblyQualifiedType
    = LocalRef String (List PossiblyQualifiedType)
    | InternalRef (List String) String (List PossiblyQualifiedType)
    | ExternalRef (List String) String (List PossiblyQualifiedType)
    | Generic String
    | StackRange String
    | QuotationType ParserWordType


type WordImplementation
    = SoloImpl (List AstNode)
    | MultiImpl (List ( TypeMatch, List AstNode )) (List AstNode)


type TypeMatch
    = TypeMatch SourceLocationRange PossiblyQualifiedType (List ( String, TypeMatchValue ))


type TypeMatchValue
    = LiteralInt Int
    | LiteralType PossiblyQualifiedType
    | RecursiveMatch TypeMatch


type AstNode
    = Integer SourceLocationRange Int
    | Word SourceLocationRange String
    | PackageWord SourceLocationRange (List String) String
................................................................................
        , inner = validSymbolChar
        , reserved = Set.empty
        , expecting = NotType
        }
        |. noiseParser


genericOrRangeParser : Parser PossiblyQualifiedType
genericOrRangeParser =
    let
        helper value =
            Parser.oneOf
                [ Parser.succeed (StackRange value)
                    |. Parser.symbol (Token "..." NoProblem)
                    |. noiseParser
                , Parser.succeed (Generic value)
                ]
    in
    Parser.andThen helper genericParser


typeParser : Parser PossiblyQualifiedType
typeParser =

    Parser.succeed (\name -> LocalRef name [])



        |= typeNameParser



typeRefParser : Parser PossiblyQualifiedType
typeRefParser =









    Parser.oneOf
        [ Parser.succeed (\name binds -> LocalRef name binds)



            |= typeNameParser
            |= Parser.loop [] typeOrGenericParser
        , Parser.succeed Generic
            |= genericParser
        , Parser.succeed identity
            |. Parser.symbol (Token "(" ExpectedLeftParen)
            |. noiseParser
            |= Parser.lazy (\_ -> typeRefParser)
            |. Parser.symbol (Token ")" ExpectedRightParen)
            |. noiseParser
        ]


typeOrGenericParser : List PossiblyQualifiedType -> Parser (Parser.Step (List PossiblyQualifiedType) (List PossiblyQualifiedType))
typeOrGenericParser types =
    Parser.oneOf
        [ Parser.succeed (\name -> Parser.Loop (LocalRef name [] :: types))
            |= typeNameParser
        , Parser.succeed (\name -> Parser.Loop (Generic name :: types))
            |= genericParser
        , Parser.succeed (Parser.Done (List.reverse types))
        ]


noiseParser : Parser ()
noiseParser =
................................................................................
                        |> Parser.succeed

        maybeInsertWordProblem wordDef =
            Dict.get wordDef.name ast.words
                |> Maybe.map
                    (\prevDef ->
                        WordAlreadyDefined wordDef.name
                            prevDef.sourceLocationRange
                            wordDef.sourceLocationRange
                    )

        insertType typeDef =
            let
                typeName =
                    typeDefinitionName typeDef
            in
................................................................................
    case typeDef of
        UnionTypeDef _ _ _ _ ->
            []

        CustomTypeDef _ typeName binds typeMembers ->
            let
                typeOfType =





                    LocalRef typeName (List.map Generic binds)

                ctorDef =
                    { name =
                        if List.isEmpty typeMembers then
                            typeName

                        else
                            ">" ++ typeName
                    , typeSignature =
                        Verified
                            { input = List.map Tuple.second typeMembers
                            , output = [ typeOfType ]
                            }
                    , sourceLocationRange = Nothing
                    , aliases = Dict.empty
                    , imports = Dict.empty
                    , implementation =
                        SoloImpl [ ConstructType typeName ]
                    }

                setterGetterPair ( memberName, memberType ) =
                    [ { name = ">" ++ memberName
                      , typeSignature =
                            Verified
                                { input = [ typeOfType, memberType ]
                                , output = [ typeOfType ]
                                }
                      , sourceLocationRange = Nothing
                      , aliases = Dict.empty
                      , imports = Dict.empty
                      , implementation =
                            SoloImpl
                                [ SetMember typeName memberName ]
                      }
                    , { name = memberName ++ ">"
                      , typeSignature =
                            Verified
                                { input = [ typeOfType ]
                                , output = [ memberType ]
                                }
                      , sourceLocationRange = Nothing
                      , aliases = Dict.empty
                      , imports = Dict.empty
                      , implementation =
                            SoloImpl
                                [ GetMember typeName memberName ]
                      }
                    ]
            in
            typeMembers
................................................................................

wordDefinitionParser : SourceLocation -> Parser WordDefinition
wordDefinitionParser startLocation =
    let
        joinParseResults name def endLocation =
            { def
                | name = name
                , sourceLocationRange =
                    Just
                        { start = startLocation
                        , end = endLocation
                        }

            }

        emptyDef =
            { name = ""
            , typeSignature = NotProvided
            , sourceLocationRange = Nothing
            , aliases = Dict.empty
            , imports = Dict.empty
            , implementation = SoloImpl []
            }
    in
    Parser.succeed joinParseResults
        |= symbolParser
        |= Parser.loop emptyDef wordMetadataParser
        |= sourceLocationParser


wordMetadataParser : WordDefinition -> Parser (Parser.Step WordDefinition WordDefinition)
wordMetadataParser def =




    Parser.oneOf
        [ Parser.succeed (\typeSign -> Parser.Loop { def | typeSignature = UserProvided typeSign })
            |. Parser.keyword (Token "type:" NoProblem)
            |. noiseParser
            |= typeSignatureParser
        , Parser.succeed (\alias value -> Parser.Loop { def | aliases = Dict.insert alias value def.aliases })
            |. Parser.keyword (Token "alias:" NoProblem)
            |. noiseParser
            |= symbolParser
            |. noiseParser
            |= modulePathStringParser
            |. noiseParser
        , Parser.succeed (\mod vals -> Parser.Loop { def | imports = Dict.insert mod vals def.imports })
            |. Parser.keyword (Token "import:" NoProblem)
            |. noiseParser
            |= modulePathStringParser
            |. noiseParser
            |= Parser.loop [] symbolImplListParser
            |. noiseParser
        , Parser.succeed (\impl -> Parser.Loop { def | implementation = SoloImpl impl })
................................................................................
multiWordDefinitionParser : SourceLocation -> Parser WordDefinition
multiWordDefinitionParser startLocation =
    let
        joinParseResults name def endLocation =
            reverseWhens <|
                { def
                    | name = name
                    , sourceLocationRange =
                        Just
                            { start = startLocation
                            , end = endLocation
                            }

                }

        emptyDef =
            { name = ""
            , typeSignature = NotProvided
            , sourceLocationRange = Nothing
            , aliases = Dict.empty
            , imports = Dict.empty
            , implementation = SoloImpl []
            }

        reverseWhens def =
            case def.implementation of
                SoloImpl _ ->
                    def
................................................................................
        |= Parser.loop emptyDef multiWordMetadataParser
        |= sourceLocationParser


multiWordMetadataParser : WordDefinition -> Parser (Parser.Step WordDefinition WordDefinition)
multiWordMetadataParser def =
    let



        addWhenImpl impl =
            case def.implementation of
                MultiImpl whens default ->
                    MultiImpl (impl :: whens) default

                SoloImpl default ->
                    MultiImpl [ impl ] default
................................................................................
                MultiImpl whens _ ->
                    MultiImpl whens impl

                SoloImpl _ ->
                    MultiImpl [] impl
    in
    Parser.oneOf
        [ Parser.succeed (\typeSign -> Parser.Loop { def | typeSignature = UserProvided typeSign })
            |. Parser.keyword (Token "type:" NoProblem)
            |. noiseParser
            |= typeSignatureParser
        , Parser.succeed (\impl -> Parser.Loop { def | implementation = setDefaultImpl impl })
            |. Parser.keyword (Token "else:" NoProblem)
            |. noiseParser
            |= implementationParser
................................................................................
    Parser.oneOf
        [ Parser.succeed (\name -> Parser.Loop (name :: generics))
            |= genericParser
        , Parser.succeed (Parser.Done (List.reverse generics))
        ]


typeMemberParser :
    List ( String, PossiblyQualifiedType )
    -> Parser (Parser.Step (List ( String, PossiblyQualifiedType )) (List ( String, PossiblyQualifiedType )))
typeMemberParser types =
    Parser.oneOf
        [ Parser.succeed (\name type_ -> Parser.Loop (( name, type_ ) :: types))
            |. Parser.symbol (Token ":" NoProblem)
            |. noiseParser
            |= symbolParser
            |= typeRefParser
................................................................................
    Parser.succeed ctor
        |= typeNameParser
        |= Parser.loop [] typeGenericParser
        |= Parser.loop [] unionTypeMemberParser
        |= sourceLocationParser


unionTypeMemberParser :
    List PossiblyQualifiedType
    -> Parser (Parser.Step (List PossiblyQualifiedType) (List PossiblyQualifiedType))
unionTypeMemberParser types =
    Parser.oneOf
        [ Parser.succeed (\type_ -> Parser.Loop (type_ :: types))
            |. Parser.symbol (Token ":" NoProblem)
            |. noiseParser
            |= typeRefParser
        , Parser.succeed UnknownMetadata
            |= definitionMetadataParser
            |> Parser.andThen Parser.problem
        , Parser.succeed (Parser.Done (List.reverse types))
        ]


typeSignatureParser : Parser ParserWordType
typeSignatureParser =
    Parser.succeed (\input output -> { input = input, output = output })
        |= Parser.loop [] typeLoopParser
        |. Parser.symbol (Token "--" ExpectedTypeSeperator)
        |. noiseParser
        |= Parser.loop [] typeLoopParser


typeLoopParser :
    List PossiblyQualifiedType
    -> Parser (Parser.Step (List PossiblyQualifiedType) (List PossiblyQualifiedType))
typeLoopParser reverseTypes =
    let
        step type_ =
            Parser.Loop (type_ :: reverseTypes)
    in
    Parser.oneOf
        [ Parser.succeed step
            |= typeParser
        , Parser.succeed step
            |= genericOrRangeParser
        , Parser.succeed step
            |= typeRefParser
        , Parser.succeed (\wordType -> step (QuotationType wordType))
            |. Parser.symbol (Token "[" ExpectedLeftBracket)
            |. noiseParser
            |= typeSignatureParser
            |. Parser.symbol (Token "]" ExpectedRightBracket)
            |. noiseParser
        , Parser.succeed (Parser.Done (List.reverse reverseTypes))
        ]
................................................................................
                    |. noiseParser
                    |= Parser.loop [] typeMatchConditionParser
                    |. Parser.symbol (Token ")" ExpectedRightParen)
                , Parser.succeed []
                ]
            |= sourceLocationParser
            |. noiseParser
        , Parser.succeed (\startLoc sym endLoc -> TypeMatch (SourceLocationRange startLoc endLoc) (Generic sym) [])
            |= sourceLocationParser
            |= genericParser
            |= sourceLocationParser
        , Parser.succeed (\startLoc typ endLoc -> TypeMatch (SourceLocationRange startLoc endLoc) typ [])
            |= sourceLocationParser
            |= typeRefParser
            |= sourceLocationParser

Modified src/Play/Qualifier.elm from [f368b70ffb] to [2060841194].

213
214
215
216
217
218
219


220


221
222




















223


















224
225
226
227
228
229
230
231
232
233

234

235
236
237





238
239







240










241
242
243
244
245
246
247
...
255
256
257
258
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
...
313
314
315
316
317
318
319
320
321
322
323
324
325
326











327
328

329
330
331

332
333
334
335





336


337
338
339
340
341


342
343





344
345

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
...
497
498
499
500
501
502
503






504



505
506
507
508
509
510
511
...
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
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898

                Ok qualifiedMemberTypes ->
                    ( errors
                    , Dict.insert qualifiedName (UnionTypeDef qualifiedName range generics qualifiedMemberTypes) acc
                    )




qualifyMemberType : RunConfig -> SourceLocationRange -> Type -> Result Problem Type


qualifyMemberType config range type_ =
    case type_ of




















        Type.Custom name ->


















            case Dict.get name config.ast.types of
                Just _ ->
                    Ok <| Type.Custom (qualifyName config name)

                Nothing ->
                    Err <| UnknownTypeRef range name

        Type.CustomGeneric name binds ->
            case Dict.get name config.ast.types of
                Just _ ->

                    Ok <| Type.CustomGeneric (qualifyName config name) binds


                Nothing ->
                    Err <| UnknownTypeRef range name






        _ ->







            Ok type_












qualifyDefinition :
    RunConfig
    -> Dict String TypeDefinition
    -> Parser.WordDefinition
    -> ( List Problem, Dict String WordDefinition )
................................................................................

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

        moduleReferences =
            case config.ast.moduleDefinition of
                Parser.Defined def ->
                    { aliases = Dict.union unqualifiedWord.metadata.aliases def.aliases
                    , imports = Dict.union unqualifiedWord.metadata.imports def.imports
                    }

                Parser.Undefined ->
                    { aliases = unqualifiedWord.metadata.aliases
                    , imports = unqualifiedWord.metadata.imports
                    }

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

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

        qualifiedMetadataResult =
            qualifyMetadata config qualifiedTypes unqualifiedWord.name unqualifiedWord.metadata

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


qualifyMetadata :
    RunConfig
    -> Dict String TypeDefinition
    -> String
    -> Metadata
    -> Result Problem Metadata
qualifyMetadata config qualifiedTypes fnName meta =
    let
        wordRange =
            Maybe.withDefault SourceLocation.emptyRange meta.sourceLocationRange











    in
    TypeSignature.toMaybe meta.type_

        |> Maybe.map (\ts -> ts.input ++ ts.output)
        |> Maybe.withDefault []
        |> List.map (validateTypeReferences config qualifiedTypes wordRange)

        |> Result.combine
        |> Result.map
            (\qualifiedFlatTypeSignature ->
                let





                    ts =


                        TypeSignature.map
                            (\wt ->
                                { input = List.take (List.length wt.input) qualifiedFlatTypeSignature
                                , output = List.drop (List.length wt.input) qualifiedFlatTypeSignature
                                }


                            )
                            meta.type_





                in
                { meta

                    | type_ =
                        TypeSignature.map (resolveUnions qualifiedTypes) ts
                    , isExposed =
                        case config.ast.moduleDefinition of
                            Parser.Undefined ->
                                True

                            Parser.Defined def ->
                                Set.member fnName def.exposes
                }
            )


validateTypeReferences : RunConfig -> Dict String TypeDefinition -> SourceLocationRange -> Type -> Result Problem Type
validateTypeReferences config typeDefs wordRange type_ =
    case type_ of
................................................................................
            , Ok ( qualifiedMatch, qualifiedImplementation ) :: result
            )


qualifyMatch : RunConfig -> Dict String TypeDefinition -> Parser.TypeMatch -> Result Problem TypeMatch
qualifyMatch config qualifiedTypes typeMatch =
    case typeMatch of
        Parser.TypeMatch range Type.Int [] ->
            Ok <| TypeMatch range Type.Int []

        Parser.TypeMatch range Type.Int [ ( "value", Parser.LiteralInt val ) ] ->
            Ok <| TypeMatch range Type.Int [ ( "value", LiteralInt val ) ]

        Parser.TypeMatch range ((Type.Generic _) as type_) [] ->
            Ok <| TypeMatch range type_ []

        Parser.TypeMatch range (Type.Custom name) patterns ->
            let
                qualifiedName =
                    qualifyName config name
            in
            case Dict.get qualifiedName qualifiedTypes of
                Just (CustomTypeDef _ _ gens members) ->
                    let
................................................................................
qualifyMatchValue config qualifiedTypes range typeName memberNames ( fieldName, matchValue ) =
    if Set.member fieldName memberNames then
        case matchValue of
            Parser.LiteralInt val ->
                Ok <| ( fieldName, LiteralInt val )

            Parser.LiteralType type_ ->






                Ok <| ( fieldName, LiteralType type_ )




            Parser.RecursiveMatch typeMatch ->
                case qualifyMatch config qualifiedTypes typeMatch of
                    Err err ->
                        Err err

                    Ok match ->
................................................................................
        |> Set.foldl fullyQualify Set.empty


requiredModulesOfWord : Dict String String -> Parser.WordDefinition -> Set String
requiredModulesOfWord topLevelAliases word =
    let
        wordAliases =
            word.metadata.aliases
                |> Dict.values
                |> Set.fromList

        wordImports =
            word.metadata.imports
                |> Dict.keys
                |> Set.fromList

        impls =
            case word.implementation of
                Parser.SoloImpl impl ->
                    [ impl ]
................................................................................

                Parser.MultiImpl branches impl ->
                    impl :: List.map Tuple.second branches

        wordReferences =
            impls
                |> List.concat
                |> List.filterMap (extractModuleReferenceFromNode topLevelAliases word.metadata)
                |> Set.fromList
    in
    wordAliases
        |> Set.union wordImports
        |> Set.union wordReferences


extractModuleReferenceFromNode : Dict String String -> Metadata -> Parser.AstNode -> Maybe String
extractModuleReferenceFromNode topLevelAliases meta node =
    case node of
        Parser.PackageWord _ [ potentialAlias ] _ ->
            case
                ( Dict.get potentialAlias topLevelAliases
                , Dict.get potentialAlias meta.aliases
                )







>
>
|
>
>


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







|
|
<
>
|
>

<
|
>
>
>
>
>

<
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>







 







|
|



|
|











|







 







|
<

|


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

<
>


<
>




>
>
>
>
>

>
>
|
<
<
<
|
>
>
|
<
>
>
>
>
>

<
>








|







 







|


|


|
|

|







 







>
>
>
>
>
>
|
>
>
>







 







|




|







 







|







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
376
377
378
379
380
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



418
419
420
421

422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
...
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
...
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
...
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990

                Ok qualifiedMemberTypes ->
                    ( errors
                    , Dict.insert qualifiedName (UnionTypeDef qualifiedName range generics qualifiedMemberTypes) acc
                    )


qualifyMemberType :
    RunConfig
    -> SourceLocationRange
    -> Parser.PossiblyQualifiedType
    -> Result Problem Type
qualifyMemberType config range type_ =
    case type_ of
        Parser.LocalRef name [] ->
            case Dict.get name config.ast.types of
                Just _ ->
                    Ok <| Type.Custom (qualifyName config name)

                Nothing ->
                    Err <| UnknownTypeRef range name

        Parser.LocalRef name binds ->
            case Dict.get name config.ast.types of
                Just _ ->
                    let
                        bindResult =
                            binds
                                |> List.map (qualifyMemberType config range)
                                |> Result.combine
                    in
                    case bindResult of
                        Ok convertedBindings ->
                            Ok <|
                                Type.CustomGeneric
                                    (qualifyName config name)
                                    convertedBindings

                        Err err ->
                            Err err

                Nothing ->
                    Err <| UnknownTypeRef range name

        Parser.InternalRef _ name _ ->
            case Dict.get name config.ast.types of
                Just _ ->
                    Ok <| Type.Custom (qualifyName config name)

                Nothing ->
                    Err <| UnknownTypeRef range name

        Parser.ExternalRef _ name _ ->
            case Dict.get name config.ast.types of
                Just _ ->
                    Ok <| Type.Custom (qualifyName config name)

                Nothing ->
                    Err <| UnknownTypeRef range name

        Parser.Generic sym ->
            Ok (Type.Generic sym)


        Parser.StackRange sym ->
            Ok (Type.Generic sym)


        Parser.QuotationType sign ->
            let
                inputResult =
                    sign.input
                        |> List.map (qualifyMemberType config range)
                        |> Result.combine


                outputResult =
                    sign.output
                        |> List.map (qualifyMemberType config range)
                        |> Result.combine
            in
            case ( inputResult, outputResult ) of
                ( Ok input, Ok output ) ->
                    Ok <|
                        Type.Quotation
                            { input = input
                            , output = output
                            }

                ( Err input, _ ) ->
                    Err input

                ( _, Err output ) ->
                    Err output


qualifyDefinition :
    RunConfig
    -> Dict String TypeDefinition
    -> Parser.WordDefinition
    -> ( List Problem, Dict String WordDefinition )
................................................................................

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

        moduleReferences =
            case config.ast.moduleDefinition of
                Parser.Defined def ->
                    { aliases = Dict.union unqualifiedWord.aliases def.aliases
                    , imports = Dict.union unqualifiedWord.imports def.imports
                    }

                Parser.Undefined ->
                    { aliases = unqualifiedWord.aliases
                    , imports = unqualifiedWord.imports
                    }

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

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

        qualifiedMetadataResult =
            qualifyMetadata config qualifiedTypes unqualifiedWord

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


qualifyMetadata :
    RunConfig
    -> Dict String TypeDefinition
    -> Parser.WordDefinition

    -> Result Problem Metadata
qualifyMetadata config qualifiedTypes word =
    let
        wordRange =
            Maybe.withDefault SourceLocation.emptyRange word.sourceLocationRange

        inputLength =
            case word.typeSignature of
                Parser.NotProvided ->
                    0

                Parser.UserProvided wt ->
                    List.length wt.input

                Parser.Verified wt ->
                    List.length wt.input
    in

    Parser.typeSignatureToMaybe word.typeSignature
        |> Maybe.map (\ts -> ts.input ++ ts.output)
        |> Maybe.withDefault []

        |> List.map (qualifyMemberType config wordRange)
        |> Result.combine
        |> Result.map
            (\qualifiedFlatTypeSignature ->
                let
                    wordType =
                        { input = List.take inputLength qualifiedFlatTypeSignature
                        , output = List.drop inputLength qualifiedFlatTypeSignature
                        }

                    ts =
                        case word.typeSignature of
                            Parser.NotProvided ->
                                TypeSignature.NotProvided




                            Parser.UserProvided _ ->
                                TypeSignature.UserProvided wordType


                            Parser.Verified _ ->
                                TypeSignature.CompilerProvided wordType

                    baseMeta =
                        Metadata.default
                in

                { baseMeta
                    | type_ =
                        TypeSignature.map (resolveUnions qualifiedTypes) ts
                    , isExposed =
                        case config.ast.moduleDefinition of
                            Parser.Undefined ->
                                True

                            Parser.Defined def ->
                                Set.member word.name def.exposes
                }
            )


validateTypeReferences : RunConfig -> Dict String TypeDefinition -> SourceLocationRange -> Type -> Result Problem Type
validateTypeReferences config typeDefs wordRange type_ =
    case type_ of
................................................................................
            , Ok ( qualifiedMatch, qualifiedImplementation ) :: result
            )


qualifyMatch : RunConfig -> Dict String TypeDefinition -> Parser.TypeMatch -> Result Problem TypeMatch
qualifyMatch config qualifiedTypes typeMatch =
    case typeMatch of
        Parser.TypeMatch range (Parser.LocalRef "Int" []) [] ->
            Ok <| TypeMatch range Type.Int []

        Parser.TypeMatch range (Parser.LocalRef "Int" []) [ ( "value", Parser.LiteralInt val ) ] ->
            Ok <| TypeMatch range Type.Int [ ( "value", LiteralInt val ) ]

        Parser.TypeMatch range (Parser.Generic sym) [] ->
            Ok <| TypeMatch range (Type.Generic sym) []

        Parser.TypeMatch range (Parser.LocalRef name []) patterns ->
            let
                qualifiedName =
                    qualifyName config name
            in
            case Dict.get qualifiedName qualifiedTypes of
                Just (CustomTypeDef _ _ gens members) ->
                    let
................................................................................
qualifyMatchValue config qualifiedTypes range typeName memberNames ( fieldName, matchValue ) =
    if Set.member fieldName memberNames then
        case matchValue of
            Parser.LiteralInt val ->
                Ok <| ( fieldName, LiteralInt val )

            Parser.LiteralType type_ ->
                let
                    qualifyTypeResult =
                        qualifyMemberType config range type_
                in
                case qualifyTypeResult of
                    Ok qualifiedType ->
                        Ok <| ( fieldName, LiteralType qualifiedType )

                    Err err ->
                        Err err

            Parser.RecursiveMatch typeMatch ->
                case qualifyMatch config qualifiedTypes typeMatch of
                    Err err ->
                        Err err

                    Ok match ->
................................................................................
        |> Set.foldl fullyQualify Set.empty


requiredModulesOfWord : Dict String String -> Parser.WordDefinition -> Set String
requiredModulesOfWord topLevelAliases word =
    let
        wordAliases =
            word.aliases
                |> Dict.values
                |> Set.fromList

        wordImports =
            word.imports
                |> Dict.keys
                |> Set.fromList

        impls =
            case word.implementation of
                Parser.SoloImpl impl ->
                    [ impl ]
................................................................................

                Parser.MultiImpl branches impl ->
                    impl :: List.map Tuple.second branches

        wordReferences =
            impls
                |> List.concat
                |> List.filterMap (extractModuleReferenceFromNode topLevelAliases word)
                |> Set.fromList
    in
    wordAliases
        |> Set.union wordImports
        |> Set.union wordReferences


extractModuleReferenceFromNode : Dict String String -> Parser.WordDefinition -> Parser.AstNode -> Maybe String
extractModuleReferenceFromNode topLevelAliases meta node =
    case node of
        Parser.PackageWord _ [ potentialAlias ] _ ->
            case
                ( Dict.get potentialAlias topLevelAliases
                , Dict.get potentialAlias meta.aliases
                )

Modified tests/Test/Parser/Util.elm from [6ce6ed116d] to [c6efc18281].

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147





148
149
150
151
152
153
154
155
156
157
158
159
160




161
162
163
164
165
166
167
168
169
170
171
172
173
174




175
176
177
178
179
180
181
            AST.UnionTypeDef emptyRange name generics members


stripWordLocation : WordDefinition -> WordDefinition
stripWordLocation word =
    { word
        | implementation = stripImplementationLocation word.implementation
        , metadata = Metadata.clearSourceLocationRange word.metadata
    }


stripImplementationLocation : WordImplementation -> WordImplementation
stripImplementationLocation impl =
    case impl of
        SoloImpl nodes ->
................................................................................

                _ ->
                    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
                Type.CustomGeneric name (List.map Type.Generic generics)

        ctor =
            { name =
                if List.isEmpty members then
                    name

                else
                    ">" ++ name
            , metadata =
                Metadata.default
                    |> Metadata.withVerifiedType (List.map Tuple.second members) [ selfType ]





            , implementation = AST.SoloImpl [ AST.ConstructType name ]
            }

        setters =
            List.map settersHelper members

        settersHelper ( memberName, type_ ) =
            { name = ">" ++ memberName
            , metadata =
                Metadata.default
                    |> Metadata.withVerifiedType
                        [ selfType, type_ ]
                        [ selfType ]




            , implementation =
                AST.SoloImpl [ AST.SetMember name memberName ]
            }

        getters =
            List.map gettersHelper members

        gettersHelper ( memberName, type_ ) =
            { name = memberName ++ ">"
            , metadata =
                Metadata.default
                    |> Metadata.withVerifiedType
                        [ selfType ]
                        [ type_ ]




            , implementation =
                AST.SoloImpl [ AST.GetMember name memberName ]
            }

        allFuncs =
            (ctor :: setters)
                ++ getters







|







 







|



|
<
<
<
<








|
|
|
>
>
>
>
>








|
<
|
|
|
>
>
>
>









|
<
|
|
|
>
>
>
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
...
121
122
123
124
125
126
127
128
129
130
131
132




133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188
            AST.UnionTypeDef emptyRange name generics members


stripWordLocation : WordDefinition -> WordDefinition
stripWordLocation word =
    { word
        | implementation = stripImplementationLocation word.implementation
        , sourceLocationRange = Nothing
    }


stripImplementationLocation : WordImplementation -> WordImplementation
stripImplementationLocation impl =
    case impl of
        SoloImpl nodes ->
................................................................................

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


addFunctionsForStructsHelper : String -> List String -> List ( String, AST.PossiblyQualifiedType ) -> AST -> AST
addFunctionsForStructsHelper name generics members ast =
    let
        selfType =
            LocalRef name (List.map Generic generics)





        ctor =
            { name =
                if List.isEmpty members then
                    name

                else
                    ">" ++ name
            , typeSignature =
                Verified
                    { input = List.map Tuple.second members
                    , output = [ selfType ]
                    }
            , sourceLocationRange = Nothing
            , aliases = Dict.empty
            , imports = Dict.empty
            , implementation = AST.SoloImpl [ AST.ConstructType name ]
            }

        setters =
            List.map settersHelper members

        settersHelper ( memberName, type_ ) =
            { name = ">" ++ memberName
            , typeSignature =

                Verified
                    { input = [ selfType, type_ ]
                    , output = [ selfType ]
                    }
            , sourceLocationRange = Nothing
            , aliases = Dict.empty
            , imports = Dict.empty
            , implementation =
                AST.SoloImpl [ AST.SetMember name memberName ]
            }

        getters =
            List.map gettersHelper members

        gettersHelper ( memberName, type_ ) =
            { name = memberName ++ ">"
            , typeSignature =

                Verified
                    { input = [ selfType ]
                    , output = [ type_ ]
                    }
            , sourceLocationRange = Nothing
            , aliases = Dict.empty
            , imports = Dict.empty
            , implementation =
                AST.SoloImpl [ AST.GetMember name memberName ]
            }

        allFuncs =
            (ctor :: setters)
                ++ getters

Modified tests/Test/Qualifier/Error.elm from [689378d359] to [0f9091b125].

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
..
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
..
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
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
                    let
                        ast =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "inc"
                                      , metadata = Metadata.default



                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "+"
                                                ]
                                      }
                                    , { name = "main"
                                      , metadata =
                                            Metadata.default
                                                |> Metadata.asEntryPoint

                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "inc"
                                                , AST.Word emptyRange "inc"
                                                , AST.Word emptyRange "dec"
                                                , AST.Integer emptyRange 2
................................................................................
                    let
                        ast =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "main"
                                      , metadata =
                                            Metadata.default
                                                |> Metadata.asEntryPoint

                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "/external/module/inc"
                                                ]
                                      }
                                    ]
................................................................................
                    let
                        ast =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "inc"
                                      , metadata =
                                            Metadata.default
                                                |> Metadata.withType [ Type.Custom "Ints" ] [ Type.Int ]





                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "+"
                                                ]
                                      }
                                    , { name = "main"
                                      , metadata =
                                            Metadata.default
                                                |> Metadata.asEntryPoint

                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "inc"
                                                , AST.Integer emptyRange 2
                                                , AST.Word emptyRange "="
                                                ]
................................................................................
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types =
                                Dict.fromListBy AST.typeDefinitionName
                                    [ AST.UnionTypeDef
                                        emptyRange
                                        "USMoney"
                                        []
                                        [ Type.Custom "Dollar"
                                        , Type.Custom "Cent"
                                        ]
                                    , AST.CustomTypeDef
                                        emptyRange
                                        "Dollar"
                                        []
                                        [ ( "dollar-value", Type.Int ) ]
                                    ]
                            , words = Dict.empty
                            }
                    in
                    checkForError (noSuchTypeReferenceError "Cent") ast
            , test "Wrong reference within custom type definition" <|
                \_ ->
................................................................................
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types =
                                Dict.fromListBy AST.typeDefinitionName
                                    [ AST.CustomTypeDef
                                        emptyRange
                                        "BoxWrapper"
                                        []
                                        [ ( "box", Type.Custom "Box" ) ]
                                    ]
                            , words = Dict.empty
                            }
                    in
                    checkForError (noSuchTypeReferenceError "Box") ast
            ]
        ]







|
>
>
>







|
|
|
>







 







|
|
|
>







 







|
|
|
>
>
>
>
>







|
|
|
>







 







|
|





|







 







|







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
..
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
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
...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
                    let
                        ast =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "inc"
                                      , typeSignature = AST.NotProvided
                                      , sourceLocationRange = Nothing
                                      , aliases = Dict.empty
                                      , imports = Dict.empty
                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "+"
                                                ]
                                      }
                                    , { name = "main"
                                      , typeSignature = AST.NotProvided
                                      , sourceLocationRange = Nothing
                                      , aliases = Dict.empty
                                      , imports = Dict.empty
                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "inc"
                                                , AST.Word emptyRange "inc"
                                                , AST.Word emptyRange "dec"
                                                , AST.Integer emptyRange 2
................................................................................
                    let
                        ast =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "main"
                                      , typeSignature = AST.NotProvided
                                      , sourceLocationRange = Nothing
                                      , aliases = Dict.empty
                                      , imports = Dict.empty
                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "/external/module/inc"
                                                ]
                                      }
                                    ]
................................................................................
                    let
                        ast =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "inc"
                                      , typeSignature =
                                            AST.UserProvided
                                                { input = [ AST.LocalRef "Ints" [] ]
                                                , output = [ AST.LocalRef "Int" [] ]
                                                }
                                      , sourceLocationRange = Nothing
                                      , aliases = Dict.empty
                                      , imports = Dict.empty
                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "+"
                                                ]
                                      }
                                    , { name = "main"
                                      , typeSignature = AST.NotProvided
                                      , sourceLocationRange = Nothing
                                      , aliases = Dict.empty
                                      , imports = Dict.empty
                                      , implementation =
                                            AST.SoloImpl
                                                [ AST.Integer emptyRange 1
                                                , AST.Word emptyRange "inc"
                                                , AST.Integer emptyRange 2
                                                , AST.Word emptyRange "="
                                                ]
................................................................................
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types =
                                Dict.fromListBy AST.typeDefinitionName
                                    [ AST.UnionTypeDef
                                        emptyRange
                                        "USMoney"
                                        []
                                        [ AST.LocalRef "Dollar" []
                                        , AST.LocalRef "Cent" []
                                        ]
                                    , AST.CustomTypeDef
                                        emptyRange
                                        "Dollar"
                                        []
                                        [ ( "dollar-value", AST.LocalRef "Int" [] ) ]
                                    ]
                            , words = Dict.empty
                            }
                    in
                    checkForError (noSuchTypeReferenceError "Cent") ast
            , test "Wrong reference within custom type definition" <|
                \_ ->
................................................................................
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types =
                                Dict.fromListBy AST.typeDefinitionName
                                    [ AST.CustomTypeDef
                                        emptyRange
                                        "BoxWrapper"
                                        []
                                        [ ( "box", AST.LocalRef "Box" [] ) ]
                                    ]
                            , words = Dict.empty
                            }
                    in
                    checkForError (noSuchTypeReferenceError "Box") ast
            ]
        ]