nixd
Loading...
Searching...
No Matches
SemaActions.h
Go to the documentation of this file.
1/// \file
2/// \brief Semantic Actions while building the AST
3///
4/// Non grammatical errors (e.g. duplicating) are detected here.
5
10#include "nixf/Basic/Range.h"
11
12#include <map>
13
14namespace nixf {
15
16class Sema {
17 std::string_view Src;
18 std::vector<Diagnostic> &Diags;
19
20 /// Merge Y into X if both expressions are attrsets.
21 bool tryMergeAttrs(Expr *X, Expr *Y);
22
23public:
24 Sema(std::string_view Src, std::vector<Diagnostic> &Diags)
25 : Src(Src), Diags(Diags) {}
26
28
29 /// \brief Make text edits to remove a formal
30 static void removeFormal(Fix &F, const FormalVector::const_iterator &Rm,
31 const FormalVector &FV);
32
33 /// \brief Check if there is a seperator "," between formals
34 void checkFormalSep(const FormalVector &FV);
35
36 /// \brief Check if ellipsis "..."
37 void checkFormalEllipsis(const FormalVector &FV);
38
39 /// \brief Diagnose empty formal i.e. single comma
40 //
41 // e.g. `{ , } : 1`
42 void checkFormalEmpty(const FormalVector &FV);
43
44 /// \brief Deduplicate formals.
45 void dedupFormal(std::map<std::string, const Formal *> &Dedup,
46 const FormalVector &FV);
47
48 std::shared_ptr<Formals> onFormals(LexerCursorRange Range, FormalVector FV);
49
50 /// \brief Desugar inherit (expr) a, inherit a, into select, or variable.
51 static std::pair<std::shared_ptr<Expr>, Attribute::AttributeKind>
52 desugarInheritExpr(std::shared_ptr<AttrName> Name, std::shared_ptr<Expr> E);
53
54 void dupAttr(std::string Name, LexerCursorRange Range, LexerCursorRange Prev);
55
56 /// \brief Check if these two attrsets has the same "recursive" modifier.
57 ///
58 /// Official nix implementation implicitly discards the second modifier, this
59 /// is somehow error-prone, let's detect it.
60 void checkAttrRecursiveForMerge(const ExprAttrs &XAttrs,
61 const ExprAttrs &YAttrs);
62
63 /// \brief Perform attrsets merging while duplicated fields are both attrsets.
64 ///
65 /// e.g.
66 /// \code{nix}
67 /// {
68 /// a = { x = 1; };
69 /// a = { y = 1; };
70 /// }
71 /// \endcode
72 /// We may want to merge both "a = " attrsets into a single one, instead of
73 /// report duplicating attrs.
74 void mergeAttrSets(SemaAttrs &XAttrs, const SemaAttrs &YAttrs);
75
76 /// \note Name must not be null
77 void insertAttr(SemaAttrs &SA, std::shared_ptr<AttrName> Name,
78 std::shared_ptr<Expr> E, Attribute::AttributeKind Kind);
79
80 /// Select into \p Attr the attribute specified by \p Path, or create one if
81 /// not exists, until reached the inner-most attr. Similar to `mkdir -p`.
82 ///
83 /// \return The selected or created attribute.
85 const std::vector<std::shared_ptr<AttrName>> &Path);
86
87 /// Insert the binding: `AttrPath = E;` into \p Attr
88 void addAttr(SemaAttrs &Attr, const AttrPath &Path, std::shared_ptr<Expr> E);
89
90 void lowerInheritName(SemaAttrs &SA, std::shared_ptr<AttrName> Name,
91 std::shared_ptr<Expr> E,
92 Attribute::AttributeKind InheritKind);
93
94 void lowerInherit(SemaAttrs &Attr, const Inherit &Inherit);
95
96 void lowerBinds(SemaAttrs &SA, const Binds &B);
97
98 std::shared_ptr<ExprAttrs> onExprAttrs(LexerCursorRange Range,
99 std::shared_ptr<Binds> Binds,
100 std::shared_ptr<Misc> Rec);
101
102 std::shared_ptr<LambdaArg> onLambdaArg(LexerCursorRange Range,
103 std::shared_ptr<Identifier> ID,
104 std::shared_ptr<Formals> F);
105};
106
107} // namespace nixf
std::vector< std::shared_ptr< Formal > > FormalVector
Definition Lambda.h:65
Attribute set after deduplication.
Definition Attrs.h:236
SemaAttrs * selectOrCreate(SemaAttrs &SA, const std::vector< std::shared_ptr< AttrName > > &Path)
void insertAttr(SemaAttrs &SA, std::shared_ptr< AttrName > Name, std::shared_ptr< Expr > E, Attribute::AttributeKind Kind)
void lowerInherit(SemaAttrs &Attr, const Inherit &Inherit)
std::shared_ptr< ExprAttrs > onExprAttrs(LexerCursorRange Range, std::shared_ptr< Binds > Binds, std::shared_ptr< Misc > Rec)
std::shared_ptr< LambdaArg > onLambdaArg(LexerCursorRange Range, std::shared_ptr< Identifier > ID, std::shared_ptr< Formals > F)
void dedupFormal(std::map< std::string, const Formal * > &Dedup, const FormalVector &FV)
Deduplicate formals.
void lowerInheritName(SemaAttrs &SA, std::shared_ptr< AttrName > Name, std::shared_ptr< Expr > E, Attribute::AttributeKind InheritKind)
void mergeAttrSets(SemaAttrs &XAttrs, const SemaAttrs &YAttrs)
Perform attrsets merging while duplicated fields are both attrsets.
void checkFormalEllipsis(const FormalVector &FV)
Check if ellipsis "...".
void lowerBinds(SemaAttrs &SA, const Binds &B)
void addAttr(SemaAttrs &Attr, const AttrPath &Path, std::shared_ptr< Expr > E)
Insert the binding: AttrPath = E; into Attr.
void checkFormalSep(const FormalVector &FV)
Check if there is a seperator "," between formals.
void dupAttr(std::string Name, LexerCursorRange Range, LexerCursorRange Prev)
Formals::FormalVector FormalVector
Definition SemaActions.h:27
void checkAttrRecursiveForMerge(const ExprAttrs &XAttrs, const ExprAttrs &YAttrs)
Check if these two attrsets has the same "recursive" modifier.
void checkFormalEmpty(const FormalVector &FV)
Diagnose empty formal i.e. single comma.
std::shared_ptr< Formals > onFormals(LexerCursorRange Range, FormalVector FV)
static void removeFormal(Fix &F, const FormalVector::const_iterator &Rm, const FormalVector &FV)
Make text edits to remove a formal.
Sema(std::string_view Src, std::vector< Diagnostic > &Diags)
Definition SemaActions.h:24
static std::pair< std::shared_ptr< Expr >, Attribute::AttributeKind > desugarInheritExpr(std::shared_ptr< AttrName > Name, std::shared_ptr< Expr > E)
Desugar inherit (expr) a, inherit a, into select, or variable.