8000 Support local type synonyms natively · purescript/purescript@7a60917 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7a60917

Browse files
committed
Support local type synonyms natively
1 parent 18e3b14 commit 7a60917

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1012
-168
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* Support local type synonyms
2+
3+
This feature enables type synonyms to be defined in do, let, and where
4+
blocks, alongside value definitions.

lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ data HintCategory
9797
| CheckHint
9898
| PositionHint
9999
| SolverHint
100-
| DeclarationHint
100+
| TypeDeclarationHint
101+
| ValueDeclarationHint
101102
| OtherHint
102103
deriving (Show, Eq)
103104

lib/purescript-cst/src/Language/PureScript/AST/Traversals.hs

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -493,50 +493,56 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
493493
k' s (ConditionGuard e) = ConditionGuard <$> g'' s e
494494
k' s (PatternGuard b e) = PatternGuard <$> h'' s b <*> g'' s e
495495

496-
data ScopedIdent = LocalIdent Ident | ToplevelIdent Ident
496+
data ScopedName = LocalName Name | ToplevelName Name
497497
deriving (Show, Eq, Ord)
498498

499-
inScope :: Ident -> S.Set ScopedIdent -> Bool
500-
inScope i s = (LocalIdent i `S.member` s) || (ToplevelIdent i `S.member` s)
499+
inScope' :: (a -> Name) -> a -> S.Set ScopedName -> Bool
500+
inScope' ctor i s = (LocalName (ctor i) `S.member` s) || (ToplevelName (ctor i) `S.member` s)
501+
502+
inScope :: Ident -> S.Set ScopedName -> Bool
503+
inScope = inScope' IdentName
504+
505+
typeInScope :: ProperName 'TypeName -> S.Set ScopedName -> Bool
506+
typeInScope = inScope' TyName
501507

