Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ios] making objective-C smart pointers support ARC #47612

Merged
merged 5 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ group("unittests") {
"//flutter/display_list:display_list_unittests",
"//flutter/flow:flow_unittests",
"//flutter/fml:fml_unittests",
"//flutter/fml:fml_unittests_arc",
"//flutter/lib/ui:ui_unittests",
"//flutter/runtime:dart_plugin_registrant_unittests",
"//flutter/runtime:no_dart_plugin_registrant_unittests",
Expand Down
2 changes: 2 additions & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@
../../../flutter/fml/message_loop_unittests.cc
../../../flutter/fml/paths_unittests.cc
../../../flutter/fml/platform/darwin/cf_utils_unittests.mm
../../../flutter/fml/platform/darwin/scoped_nsobject_unittests.mm
../../../flutter/fml/platform/darwin/scoped_nsobject_unittests_arc.mm
../../../flutter/fml/platform/darwin/string_range_sanitization_unittests.mm
../../../flutter/fml/platform/win/file_win_unittests.cc
../../../flutter/fml/platform/win/wstring_conversion_unittests.cc
Expand Down
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2795,6 +2795,8 @@ ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.cc + ../.
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsobject.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsobject.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_policy.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_typeref.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/string_range_sanitization.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/string_range_sanitization.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/fuchsia/message_loop_fuchsia.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -5578,6 +5580,8 @@ FILE: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.cc
FILE: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.h
FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.h
FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.mm
FILE: ../../../flutter/fml/platform/darwin/scoped_policy.h
FILE: ../../../flutter/fml/platform/darwin/scoped_typeref.h
FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization.h
FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization.mm
FILE: ../../../flutter/fml/platform/fuchsia/message_loop_fuchsia.cc
Expand Down
20 changes: 20 additions & 0 deletions fml/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ source_set("fml") {
"platform/darwin/scoped_nsautorelease_pool.h",
"platform/darwin/scoped_nsobject.h",
"platform/darwin/scoped_nsobject.mm",
"platform/darwin/scoped_policy.h",
"platform/darwin/scoped_typeref.h",
"platform/darwin/string_range_sanitization.h",
"platform/darwin/string_range_sanitization.mm",
]
Expand Down Expand Up @@ -366,6 +368,10 @@ if (enable_unittests) {
]
}

if (is_mac || is_ios) {
sources += [ "platform/darwin/scoped_nsobject_unittests.mm" ]
}

if (is_win) {
sources += [
"platform/win/file_win_unittests.cc",
Expand All @@ -388,4 +394,18 @@ if (enable_unittests) {
[ "${fuchsia_sdk_path}/arch/${target_cpu}/sysroot/lib/libzircon.so" ]
}
}

executable("fml_unittests_arc") {
testonly = true
if (is_mac || is_ios) {
cflags_objcc = flutter_cflags_objc_arc
sources = [ "platform/darwin/scoped_nsobject_unittests_arc.mm" ]
}

deps = [
":fml_fixtures",
"//flutter/fml",
"//flutter/testing",
]
}
}
10 changes: 10 additions & 0 deletions fml/compiler_specific.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@
#define FML_ALLOW_UNUSED_TYPE
#endif

// Annotate a function indicating the caller must examine the return value.
// Use like:
// int foo() WARN_UNUSED_RESULT;
#undef WARN_UNUSED_RESULT
#if defined(COMPILER_GCC) || defined(__clang__)
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif

#endif // FLUTTER_FML_COMPILER_SPECIFIC_H_
92 changes: 23 additions & 69 deletions fml/platform/darwin/scoped_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,86 +8,40 @@
#include <Block.h>

#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/platform/darwin/scoped_typeref.h"

namespace fml {

// ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and
// Block_release() instead of CFRetain() and CFRelease().
#if defined(__has_feature) && __has_feature(objc_arc)
#define BASE_MAC_BRIDGE_CAST(TYPE, VALUE) (__bridge TYPE)(VALUE)
#else
#define BASE_MAC_BRIDGE_CAST(TYPE, VALUE) VALUE
#endif

enum class OwnershipPolicy {
// The scoped object takes ownership of an object by taking over an existing
// ownership claim.
kAssume,
namespace fml {

// The scoped object will retain the object and any initial ownership is
// not changed.
kRetain,
};
namespace internal {

template <typename B>
class ScopedBlock {
public:
explicit ScopedBlock(B block = nullptr,
OwnershipPolicy policy = OwnershipPolicy::kAssume)
: block_(block) {
if (block_ && policy == OwnershipPolicy::kRetain) {
block_ = Block_copy(block);
}
struct ScopedBlockTraits {
static B InvalidValue() { return nullptr; }
static B Retain(B block) {
return BASE_MAC_BRIDGE_CAST(
B, Block_copy(BASE_MAC_BRIDGE_CAST(const void*, block)));
}

ScopedBlock(const ScopedBlock<B>& that) : block_(that.block_) {
if (block_) {
block_ = Block_copy(block_);
}
}

~ScopedBlock() {
if (block_) {
Block_release(block_);
}
}

ScopedBlock& operator=(const ScopedBlock<B>& that) {
reset(that.get(), OwnershipPolicy::kRetain);
return *this;
}

void reset(B block = nullptr,
OwnershipPolicy policy = OwnershipPolicy::kAssume) {
if (block && policy == OwnershipPolicy::kRetain) {
block = Block_copy(block);
}
if (block_) {
Block_release(block_);
}
block_ = block;
static void Release(B block) {
Block_release(BASE_MAC_BRIDGE_CAST(const void*, block));
}
};

bool operator==(B that) const { return block_ == that; }

bool operator!=(B that) const { return block_ != that; }

// NOLINTNEXTLINE(google-explicit-constructor)
operator B() const { return block_; }

B get() const { return block_; }

void swap(ScopedBlock& that) {
B temp = that.block_;
that.block_ = block_;
block_ = temp;
}
} // namespace internal

[[nodiscard]] B release() {
B temp = block_;
block_ = nullptr;
return temp;
}
// ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and
// Block_release() instead of CFRetain() and CFRelease().

private:
B block_;
};
template <typename B>
using ScopedBlock = ScopedTypeRef<B, internal::ScopedBlockTraits<B>>;

} // namespace fml

#undef BASE_MAC_BRIDGE_CAST

#endif // FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_
Loading