Skip to content

Commit 1bc3a80

Browse files
coadozoontek
authored andcommitted
Normalize Objective-C nullability annotations (facebook#55898)
Summary: Pull Request resolved: facebook#55898 Normalize Objective-C nullability annotations in the cxx-api parser to ensure consistent output in API snapshots. Objective-C has three different forms of nullability annotations that are semantically equivalent: - `nonnull`/`nullable` (context-sensitive keywords) - `_Nonnull`/`_Nullable` (type qualifiers) - `__nonnull`/`__nullable` (legacy Apple macros) This diff normalizes all forms to `_Nonnull`/`_Nullable` for consistency. **Examples:** - `nonnull NSString*` → `_Nonnull NSString*` - `NSString* __nonnull` → `NSString* _Nonnull` - `nullable id` → `_Nullable id` - `id __nullable` → `id _Nullable` - `NSString* _Nonnull` → `NSString* _Nonnull` (unchanged) Added a test case to verify the normalization works correctly. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D95195669 fbshipit-source-id: ca2afd14b3c8bf7e62864daf9c3848f5d713898e
1 parent 12da371 commit 1bc3a80

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

scripts/cxx-api/parser/utils/text_resolution.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,30 @@ def normalize_angle_brackets(text: str) -> str:
9090
return text
9191

9292

93+
def normalize_nullability(text: str) -> str:
94+
"""Normalize Objective-C nullability annotations to a consistent form.
95+
96+
There are three forms of nullability annotations in Objective-C:
97+
- nonnull/nullable (context-sensitive keywords, typically used as prefix)
98+
- _Nonnull/_Nullable (type qualifiers, can appear after the type)
99+
- __nonnull/__nullable (legacy Apple macros, deprecated but still used)
100+
101+
This function normalizes all forms to _Nonnull/_Nullable, which is the
102+
most flexible form that can be used in any position.
103+
"""
104+
# Normalize __nonnull -> _Nonnull (must come before nonnull)
105+
text = re.sub(r"\b__nonnull\b", "_Nonnull", text)
106+
# Normalize nonnull -> _Nonnull (negative lookbehind to avoid _Nonnull)
107+
text = re.sub(r"(?<!_)\bnonnull\b", "_Nonnull", text)
108+
109+
# Normalize __nullable -> _Nullable (must come before nullable)
110+
text = re.sub(r"\b__nullable\b", "_Nullable", text)
111+
# Normalize nullable -> _Nullable (negative lookbehind to avoid _Nullable)
112+
text = re.sub(r"(?<!_)\bnullable\b", "_Nullable", text)
113+
114+
return text
115+
116+
93117
def normalize_pointer_spacing(text: str) -> str:
94118
"""Normalize spacing around pointer (*) and reference (&, &&) symbols.
95119
@@ -179,7 +203,9 @@ def resolve_linked_text_name(
179203
name = name[1:-1].strip()
180204

181205
return (
182-
normalize_pointer_spacing(normalize_angle_brackets(name.strip())),
206+
normalize_nullability(
207+
normalize_pointer_spacing(normalize_angle_brackets(name.strip()))
208+
),
183209
initialier_type,
184210
)
185211

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
interface NullabilityTest : public NSObject {
2+
public @property (assign) NSString* nonnullProperty;
3+
public @property (assign) NSString* nullableProperty;
4+
public virtual NSString* _Nonnull legacyNonnullMethod();
5+
public virtual NSString* _Nonnull modernNonnullMethod();
6+
public virtual NSString* _Nullable legacyNullableMethod();
7+
public virtual NSString* _Nullable modernNullableMethod();
8+
public virtual _Nonnull NSString* nonnullMethod();
9+
public virtual _Nullable NSString* nullableMethod();
10+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
@interface NullabilityTest : NSObject
9+
10+
// Different nullability annotation styles that should be normalized
11+
- (nonnull NSString *)nonnullMethod;
12+
- (nullable NSString *)nullableMethod;
13+
- (NSString *__nonnull)legacyNonnullMethod;
14+
- (NSString *__nullable)legacyNullableMethod;
15+
- (NSString *_Nonnull)modernNonnullMethod;
16+
- (NSString *_Nullable)modernNullableMethod;
17+
18+
@property (nonatomic, nonnull) NSString *nonnullProperty;
19+
@property (nonatomic, nullable) NSString *nullableProperty;
20+
21+
@end

0 commit comments

Comments
 (0)