502508
everythingWithScope
503509
:: forall r
504510
. (Monoid r)
505-
=> (S.Set ScopedIdent -> Declaration -> r)
506-
-> (S.Set ScopedIdent -> Expr -> r)
507-
-> (S.Set ScopedIdent -> Binder -> r)
508-
-> (S.Set ScopedIdent -> CaseAlternative -> r)
509-
-> (S.Set ScopedIdent -> DoNotationElement -> r)
510-
-> ( S.Set ScopedIdent -> Declaration -> r
511-
, S.Set ScopedIdent -> Expr -> r
512-
, S.Set ScopedIdent -> Binder -> r
513-
, S.Set ScopedIdent -> CaseAlternative -> r
514-
, S.Set ScopedIdent -> DoNotationElement -> r
511+
=> (S.Set ScopedName -> Declaration -> r)
512+
-> (S.Set ScopedName -> Expr -> r)
513+
-> (S.Set ScopedName -> Binder -> r)
514+
-> (S.Set ScopedName -> CaseAlternative -> r)
515+
-> (S.Set ScopedName -> DoNotationElement -> r)
516+
-> ( S.Set ScopedName -> Declaration -> r
517+
, S.Set ScopedName -> Expr -> r
518+
, S.Set ScopedName -> Binder -> r
519+
, S.Set ScopedName -> CaseAlternative -> r
520+
, S.Set ScopedName -> DoNotationElement -> r
515521
)
516522
everythingWithScope f g h i j = (f'', g'', h'', i'', \s -> snd . j'' s)
517523
where
518-
f'' :: S.Set ScopedIdent -> Declaration -> r
524+
f'' :: S.Set ScopedName -> Declaration -> r
519525
f'' s a = f s a <> f' s a
520526

521-
f' :: S.Set ScopedIdent -> Declaration -> r
527+
f' :: S.Set ScopedName -> Declaration -> r
522528
f' s (DataBindingGroupDeclaration ds) =
523-
let s' = S.union s (S.fromList (map ToplevelIdent (mapMaybe getDeclIdent (NEL.toList ds))))
529+
let s' = S.union s (S.fromList (map ToplevelName (mapMaybe declName (NEL.toList ds))))
524530
in foldMap (f'' s') ds
525531
f' s (ValueDecl _ name _ bs val) =
526-
let s' = S.insert (ToplevelIdent name) s
532+
let s' = S.insert (ToplevelName (IdentName name)) s
527533
s'' = S.union s' (S.fromList (concatMap localBinderNames bs))
528534
in foldMap (h'' s') bs <> foldMap (l' s'') val
529535
f' s (BindingGroupDeclaration ds) =
530-
let s' = S.union s (S.fromList (NEL.toList (fmap (\((_, name), _, _) -> ToplevelIdent name) ds)))
536+
let s' = S.union s (S.fromList (NEL.toList (fmap (\((_, name), _, _) -> ToplevelName (IdentName name)) ds)))
531537
in foldMap (\(_, _, val) -> g'' s' val) ds
532538
f' s (TypeClassDeclaration _ _ _ _ _ ds) = foldMap (f'' s) ds
533539
f' s (TypeInstanceDeclaration _ _ _ _ _ _ _ (ExplicitInstance ds)) = foldMap (f'' s) ds
534540
f' _ _ = mempty
535541

536-
g'' :: S.Set ScopedIdent -> Expr -> r
542+
g'' :: S.Set ScopedName -> Expr -> r
537543
g'' s a = g s a <> g' s a
538544

539-
g' :: S.Set ScopedIdent -> Expr -> r
545+
g' :: S.Set ScopedName -> Expr -> r
540546
g' s (Literal _ l) = lit g'' s l
541547
g' s (UnaryMinus _ v1) = g'' s v1
542548
g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
@@ -553,7 +559,7 @@ everythingWithScope f g h i j = (f'', g'', h'', i'', \s -> snd . j'' s)
553559
g' s (Case vs alts) = foldMap (g'' s) vs <> foldMap (i'' s) alts
554560
g' s (TypedValue _ v1 _) = g'' s v1
555561
g' s (Let _ ds v1) =
556-
let s' = S.union s (S.fromList (map LocalIdent (mapMaybe getDeclIdent ds)))
562+
let s' = S.union s (S.fromList (map LocalName (mapMaybe declName ds)))
557563
in foldMap (f'' s') ds <> g'' s' v1
558564
g' s (Do _ es) = fold . snd . mapAccumL j'' s $ es
559565
g' s (Ado _ es v1) =
@@ -562,46 +568,46 @@ everythingWithScope f g h i j = (f'', g'', h'', i'', \s -> snd . j'' s)
562568
g' s (PositionedValue _ _ v1) = g'' s v1
563569
g' _ _ = mempty
564570

565-
h'' :: S.Set ScopedIdent -> Binder -> r
571+
h'' :: S.Set ScopedName -> Binder -> r
566572
h'' s a = h s a <> h' s a
567573

568-
h' :: S.Set ScopedIdent -> Binder -> r
574+
h' :: S.Set ScopedName -> Binder -> r
569575
h' s (LiteralBinder _ l) = lit h'' s l
570576
h' s (ConstructorBinder _ _ bs) = foldMap (h'' s) bs
571577
h' s (BinaryNoParensBinder b1 b2 b3) = foldMap (h'' s) [b1, b2, b3]
572578
h' s (ParensInBinder b) = h'' s b
573-
h' s (NamedBinder _ name b1) = h'' (S.insert (LocalIdent name) s) b1
579+
h' s (NamedBinder _ name b1) = h'' (S.insert (LocalName (IdentName name)) s) b1
574580
h' s (PositionedBinder _ _ b1) = h'' s b1
575581
h' s (TypedBinder _ b1) = h'' s b1
576582
h' _ _ = mempty
577583

578-
lit :: (S.Set ScopedIdent -> a -> r) -> S.Set ScopedIdent -> Literal a -> r
584+
lit :: (S.Set ScopedName -> a -> r) -> S.Set ScopedName -> Literal a -> r
579585
lit go s (ArrayLiteral as) = foldMap (go s) as
580586
lit go s (ObjectLiteral as) = foldMap (go s . snd) as
581587
lit _ _ _ = mempty
582588

583-
i'' :: S.Set ScopedIdent -> CaseAlternative -> r
589+
i'' :: S.Set ScopedName -> CaseAlternative -> r
584590
i'' s a = i s a <> i' s a
585591

586-
i' :: S.Set ScopedIdent -> CaseAlternative -> r
592+
i' :: S.Set ScopedName -> CaseAlternative -> r
587593
i' s (CaseAlternative bs gs) =
588594
let s' = S.union s (S.fromList (concatMap localBinderNames bs))
589595
in foldMap (h'' s) bs <> foldMap (l' s') gs
590596

591-
j'' :: S.Set ScopedIdent -> DoNotationElement -> (S.Set ScopedIdent, r)
597+
j'' :: S.Set ScopedName -> DoNotationElement -> (S.Set ScopedName, r)
592598
j'' s a = let (s', r) = j' s a in (s', j s a <> r)
593599

594-
j' :: S.Set ScopedIdent -> DoNotationElement -> (S.Set ScopedIdent, r)
600+
j' :: S.Set ScopedName -> DoNotationElement -> (S.Set ScopedName, r)
595601
j' s (DoNotationValue v) = (s, g'' s v)
596602
j' s (DoNotationBind b v) =
597603
let s' = S.union (S.fromList (localBinderNames b)) s
598604
in (s', h'' s b <> g'' s v)
599605
j' s (DoNotationLet ds) =
600-
let s' = S.union s (S.fromList (map LocalIdent (mapMaybe getDeclIdent ds)))
606+
let s' = S.union s (S.fromList (map LocalName (mapMaybe declName ds)))
601607
in (s', foldMap (f'' s') ds)
602608
j' s (PositionedDoNotationElement _ _ e1) = j'' s e1
603609

604-
k' :: S.Set ScopedIdent -> Guard -> (S.Set ScopedIdent, r)
610+
k' :: S.Set ScopedName -> Guard -> (S.Set ScopedName, r)
605611
k' s (ConditionGuard e) = (s, g'' s e)
606612
k' s (PatternGuard b e) =
607613
let s' = S.union (S.fromList (localBinderNames b)) s
@@ -612,12 +618,7 @@ everythingWithScope f g h i j = (f'', g'', h'', i'', \s -> snd . j'' s)
612618
let (s', r) = k' s grd
613619
in r <> l' s' (GuardedExpr gs e)
614620

615-
getDeclIdent :: Declaration -> Maybe Ident
616-
getDeclIdent (ValueDeclaration vd) = Just (valdeclIdent vd)
617-
getDeclIdent (TypeDeclaration td) = Just (tydeclIdent td)
618-
getDeclIdent _ = Nothing
619-
620-
localBinderNames = map LocalIdent . binderNames
621+
localBinderNames = map (LocalName . IdentName) . binderNames
621622

622623
accumTypes
623624
:: (Monoid r)

lib/purescript-cst/src/Language/PureScript/CST/Convert.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,16 @@ convertLetBinding fileName = \case
226226
binding@(LetBindingPattern _ a _ b) -> do
227227
let ann = uncurry (sourceAnnCommented fileName) $ letBindingRange binding
228228
AST.BoundValueDeclaration ann (convertBinder fileName a) (convertWhere fileName b)
229+
binding@(LetBindingType _ (DataHead _ a vars) _ bd) -> do
230+
let ann = uncurry (sourceAnnCommented fileName) $ letBindingRange binding
231+
AST.TypeSynonymDeclaration ann (nameValue a) (goTypeVar <$> vars) (convertType fileName bd)
232+
binding@(LetBindingKindSignature _ _ (Labeled name _ ty)) -> do
233+
let ann = uncurry (sourceAnnCommented fileName) $ letBindingRange binding
234+
AST.KindDeclaration ann AST.TypeSynonymSig (nameValue name) $ convertType fileName ty
235+
where
236+
goTypeVar = \case
237+
TypeVarKinded (Wrapped _ (Labeled x _ y) _) -> (getIdent $ nameValue x, Just $ convertType fileName y)
238+
TypeVarName x -> (getIdent $ nameValue x, Nothing)
229239

230240
convertExpr :: forall a. String -> Expr a -> AST.Expr
231241
convertExpr fileName = go

lib/purescript-cst/src/Language/PureScript/CST/Flatten.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ flattenLetBinding = \case
163163
LetBindingSignature _ a -> flattenLabeled flattenName flattenType a
164164
LetBindingName _ a -> flattenValueBindingFields a
165165
LetBindingPattern _ a b c -> flattenBinder a <> pure b <> flattenWhere c
166+
LetBindingType _ a b c -> flattenDataHead a <> pure b <> flattenType c
167+
LetBindingKindSignature _ a b -> pure a <> flattenLabeled flattenName flattenType b
166168

167169
flattenWhere :: Where a -> DList SourceToken
168170
flattenWhere (Where a b) =

lib/purescript-cst/src/Language/PureScript/CST/Parser.y

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ letBinding :: { LetBinding () }
457457
| ident guardedDecl { LetBindingName () (ValueBindingFields $1 [] $2) }
458458
| ident many(binderAtom) guardedDecl { LetBindingName () (ValueBindingFields $1 (NE.toList $2) $3) }
459459
| binder1 '=' exprWhere { LetBindingPattern () $1 $2 $3 }
460+
| typeHead '=' type {% checkNoWildcards $3 *> pure (LetBindingType () $1 $2 $3) }
461+
| 'type' properName '::' type {% checkNoWildcards $4 *> pure (LetBindingKindSignature () $1 (Labeled (getProperName $2) $3 $4)) }
460462
461463
caseBranch :: { (Separated (Binder ()), Guarded ()) }
462464
: sep(binder1, ',') guardedCase { ($1, $2) }

lib/purescript-cst/src/Language/PureScript/CST/Positions.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ letBindingRange = \case
304304
LetBindingSignature _ (Labeled a _ b) -> (nameTok a, snd $ typeRange b)
305305
LetBindingName _ a -> valueBindingFieldsRange a
306306
LetBindingPattern _ a _ b -> (fst $ binderRange a, snd $ whereRange b)
307+
LetBindingType _ a _ b -> (fst $ dataHeadRange a, snd $ typeRange b)
308+
LetBindingKindSignature _ a (Labeled _ _ b) -> (a, snd $ typeRange b)
307309

308310
doStatementRange :: DoStatement a -> TokenRange
309311
doStatementRange = \case

lib/purescript-cst/src/Language/PureScript/CST/Types.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ data LetBinding a
401401
= LetBindingSignature a (Labeled (Name Ident) (Type a))
402402
| LetBindingName a (ValueBindingFields a)
403403
| LetBindingPattern a (Binder a) SourceToken (Where a)
404+
| LetBindingType a (DataHead a) SourceToken (Type a)
405+
| LetBindingKindSignature a SourceToken (Labeled (Name (N.ProperName 'N.TypeName)) (Type a))
404406
deriving (Show, Eq, Ord, Functor, Foldable, Traversable, Generic)
405407

406408
data DoBlock a = DoBlock

src/Language/PureScript/Errors.hs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,10 @@ data SimpleErrorMessage
136136
| TransitiveDctorExportError DeclarationRef [ProperName 'ConstructorName]
137137
| HiddenConstructors DeclarationRef (Qualified (ProperName 'ClassName))
138138
| ShadowedName Ident
139+
| ShadowedTypeName (ProperName 'TypeName)
139140
| ShadowedTypeVar Text
140141
| UnusedTypeVar Text
141-
| UnusedName Ident
142+
| UnusedName Name
142143
| UnusedDeclaration Ident
143144
| WildcardInferredType SourceType Context
144145
| HoleInferredType Text SourceType Context (Maybe TypeSearch)
@@ -309,6 +310,7 @@ errorCode em = case unwrapErrorMessage em of
309310
ShadowedName{} -> "ShadowedName"
310311
UnusedName{} -> "UnusedName"
311312
UnusedDeclaration{} -> "UnusedDeclaration"
313+
ShadowedTypeName{} -> "ShadowedTypeName"
312314
ShadowedTypeVar{} -> "ShadowedTypeVar"
313315
UnusedTypeVar{} -> "UnusedTypeVar"
314316
WildcardInferredType{} -> "WildcardInferredType"
@@ -1057,10 +1059,12 @@ prettyPrintSingleError (PPEOptions codeColor full level showDocs relPath) e = fl
10571059
]
10581060
renderSimpleErrorMessage (ShadowedName nm) =
10591061
line $ "Name " <> markCode (showIdent nm) <> " was shadowed."
1062+
renderSimpleErrorMessage (ShadowedTypeName nm) =
1063+
line $ "Type " <> markCode (runProperName nm) <> " was shadowed."
10601064
renderSimpleErrorMessage (ShadowedTypeVar tv) =
10611065
line $ "Type variable " <> markCode tv <> " was shadowed."
10621066
renderSimpleErrorMessage (UnusedName nm) =
1063-
line $ "Name " <> markCode (showIdent nm) <> " was introduced but not used."
1067+
line $ "Name " <> markCode (runName (Qualified Nothing nm)) <> " was introduced but not used."
10641068
renderSimpleErrorMessage (UnusedDeclaration nm) =
10651069
line $ "Declaration " <> markCode (showIdent nm) <> " was not used, and is not exported."
10661070
renderSimpleErrorMessage (UnusedTypeVar tv) =
@@ -1675,17 +1679,17 @@ prettyPrintSingleError (PPEOptions codeColor full level showDocs relPath) e = fl
16751679
hintCategory ErrorCheckingKind{} = CheckHint
16761680
hintCategory ErrorSolvingConstraint{} = SolverHint
16771681
hintCategory PositionedError{} = PositionHint
1678-
hintCategory ErrorInDataConstructor{} = DeclarationHint
1679-
hintCategory ErrorInTypeConstructor{} = DeclarationHint
1680-
hintCategory ErrorInBindingGroup{} = DeclarationHint
1681-
hintCategory ErrorInDataBindingGroup{} = DeclarationHint
1682-
hintCategory ErrorInTypeSynonym{} = DeclarationHint
1683-
hintCategory ErrorInValueDeclaration{} = DeclarationHint
1684-
hintCategory ErrorInTypeDeclaration{} = DeclarationHint
1685-
hintCategory ErrorInTypeClassDeclaration{} = DeclarationHint
1686-
hintCategory ErrorInKindDeclaration{} = DeclarationHint
1687-
hintCategory ErrorInRoleDeclaration{} = DeclarationHint
1688-
hintCategory ErrorInForeignImport{} = DeclarationHint
1682+
hintCategory ErrorInDataConstructor{} = TypeDeclarationHint
1683+
hintCategory ErrorInTypeConstructor{} = TypeDeclarationHint
1684+
hintCategory ErrorInDataBindingGroup{} = TypeDeclarationHint
1685+
hintCategory ErrorInTypeSynonym{} = TypeDeclarationHint
1686+
hintCategory ErrorInTypeDeclaration{} = TypeDeclarationHint
1687+
hintCategory ErrorInTypeClassDeclaration{} = TypeDeclarationHint
1688+
hintCategory ErrorInKindDeclaration{} = TypeDeclarationHint
1689+
hintCategory ErrorInRoleDeclaration{} = TypeDeclarationHint
1690+
hintCategory ErrorInBindingGroup{} = ValueDeclarationHint
1691+
hintCategory ErrorInValueDeclaration{} = ValueDeclarationHint
1692+
hintCategory ErrorInForeignImport{} = ValueDeclarationHint
16891693
hintCategory _ = OtherHint
16901694

16911695
prettyPrintPlainIdent :: Ident -> Text

src/Language/PureScript/Ide/Usage.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ applySearch module_ search =
141141
P.Var sp i
142142
| Just ideValue <- preview _IdeDeclValue (P.disqualify search)
143143
, P.isQualified search
144-
|| not (P.LocalIdent (_ideValueIdent ideValue) `Set.member` scope) ->
144+
|| not (P.LocalName (P.IdentName (_ideValueIdent ideValue)) `Set.member` scope) ->
145145
[sp | map P.runIdent i == map identifierFromIdeDeclaration search]
146146
P.Constructor sp name
147147
| Just ideDtor <- traverse (preview _IdeDeclDataConstructor) search ->

0 commit comments

Comments
 (0)
0