17
17
18
18
#include " swift/AST/Parameter.h"
19
19
#include " swift/AST/ASTContext.h"
20
+ #include " swift/AST/Expr.h"
21
+ #include " swift/AST/ExprHandle.h"
20
22
using namespace swift ;
21
23
24
+ // / Return the full source range of this parameter.
25
+ SourceRange Parameter::getSourceRange () const {
26
+ SourceRange range = decl->getSourceRange ();
27
+ if (range.isInvalid ()) return range;
28
+
29
+ // It would be nice to extend the front of the range to show where inout is,
30
+ // but we don't have that location info. Extend the back of the range to the
31
+ // location of the default argument, or the typeloc if they are valid.
32
+ if (auto expr = getDefaultValue ()) {
33
+ auto endLoc = expr->getExpr ()->getEndLoc ();
34
+ if (endLoc.isValid ())
35
+ return SourceRange (range.Start , endLoc);
36
+ }
37
+
38
+ // If the typeloc has a valid location, use it to end the range.
39
+ if (auto typeRepr = type.getTypeRepr ()) {
40
+ auto endLoc = typeRepr->getEndLoc ();
41
+ if (endLoc.isValid ())
42
+ return SourceRange (range.Start , endLoc);
43
+ }
44
+
45
+ // Otherwise, just return the info we have about the parameter.
46
+ return range;
47
+ }
48
+
49
+ Type Parameter::getVarargBaseTy (Type VarArgT) {
50
+ TypeBase *T = VarArgT.getPointer ();
51
+ if (ArraySliceType *AT = dyn_cast<ArraySliceType>(T))
52
+ return AT->getBaseType ();
53
+ if (BoundGenericType *BGT = dyn_cast<BoundGenericType>(T)) {
54
+ // It's the stdlib Array<T>.
55
+ return BGT->getGenericArgs ()[0 ];
56
+ }
57
+ assert (isa<ErrorType>(T));
58
+ return T;
59
+ }
60
+
61
+
22
62
// / TODO: unique and reuse the () parameter list in ASTContext, as well as the
23
63
// / "(self : T)" parameter lists common to many methods.
24
64
ParameterList *
25
- ParameterList::create (ASTContext &context, ArrayRef<Parameter> params) {
65
+ ParameterList::create (const ASTContext &C, SourceLoc LParenLoc,
66
+ ArrayRef<Parameter> params, SourceLoc RParenLoc) {
67
+ assert (LParenLoc.isValid () == RParenLoc.isValid () &&
68
+ " Either both paren locs are valid or neither are" );
69
+
26
70
auto byteSize = sizeof (ParameterList)+params.size ()*sizeof (Parameter);
27
- auto rawMem = context .Allocate (byteSize, alignof (ParameterList));
71
+ auto rawMem = C .Allocate (byteSize, alignof (ParameterList));
28
72
29
73
// Placement initialize the ParameterList and the Parameter's.
30
74
auto PL = ::new (rawMem) ParameterList (params.size ());
@@ -34,3 +78,121 @@ ParameterList::create(ASTContext &context, ArrayRef<Parameter> params) {
34
78
35
79
return PL;
36
80
}
81
+
82
+ // / Create an implicit 'self' decl for a method in the specified decl context.
83
+ // / If 'static' is true, then this is self for a static method in the type.
84
+ // /
85
+ // / Note that this decl is created, but it is returned with an incorrect
86
+ // / DeclContext that needs to be set correctly. This is automatically handled
87
+ // / when a function is created with this as part of its argument list.
88
+ // /
89
+ ParameterList *ParameterList::createSelf (SourceLoc loc, DeclContext *DC,
90
+ bool isStaticMethod, bool isInOut) {
91
+ auto *param = ParamDecl::createSelf (loc, DC, isStaticMethod, isInOut);
92
+ return create (DC->getASTContext (), Parameter::withoutLoc (param));
93
+ }
94
+
95
+ // / Change the DeclContext of any contained parameters to the specified
96
+ // / DeclContext.
97
+ void ParameterList::setDeclContextOfParamDecls (DeclContext *DC) {
98
+ for (auto &P : getParameters ())
99
+ P.decl ->setDeclContext (DC);
100
+ }
101
+
102
+
103
+
104
+ // / Make a duplicate copy of this parameter list. This allocates copies of
105
+ // / the ParamDecls, so they can be reparented into a new DeclContext.
106
+ ParameterList *ParameterList::clone (const ASTContext &C,
107
+ OptionSet<CloneFlags> options) const {
108
+ // If this list is empty, don't actually bother with a copy.
109
+ if (getNumParameters () == 0 )
110
+ return const_cast <ParameterList*>(this );
111
+
112
+ SmallVector<Parameter, 8 > params (getParameters ().begin (),
113
+ getParameters ().end ());
114
+
115
+ // Remap the ParamDecls inside of the ParameterList.
116
+ for (auto ¶m : params) {
117
+ auto decl = param.decl ;
118
+ auto name = decl->getName ();
119
+ // If the argument isn't named, and we're cloning for an inherited
120
+ // constructor, give the parameter a name so that silgen will produce a
121
+ // value for it.
122
+ if (name.empty () && (options & Inherited))
123
+ name = C.getIdentifier (" argument" );
124
+
125
+ param.decl = new (C) ParamDecl (decl->isLet (),
126
+ decl->getArgumentNameLoc (),
127
+ decl->getArgumentName (),
128
+ decl->getLoc (), name,
129
+ decl->hasType () ? decl->getType () : Type (),
130
+ decl->getDeclContext ());
131
+ if ((options & Implicit) || decl->isImplicit ())
132
+ param.decl ->setImplicit ();
133
+
134
+ // If we're inheriting a default argument, mark it as such.
135
+ if (param.defaultArgumentKind != DefaultArgumentKind::None &&
136
+ (options & Inherited)) {
137
+ param.defaultArgumentKind = DefaultArgumentKind::Inherited;
138
+ param.setDefaultValue (nullptr );
139
+ }
140
+ }
141
+
142
+ return create (C, getParameters ());
143
+ }
144
+
145
+ // / Return a TupleType or ParenType for this parameter list. This returns a
146
+ // / null type if one of the ParamDecls does not have a type set for it yet.
147
+ Type ParameterList::getType (const ASTContext &C) const {
148
+ if (getNumParameters () == 0 )
149
+ return TupleType::getEmpty (C);
150
+
151
+ SmallVector<TupleTypeElt, 8 > argumentInfo;
152
+
153
+ for (auto &P : getParameters ()) {
154
+ if (!P.decl ->hasType ()) return Type ();
155
+
156
+ argumentInfo.push_back ({
157
+ P.decl ->getType (), P.decl ->getArgumentName (), P.defaultArgumentKind ,
158
+ P.isVariadic ()
159
+ });
160
+ }
161
+
162
+ return TupleType::get (argumentInfo, C);
163
+ }
164
+
165
+
166
+ // / Return the full function type for a set of curried parameter lists that
167
+ // / returns the specified result type. This returns a null type if one of the
168
+ // / ParamDecls does not have a type set for it yet.
169
+ // /
170
+ Type ParameterList::getFullType (Type resultType, ArrayRef<ParameterList*> PLL) {
171
+ auto result = resultType;
172
+ auto &C = result->getASTContext ();
173
+
174
+ for (auto PL : reversed (PLL)) {
175
+ auto paramType = PL->getType (C);
176
+ if (!paramType) return Type ();
177
+ result = FunctionType::get (paramType, result);
178
+ }
179
+ return result;
180
+ }
181
+
182
+ // / Return the full source range of this parameter list.
183
+ SourceRange ParameterList::getSourceRange () const {
184
+ // If we have locations for the parens, then they define our range.
185
+ if (LParenLoc.isValid ())
186
+ return { LParenLoc, RParenLoc };
187
+
188
+ // Otherwise, try the first and last parameter.
189
+ if (getNumParameters () != 0 ) {
190
+ auto Start = getParameter (0 ).getStartLoc ();
191
+ auto End = getParameters ().back ().getEndLoc ();
192
+ if (Start.isValid () && End.isValid ())
193
+ return { Start, End };
194
+ }
195
+
196
+ return SourceRange ();
197
+ }
198
+
0 commit comments