Skip to content

Commit 2889d55

Browse files
committed
Add labeled and defaulted parameters to ASTSynthesis.
1 parent 0a282c0 commit 2889d55

File tree

1 file changed

+94
-5
lines changed

1 file changed

+94
-5
lines changed

include/swift/AST/ASTSynthesis.h

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/Types.h"
1717
#include "swift/AST/ASTContext.h"
1818
#include "swift/AST/Decl.h"
19+
#include "swift/AST/Expr.h"
1920
#include "swift/AST/GenericParamList.h"
2021
#include "swift/AST/ParameterList.h"
2122

@@ -171,7 +172,7 @@ Type synthesizeType(SynthesisContext &SC,
171172
}
172173

173174
MetatypeRepresentation
174-
synthesizeMetatypeRepresentation(RepresentationSynthesizer rep) {
175+
inline synthesizeMetatypeRepresentation(RepresentationSynthesizer rep) {
175176
switch (rep) {
176177
case _thin: return MetatypeRepresentation::Thin;
177178
case _thick: return MetatypeRepresentation::Thick;
@@ -299,10 +300,12 @@ Type synthesizeType(SynthesisContext &SC,
299300

300301
/// Synthesize parameter declarations.
301302
template <class S>
302-
ParamDecl *synthesizeParamDecl(SynthesisContext &SC, const S &s) {
303+
ParamDecl *synthesizeParamDecl(SynthesisContext &SC, const S &s,
304+
const char *label = nullptr) {
305+
auto argLabelIdent = (label ? SC.Context.getIdentifier(label) : Identifier());
303306
auto type = synthesizeType(SC, s);
304307
auto PD = new (SC.Context) ParamDecl(SourceLoc(), SourceLoc(),
305-
Identifier(), SourceLoc(),
308+
argLabelIdent, SourceLoc(),
306309
Identifier(), SC.DC);
307310
PD->setSpecifier(ParamSpecifier::Default);
308311
PD->setInterfaceType(type);
@@ -330,8 +333,9 @@ constexpr SpecifiedParamSynthesizer<G> _inout(G sub) {
330333
}
331334
template <class S>
332335
ParamDecl *synthesizeParamDecl(SynthesisContext &SC,
333-
const SpecifiedParamSynthesizer<S> &s) {
334-
auto param = synthesizeParamDecl(SC, s.sub);
336+
const SpecifiedParamSynthesizer<S> &s,
337+
const char *label = nullptr) {
338+
auto param = synthesizeParamDecl(SC, s.sub, label);
335339
param->setSpecifier(s.specifier);
336340
return param;
337341
}
@@ -345,6 +349,61 @@ FunctionType::Param synthesizeParamType(SynthesisContext &SC,
345349
return param.withFlags(flags);
346350
}
347351

352+
template <class S>
353+
void synthesizeDefaultArgument(SynthesisContext &SC, const S &s,
354+
ParamDecl *param) {
355+
synthesizeDefaultArgumentFromExpr(SC, s, param);
356+
}
357+
template <class S>
358+
void synthesizeDefaultArgumentFromExpr(SynthesisContext &SC, const S &s,
359+
ParamDecl *param) {
360+
// FIXME: this works except that we tend to crash in diagnostics trying
361+
// to render the default argument if you mess up the call.
362+
auto expr = synthesizeExpr(SC, s);
363+
param->setDefaultArgumentKind(DefaultArgumentKind::Normal);
364+
param->setDefaultExpr(expr, /*type checked*/ false);
365+
}
366+
367+
/// Default arguments.
368+
template <class S, class A>
369+
struct DefaultedSynthesizer { S sub; A arg; };
370+
template <class S, class A>
371+
constexpr DefaultedSynthesizer<S, A> _defaulted(S sub, A arg) {
372+
return {sub, arg};
373+
}
374+
template <class S, class A>
375+
ParamDecl *synthesizeParamDecl(SynthesisContext &SC,
376+
const DefaultedSynthesizer<S, A> &s,
377+
const char *label = nullptr) {
378+
auto param = synthesizeParamDecl(SC, s.sub, label);
379+
synthesizeDefaultArgument(SC, s.arg, param);
380+
return param;
381+
}
382+
template <class S, class A>
383+
FunctionType::Param synthesizeParamType(SynthesisContext &SC,
384+
const DefaultedSynthesizer<S, A> &s) {
385+
return synthesizeParamType(s.sub);
386+
}
387+
388+
/// Labels.
389+
template <class S>
390+
struct LabelSynthesizer { const char *label; S sub; };
391+
template <class S>
392+
constexpr LabelSynthesizer<S> _label(const char *label, S sub) {
393+
return {label, sub};
394+
}
395+
template <class S>
396+
ParamDecl *synthesizeParamDecl(SynthesisContext &SC,
397+
const LabelSynthesizer<S> &s) {
398+
return synthesizeParamDecl(SC, s.sub, s.label);
399+
}
400+
template <class S>
401+
FunctionType::Param synthesizeParamType(SynthesisContext &SC,
402+
const LabelSynthesizer<S> &s) {
403+
auto label = SC.Context.getIdentifier(s.label);
404+
return synthesizeParamType(SC, s.sub).withLabel(label);
405+
}
406+
348407
/// Synthesize a parameter list.
349408
template <class... Params>
350409
struct ParameterListSynthesizer {
@@ -468,6 +527,36 @@ Type synthesizeType(SynthesisContext &SC, const OptionalSynthesizer<S> &s) {
468527
return OptionalType::get(synthesizeType(SC, s.sub));
469528
}
470529

530+
/// Expressions.
531+
enum SingletonExprSynthesizer {
532+
_nil
533+
};
534+
inline Expr *synthesizeExpr(SynthesisContext &SC, SingletonExprSynthesizer s) {
535+
switch (s) {
536+
case _nil:
537+
return new (SC.Context) NilLiteralExpr(SourceLoc(), /*implicit*/true);
538+
}
539+
llvm_unreachable("bad singleton kind");
540+
}
541+
inline void synthesizeDefaultArgument(SynthesisContext &SC,
542+
SingletonExprSynthesizer s,
543+
ParamDecl *param) {
544+
switch (s) {
545+
case _nil: {
546+
auto expr = synthesizeExpr(SC, s);
547+
param->setDefaultArgumentKind(DefaultArgumentKind::NilLiteral);
548+
param->setDefaultExpr(expr, /*type checked*/ false);
549+
return;
550+
}
551+
552+
/*
553+
default:
554+
synthesizeDefaultArgumentFromExpr(SC, s, param);
555+
return;
556+
*/
557+
}
558+
}
559+
471560
} // end namespace swift
472561

473562
#endif

0 commit comments

Comments
 (0)