@@ -4074,132 +4074,6 @@ namespace {
40744074 }
40754075 }
40764076
4077- // / Finds the counterpart accessor method for \p MD, if one exists, in the
4078- // / same lexical context.
4079- const clang::ObjCMethodDecl *
4080- findImplicitPropertyAccessor (const clang::ObjCMethodDecl *MD) {
4081- // FIXME: Do we want to infer class properties?
4082- if (!MD->isInstanceMethod ())
4083- return nullptr ;
4084-
4085- // First, collect information about the method we have.
4086- clang::Selector sel = MD->getSelector ();
4087- llvm::SmallString<64 > counterpartName;
4088- auto numArgs = sel.getNumArgs ();
4089- clang::QualType propTy;
4090-
4091- if (numArgs > 1 )
4092- return nullptr ;
4093-
4094- if (numArgs == 0 ) {
4095- clang::IdentifierInfo *getterID = sel.getIdentifierInfoForSlot (0 );
4096- if (!getterID)
4097- return nullptr ;
4098- counterpartName =
4099- clang::SelectorTable::constructSetterName (getterID->getName ());
4100- propTy = MD->getReturnType ();
4101-
4102- } else {
4103- if (!MD->getReturnType ()->isVoidType ())
4104- return nullptr ;
4105-
4106- clang::IdentifierInfo *setterID = sel.getIdentifierInfoForSlot (0 );
4107- if (!setterID || !setterID->getName ().startswith (" set" ))
4108- return nullptr ;
4109- counterpartName = setterID->getName ().substr (3 );
4110- counterpartName[0 ] = tolower (counterpartName[0 ]);
4111- propTy = MD->parameters ().front ()->getType ();
4112- }
4113-
4114- // Next, look for its counterpart.
4115- const clang::ASTContext &clangCtx = Impl.getClangASTContext ();
4116- auto container = cast<clang::ObjCContainerDecl>(MD->getDeclContext ());
4117- for (auto method : make_range (container->instmeth_begin (),
4118- container->instmeth_end ())) {
4119- // Condition 1: it must be a getter if we have a setter, and vice versa.
4120- clang::Selector nextSel = method->getSelector ();
4121- if (nextSel.getNumArgs () != (1 - numArgs))
4122- continue ;
4123-
4124- // Condition 2: it must have the name we expect.
4125- clang::IdentifierInfo *nextID = nextSel.getIdentifierInfoForSlot (0 );
4126- if (!nextID)
4127- continue ;
4128- if (nextID->getName () != counterpartName)
4129- continue ;
4130-
4131- // Condition 3: it must have the right type signature.
4132- if (numArgs == 0 ) {
4133- if (!method->getReturnType ()->isVoidType ())
4134- continue ;
4135- clang::QualType paramTy = method->parameters ().front ()->getType ();
4136- if (!clangCtx.hasSameUnqualifiedType (propTy, paramTy))
4137- continue ;
4138- } else {
4139- clang::QualType returnTy = method->getReturnType ();
4140- if (!clangCtx.hasSameUnqualifiedType (propTy, returnTy))
4141- continue ;
4142- }
4143-
4144- return method;
4145- }
4146-
4147- return nullptr ;
4148- }
4149-
4150- // / Creates a computed property VarDecl from the given getter and
4151- // / optional setter.
4152- Decl *makeImplicitPropertyDecl (Decl *opaqueGetter,
4153- Decl *opaqueSetter,
4154- DeclContext *dc) {
4155- auto getter = cast<FuncDecl>(opaqueGetter);
4156- auto setter = cast_or_null<FuncDecl>(opaqueSetter);
4157- assert (!setter || setter->getResultType ()->isVoid ());
4158-
4159- auto name = getter->getName ();
4160-
4161- // Check whether there is a function with the same name as this
4162- // property. If so, suppress the property; the user will have to use
4163- // the methods directly, to avoid ambiguities.
4164- auto containerTy = dc->getDeclaredTypeInContext ();
4165- VarDecl *overridden = nullptr ;
4166- SmallVector<ValueDecl *, 2 > lookup;
4167- dc->lookupQualified (containerTy, name,
4168- NL_QualifiedDefault | NL_KnownNoDependency,
4169- nullptr , lookup);
4170- for (auto result : lookup) {
4171- if (isa<FuncDecl>(result))
4172- return nullptr ;
4173-
4174- if (auto var = dyn_cast<VarDecl>(result))
4175- overridden = var;
4176- }
4177-
4178- // Re-import the type as a property type.
4179- auto clangGetter = cast<clang::ObjCMethodDecl>(getter->getClangDecl ());
4180- auto type = Impl.importType (clangGetter->getReturnType (),
4181- ImportTypeKind::Property,
4182- isInSystemModule (dc),
4183- /* isFullyBridgeable*/ true );
4184- if (!type)
4185- return nullptr ;
4186-
4187- auto result = Impl.createDeclWithClangNode <VarDecl>(clangGetter,
4188- /* static*/ false , /* IsLet*/ false ,
4189- Impl.importSourceLoc (clangGetter->getLocation ()),
4190- name, type, dc);
4191-
4192- // Turn this into a computed property.
4193- // FIXME: Fake locations for '{' and '}'?
4194- result->makeComputed (SourceLoc (), getter, setter, nullptr , SourceLoc ());
4195- addObjCAttribute (result, None);
4196-
4197- if (overridden)
4198- result->setOverriddenDecl (overridden);
4199-
4200- return result;
4201- }
4202-
42034077 static bool
42044078 isPotentiallyConflictingSetter (const clang::ObjCProtocolDecl *proto,
42054079 const clang::ObjCMethodDecl *method) {
@@ -4295,28 +4169,6 @@ namespace {
42954169 // if we've failed to import a new property.
42964170 if (cast<FuncDecl>(member)->isAccessor ())
42974171 continue ;
4298- } else if (Impl.InferImplicitProperties ) {
4299- // Try to infer properties for matched getter/setter pairs.
4300- // Be careful to only do this once per matched pair.
4301- if (auto counterpart = findImplicitPropertyAccessor (objcMethod)) {
4302- if (auto counterpartImported = Impl.importDecl (counterpart)) {
4303- if (objcMethod->getReturnType ()->isVoidType ()) {
4304- if (auto prop = makeImplicitPropertyDecl (counterpartImported,
4305- member,
4306- swiftContext)) {
4307- members.push_back (prop);
4308- } else {
4309- // If we fail to import the implicit property, fall back to
4310- // adding the accessors as members. We have to add BOTH
4311- // accessors here because we already skipped over the other
4312- // one.
4313- members.push_back (member);
4314- members.push_back (counterpartImported);
4315- }
4316- }
4317- continue ;
4318- }
4319- }
43204172 } else if (auto *proto = dyn_cast<clang::ObjCProtocolDecl>(decl)) {
43214173 if (isPotentiallyConflictingSetter (proto, objcMethod))
43224174 continue ;
0 commit comments