@@ -872,19 +872,88 @@ void CompletionLookup::addVarDeclRef(const VarDecl *VD,
872872 Builder.addFlair (CodeCompletionFlairBit::ExpressionSpecific);
873873}
874874
875+ // / Return whether \p param has a non-desirable default value for code
876+ // / completion.
877+ // /
878+ // / 'ClangImporter::Implementation::inferDefaultArgument()' automatically adds
879+ // / default values for some parameters;
880+ // / * NS_OPTIONS enum type with the name '...Options'.
881+ // / * NSDictionary and labeled 'options', 'attributes', or 'userInfo'.
882+ // /
883+ // / But sometimes, this behavior isn't really desirable. This function add a
884+ // / heuristic where if a parameter matches all the following condition, we
885+ // / consider the imported default value is _not_ desirable:
886+ // / * it is the first parameter,
887+ // / * it doesn't have an argument label, and
888+ // / * the imported function base name ends with those words
889+ // / For example, ClangImporter imports:
890+ // /
891+ // / -(void)addAttributes:(NSDictionary *)attrs, options:(NSDictionary *)opts;
892+ // /
893+ // / as:
894+ // /
895+ // / func addAttributes(_ attrs: [AnyHashable:Any] = [:],
896+ // / options opts: [AnyHashable:Any] = [:])
897+ // /
898+ // / In this case, we don't want 'attrs' defaulted because the function name have
899+ // / 'Attribute' in its name so calling 'value.addAttribute()' doesn't make
900+ // / sense, but we _do_ want to keep 'opts' defaulted.
901+ // /
902+ // / Note that:
903+ // /
904+ // / -(void)performWithOptions:(NSDictionary *) opts;
905+ // /
906+ // / This doesn't match the condition because the base name of the function in
907+ // / Swift is 'peform':
908+ // /
909+ // / func perform(options opts: [AnyHashable:Any] = [:])
910+ // /
911+ bool isNonDesirableImportedDefaultArg (const ParamDecl *param) {
912+ auto kind = param->getDefaultArgumentKind ();
913+ if (kind != DefaultArgumentKind::EmptyArray &&
914+ kind != DefaultArgumentKind::EmptyDictionary)
915+ return false ;
916+
917+ if (!param->getArgumentName ().empty ())
918+ return false ;
919+
920+ auto *func = dyn_cast<FuncDecl>(param->getDeclContext ());
921+ if (!func->hasClangNode ())
922+ return false ;
923+ if (func->getParameters ()->front () != param)
924+ return false ;
925+ if (func->getBaseName ().isSpecial ())
926+ return false ;
927+
928+ auto baseName = func->getBaseName ().getIdentifier ().str ();
929+ switch (kind) {
930+ case DefaultArgumentKind::EmptyArray:
931+ return (baseName.endswith (" Options" ));
932+ case DefaultArgumentKind::EmptyDictionary:
933+ return (baseName.endswith (" Options" ) || baseName.endswith (" Attributes" ) ||
934+ baseName.endswith (" UserInfo" ));
935+ default :
936+ llvm_unreachable (" unhandled DefaultArgumentKind" );
937+ }
938+ }
939+
875940bool CompletionLookup::hasInterestingDefaultValue (const ParamDecl *param) {
876941 if (!param)
877942 return false ;
878943
879944 switch (param->getDefaultArgumentKind ()) {
880945 case DefaultArgumentKind::Normal:
881946 case DefaultArgumentKind::NilLiteral:
882- case DefaultArgumentKind::EmptyArray:
883- case DefaultArgumentKind::EmptyDictionary:
884947 case DefaultArgumentKind::StoredProperty:
885948 case DefaultArgumentKind::Inherited:
886949 return true ;
887950
951+ case DefaultArgumentKind::EmptyArray:
952+ case DefaultArgumentKind::EmptyDictionary:
953+ if (isNonDesirableImportedDefaultArg (param))
954+ return false ;
955+ return true ;
956+
888957 case DefaultArgumentKind::None:
889958#define MAGIC_IDENTIFIER (NAME, STRING, SYNTAX_KIND ) \
890959 case DefaultArgumentKind::NAME:
@@ -893,7 +962,7 @@ bool CompletionLookup::hasInterestingDefaultValue(const ParamDecl *param) {
893962 }
894963}
895964
896- bool CompletionLookup::addItemWithoutDefaultArgs (
965+ bool CompletionLookup::shouldAddItemWithoutDefaultArgs (
897966 const AbstractFunctionDecl *func) {
898967 if (!func || !Sink.addCallWithNoDefaultArgs )
899968 return false ;
@@ -923,7 +992,8 @@ bool CompletionLookup::addCallArgumentPatterns(
923992 bool hasDefault = false ;
924993 if (!declParams.empty ()) {
925994 const ParamDecl *PD = declParams[i];
926- hasDefault = PD->isDefaultArgument ();
995+ hasDefault =
996+ PD->isDefaultArgument () && !isNonDesirableImportedDefaultArg (PD);
927997 // Skip default arguments if we're either not including them or they
928998 // aren't interesting
929999 if (hasDefault &&
@@ -1188,7 +1258,7 @@ void CompletionLookup::addFunctionCallPattern(
11881258 if (isImplicitlyCurriedInstanceMethod) {
11891259 addPattern ({AFD->getImplicitSelfDecl ()}, /* includeDefaultArgs=*/ true );
11901260 } else {
1191- if (addItemWithoutDefaultArgs (AFD))
1261+ if (shouldAddItemWithoutDefaultArgs (AFD))
11921262 addPattern (AFD->getParameters ()->getArray (),
11931263 /* includeDefaultArgs=*/ false );
11941264 addPattern (AFD->getParameters ()->getArray (),
@@ -1384,7 +1454,7 @@ void CompletionLookup::addMethodCall(const FuncDecl *FD,
13841454 if (trivialTrailingClosure)
13851455 addMethodImpl (/* includeDefaultArgs=*/ false ,
13861456 /* trivialTrailingClosure=*/ true );
1387- if (addItemWithoutDefaultArgs (FD))
1457+ if (shouldAddItemWithoutDefaultArgs (FD))
13881458 addMethodImpl (/* includeDefaultArgs=*/ false );
13891459 addMethodImpl (/* includeDefaultArgs=*/ true );
13901460 }
@@ -1474,7 +1544,7 @@ void CompletionLookup::addConstructorCall(const ConstructorDecl *CD,
14741544 }
14751545 };
14761546
1477- if (ConstructorType && addItemWithoutDefaultArgs (CD))
1547+ if (ConstructorType && shouldAddItemWithoutDefaultArgs (CD))
14781548 addConstructorImpl (/* includeDefaultArgs=*/ false );
14791549 addConstructorImpl ();
14801550}
0 commit comments