@@ -218,6 +218,7 @@ void CodeCompletionString::print(raw_ostream &OS) const {
218218 case ChunkKind::DeclResultTypeClauseBegin:
219219 case ChunkKind::ParameterDeclTypeBegin:
220220 case ChunkKind::AttributeAndModifierListBegin:
221+ case ChunkKind::CallArgumentDefaultBegin:
221222 assert (I->getNestingLevel () == PrevNestingLevel + 1 );
222223 closeTags.emplace_back (" " );
223224 break ;
@@ -293,6 +294,7 @@ void CodeCompletionString::dump() const {
293294 CASE (DeclAttrParamColon)
294295 CASE (CallArgumentType)
295296 CASE (CallArgumentTypeBegin)
297+ CASE (CallArgumentDefaultBegin)
296298 CASE (TypeIdSystem)
297299 CASE (TypeIdUser)
298300 CASE (CallArgumentClosureType)
@@ -910,8 +912,8 @@ class CodeCompletionStringPrinter : public ASTPrinter {
910912
911913void CodeCompletionResultBuilder::addCallArgument (
912914 Identifier Name, Identifier LocalName, Type Ty, Type ContextTy,
913- bool IsVarArg, bool IsInOut, bool IsIUO, bool isAutoClosure ,
914- bool useUnderscoreLabel , bool isLabeledTrailingClosure ) {
915+ bool IsVarArg, bool IsInOut, bool IsIUO, bool IsAutoClosure ,
916+ bool UseUnderscoreLabel , bool IsLabeledTrailingClosure, bool HasDefault ) {
915917 ++CurrentNestingLevel;
916918 using ChunkKind = CodeCompletionString::Chunk::ChunkKind;
917919
@@ -952,7 +954,7 @@ void CodeCompletionResultBuilder::addCallArgument(
952954 escapeKeyword (Name.str (), false , EscapedKeyword));
953955 addChunkWithTextNoCopy (
954956 CodeCompletionString::Chunk::ChunkKind::CallArgumentColon, " : " );
955- } else if (useUnderscoreLabel ) {
957+ } else if (UseUnderscoreLabel ) {
956958 addChunkWithTextNoCopy (
957959 CodeCompletionString::Chunk::ChunkKind::CallArgumentName, " _" );
958960 addChunkWithTextNoCopy (
@@ -978,7 +980,7 @@ void CodeCompletionResultBuilder::addCallArgument(
978980 // If the parameter is of the type @autoclosure ()->output, then the
979981 // code completion should show the parameter of the output type
980982 // instead of the function type ()->output.
981- if (isAutoClosure ) {
983+ if (IsAutoClosure ) {
982984 // 'Ty' may be ErrorType.
983985 if (auto funcTy = Ty->getAs <FunctionType>())
984986 Ty = funcTy->getResult ();
@@ -1004,6 +1006,12 @@ void CodeCompletionResultBuilder::addCallArgument(
10041006 addChunkWithText (ChunkKind::CallArgumentType, TypeName);
10051007 }
10061008
1009+ if (HasDefault) {
1010+ withNestedGroup (ChunkKind::CallArgumentDefaultBegin, []() {
1011+ // Possibly add the actual value in the future
1012+ });
1013+ }
1014+
10071015 // Look through optional types and type aliases to find out if we have
10081016 // function type.
10091017 Ty = Ty->lookThroughAllOptionalTypes ();
@@ -1020,7 +1028,7 @@ void CodeCompletionResultBuilder::addCallArgument(
10201028 if (ContextTy)
10211029 PO.setBaseType (ContextTy);
10221030
1023- if (isLabeledTrailingClosure ) {
1031+ if (IsLabeledTrailingClosure ) {
10241032 // Expand the closure body.
10251033 SmallString<32 > buffer;
10261034 llvm::raw_svector_ostream OS (buffer);
@@ -1062,6 +1070,7 @@ void CodeCompletionResultBuilder::addCallArgument(
10621070
10631071 if (IsVarArg)
10641072 addEllipsis ();
1073+
10651074 --CurrentNestingLevel;
10661075}
10671076
@@ -1414,6 +1423,7 @@ Optional<unsigned> CodeCompletionString::getFirstTextChunkIndex(
14141423 case ChunkKind::CallArgumentColon:
14151424 case ChunkKind::CallArgumentTypeBegin:
14161425 case ChunkKind::CallArgumentType:
1426+ case ChunkKind::CallArgumentDefaultBegin:
14171427 case ChunkKind::CallArgumentClosureType:
14181428 case ChunkKind::CallArgumentClosureExpr:
14191429 case ChunkKind::ParameterDeclTypeBegin:
@@ -2746,25 +2756,32 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
27462756 Builder.addFlair (CodeCompletionFlairBit::ExpressionSpecific);
27472757 }
27482758
2749- static bool hasInterestingDefaultValues (const AbstractFunctionDecl *func) {
2750- if (!func) return false ;
2759+ static bool hasInterestingDefaultValue (const ParamDecl *param) {
2760+ if (!param)
2761+ return false ;
27512762
2752- for (auto param : *func->getParameters ()) {
2753- switch (param->getDefaultArgumentKind ()) {
2754- case DefaultArgumentKind::Normal:
2755- case DefaultArgumentKind::NilLiteral:
2756- case DefaultArgumentKind::EmptyArray:
2757- case DefaultArgumentKind::EmptyDictionary:
2758- case DefaultArgumentKind::StoredProperty:
2759- case DefaultArgumentKind::Inherited: // FIXME: include this?
2760- return true ;
2763+ switch (param->getDefaultArgumentKind ()) {
2764+ case DefaultArgumentKind::Normal:
2765+ case DefaultArgumentKind::NilLiteral:
2766+ case DefaultArgumentKind::EmptyArray:
2767+ case DefaultArgumentKind::EmptyDictionary:
2768+ case DefaultArgumentKind::StoredProperty:
2769+ case DefaultArgumentKind::Inherited:
2770+ return true ;
27612771
2762- case DefaultArgumentKind::None:
2772+ case DefaultArgumentKind::None:
27632773#define MAGIC_IDENTIFIER (NAME, STRING, SYNTAX_KIND ) \
2764- case DefaultArgumentKind::NAME:
2774+ case DefaultArgumentKind::NAME:
27652775#include " swift/AST/MagicIdentifierKinds.def"
2766- break ;
2767- }
2776+ return false ;
2777+ }
2778+ }
2779+
2780+ static bool hasInterestingDefaultValues (const AbstractFunctionDecl *func) {
2781+ if (!func) return false ;
2782+ for (auto param : *func->getParameters ()) {
2783+ if (hasInterestingDefaultValue (param))
2784+ return true ;
27682785 }
27692786 return false ;
27702787 }
@@ -2780,52 +2797,27 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
27802797 assert (declParams.empty () || typeParams.size () == declParams.size ());
27812798
27822799 bool modifiedBuilder = false ;
2783-
2784- // Determine whether we should skip this argument because it is defaulted.
2785- auto shouldSkipArg = [&](const ParamDecl *PD) -> bool {
2786- switch (PD->getDefaultArgumentKind ()) {
2787- case DefaultArgumentKind::None:
2788- return false ;
2789-
2790- case DefaultArgumentKind::Normal:
2791- case DefaultArgumentKind::StoredProperty:
2792- case DefaultArgumentKind::Inherited:
2793- case DefaultArgumentKind::NilLiteral:
2794- case DefaultArgumentKind::EmptyArray:
2795- case DefaultArgumentKind::EmptyDictionary:
2796- return !includeDefaultArgs;
2797-
2798- #define MAGIC_IDENTIFIER (NAME, STRING, SYNTAX_KIND ) \
2799- case DefaultArgumentKind::NAME:
2800- #include " swift/AST/MagicIdentifierKinds.def"
2801- // Skip parameters that are defaulted to source location or other
2802- // caller context information. Users typically don't want to specify
2803- // these parameters.
2804- return true ;
2805- }
2806-
2807- llvm_unreachable (" Unhandled DefaultArgumentKind in switch." );
2808- };
2809-
2810- bool NeedComma = false ;
2800+ bool needComma = false ;
28112801 // Iterate over each parameter.
28122802 for (unsigned i = 0 ; i != typeParams.size (); ++i) {
28132803 auto &typeParam = typeParams[i];
28142804
2815- Identifier argName;
2805+ Identifier argName = typeParam. getLabel () ;
28162806 Identifier bodyName;
28172807 bool isIUO = false ;
2818-
2808+ bool hasDefault = false ;
28192809 if (!declParams.empty ()) {
2820- auto *PD = declParams[i];
2821- if (shouldSkipArg (PD))
2810+ const ParamDecl *PD = declParams[i];
2811+ hasDefault = PD->isDefaultArgument ();
2812+ // Skip default arguments if we're either not including them or they
2813+ // aren't interesting
2814+ if (hasDefault &&
2815+ (!includeDefaultArgs || !hasInterestingDefaultValue (PD)))
28222816 continue ;
2817+
28232818 argName = PD->getArgumentName ();
28242819 bodyName = PD->getParameterName ();
28252820 isIUO = PD->isImplicitlyUnwrappedOptional ();
2826- } else {
2827- isIUO = false ;
2828- argName = typeParam.getLabel ();
28292821 }
28302822
28312823 bool isVariadic = typeParam.isVariadic ();
@@ -2835,21 +2827,22 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
28352827 if (isVariadic)
28362828 paramTy = ParamDecl::getVarargBaseTy (paramTy);
28372829
2838- if (NeedComma)
2839- Builder.addComma ();
28402830 Type contextTy;
28412831 if (auto typeContext = CurrDeclContext->getInnermostTypeContext ())
28422832 contextTy = typeContext->getDeclaredTypeInContext ();
28432833
2834+ if (needComma)
2835+ Builder.addComma ();
28442836 Builder.addCallArgument (argName, bodyName,
28452837 eraseArchetypes (paramTy, genericSig), contextTy,
28462838 isVariadic, isInOut, isIUO, isAutoclosure,
2847- /* useUnderscoreLabel =*/ false ,
2848- /* isLabeledTrailingClosure =*/ false );
2839+ /* UseUnderscoreLabel =*/ false ,
2840+ /* IsLabeledTrailingClosure =*/ false , hasDefault );
28492841
28502842 modifiedBuilder = true ;
2851- NeedComma = true ;
2843+ needComma = true ;
28522844 }
2845+
28532846 return modifiedBuilder;
28542847 }
28552848
@@ -4732,9 +4725,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
47324725 Builder.addCallArgument (Arg->getLabel (), Identifier (),
47334726 Arg->getPlainType (), ContextType,
47344727 Arg->isVariadic (), Arg->isInOut (),
4735- /* isIUO =*/ false , Arg->isAutoClosure (),
4736- /* useUnderscoreLabel =*/ true ,
4737- isLabeledTrailingClosure);
4728+ /* IsIUO =*/ false , Arg->isAutoClosure (),
4729+ /* UseUnderscoreLabel =*/ true ,
4730+ isLabeledTrailingClosure, /* HasDefault= */ false );
47384731 Builder.addFlair (CodeCompletionFlairBit::ArgumentLabels);
47394732 auto Ty = Arg->getPlainType ();
47404733 if (Arg->isInOut ()) {
0 commit comments