Skip to content

Commit ae18b38

Browse files
committed
fix(runtime): Add forgotten check for protocol availability
* Respect availability attribute in protocols * Fix typo Protcols -> Protocols * Add tests refs #1084
1 parent 8a05837 commit ae18b38

File tree

6 files changed

+59
-10
lines changed

6 files changed

+59
-10
lines changed

src/NativeScript/Metadata/Metadata.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -865,14 +865,14 @@ struct BaseClassMeta : Meta {
865865
return this->initializers(initializers);
866866
}
867867

868-
std::vector<const MethodMeta*> initializersWithProtcols() const {
868+
std::vector<const MethodMeta*> initializersWithProtocols() const {
869869
std::vector<const MethodMeta*> initializers;
870-
return this->initializersWithProtcols(initializers);
870+
return this->initializersWithProtocols(initializers);
871871
}
872872

873873
std::vector<const MethodMeta*> initializers(std::vector<const MethodMeta*>& container) const;
874874

875-
std::vector<const MethodMeta*> initializersWithProtcols(std::vector<const MethodMeta*>& container) const;
875+
std::vector<const MethodMeta*> initializersWithProtocols(std::vector<const MethodMeta*>& container) const;
876876
};
877877

878878
struct ProtocolMeta : BaseClassMeta {

src/NativeScript/Metadata/Metadata.mm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ void collectInheritanceChainMembers(const char* identifier, size_t length, Membe
198198
return result;
199199
}
200200

201-
// search in protcols
201+
// search in protocols
202202
if (includeProtocols) {
203203
for (Array<String>::iterator it = protocols->begin(); it != protocols->end(); ++it) {
204-
const ProtocolMeta* protocolMeta = static_cast<const ProtocolMeta*>(MetaFile::instance()->globalTable()->findMeta((*it).valuePtr()));
204+
const ProtocolMeta* protocolMeta = static_cast<const ProtocolMeta*>(MetaFile::instance()->globalTable()->findMeta((*it).valuePtr(), onlyIfAvailable));
205205
if (protocolMeta != nullptr) {
206206
const std::vector<const MemberMeta*> members = protocolMeta->members(identifier, length, type, onlyIfAvailable);
207207
if (members.size() > 0) {
@@ -250,12 +250,12 @@ void collectInheritanceChainMembers(const char* identifier, size_t length, Membe
250250
return container;
251251
}
252252

253-
vector<const MethodMeta*> BaseClassMeta::initializersWithProtcols(vector<const MethodMeta*>& container) const {
253+
vector<const MethodMeta*> BaseClassMeta::initializersWithProtocols(vector<const MethodMeta*>& container) const {
254254
this->initializers(container);
255255
for (Array<String>::iterator it = this->protocols->begin(); it != this->protocols->end(); it++) {
256256
const ProtocolMeta* protocolMeta = static_cast<const ProtocolMeta*>(MetaFile::instance()->globalTable()->findMeta((*it).valuePtr(), false));
257257
if (protocolMeta != nullptr)
258-
protocolMeta->initializersWithProtcols(container);
258+
protocolMeta->initializersWithProtocols(container);
259259
}
260260
return container;
261261
}

src/NativeScript/ObjC/Constructor/ObjCConstructorBase.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static void writeAdapter(ExecState* execState, const JSValue& value, void* buffe
169169
const Metadata::InterfaceMeta* metadata = this->metadata();
170170

171171
do {
172-
std::vector<const Metadata::MethodMeta*> initializers = metadata->initializersWithProtcols();
172+
std::vector<const Metadata::MethodMeta*> initializers = metadata->initializersWithProtocols();
173173
for (const Metadata::MethodMeta* method : initializers) {
174174
if (method->isAvailableInClass(this->klass(), /*isStatic*/ false)) {
175175
auto constructorWrapper = ObjCConstructorWrapper::create(vm, globalObject, globalObject->objCConstructorWrapperStructure(), this->_klass, method);
@@ -216,7 +216,7 @@ static JSValue getInitializerForSwiftStyleConstruction(ExecState* execState, Obj
216216
std::vector<const Metadata::MethodMeta*> initializers;
217217
initializers.reserve(16);
218218
do {
219-
interface->initializersWithProtcols(initializers);
219+
interface->initializersWithProtocols(initializers);
220220
for (const Metadata::MethodMeta* method : initializers) {
221221
if (strcmp(method->constructorTokens(), ctorMetadata.data()) == 0) {
222222
result = method;

tests/TestFixtures/Api/TNSVersions.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,23 @@ generateMinors(15);
7575
// max availability version that can be currently represented in the binary metadata is 31.7 (major << 3 | minor) -> uint8_t
7676
#define MAX_AVAILABILITY 31.7
7777

78-
@interface TNSInterfaceAlwaysAvailable : NSObject
78+
__attribute__((availability(ios, introduced = MAX_AVAILABILITY)))
79+
@protocol TNSProtocolNeverAvailable<NSObject>
80+
81+
+ (void)staticMethodFromProtocolNeverAvailable;
82+
- (void)methodFromProtocolNeverAvailable;
83+
84+
@end
85+
86+
__attribute__((availability(ios, introduced = 1.0)))
87+
@protocol TNSProtocolAlwaysAvailable<NSObject>
88+
89+
+ (void)staticMethodFromProtocolAlwaysAvailable;
90+
- (void)methodFromProtocolAlwaysAvailable;
91+
92+
@end
93+
94+
@interface TNSInterfaceAlwaysAvailable : NSObject <TNSProtocolNeverAvailable, TNSProtocolAlwaysAvailable>
7995
@end
8096

8197
__attribute__((availability(ios, introduced = MAX_AVAILABILITY)))

tests/TestFixtures/Api/TNSVersions.m

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@
1111
#undef generateVersionImpl
1212

1313
@implementation TNSInterfaceAlwaysAvailable
14+
15+
+ (void)staticMethodFromProtocolAlwaysAvailable {
16+
TNSLog([NSString stringWithFormat:@"%@ called", NSStringFromSelector(_cmd)]);
17+
}
18+
19+
+ (void)staticMethodFromProtocolNeverAvailable {
20+
TNSLog([NSString stringWithFormat:@"%@ called", NSStringFromSelector(_cmd)]);
21+
}
22+
23+
- (void)methodFromProtocolAlwaysAvailable {
24+
TNSLog([NSString stringWithFormat:@"%@ called", NSStringFromSelector(_cmd)]);
25+
}
26+
- (void)methodFromProtocolNeverAvailable {
27+
TNSLog([NSString stringWithFormat:@"%@ called", NSStringFromSelector(_cmd)]);
28+
}
29+
1430
@end
1531

1632
@implementation TNSInterfaceNeverAvailable : TNSInterfaceAlwaysAvailable

tests/TestRunner/app/VersionDiffTests.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,21 @@ describe(module.id, function() {
7878
// TNSInterfaceNeverAvailableDescendant : TNSInterfaceNeverAvailable(API31.7 - skipped) : TNSInterfaceAlwaysAvailable
7979
expect(Object.getPrototypeOf(TNSInterfaceNeverAvailableDescendant).toString()).toBe(TNSInterfaceAlwaysAvailable.toString(), "TNSInterfaceNeverAvailable base class should be skipped as it is unavailable");
8080
});
81+
82+
it("Methods of a protocol which is unavailable should be skipped", function() {
83+
expect(new TNSInterfaceAlwaysAvailable().methodFromProtocolNeverAvailable).toBeUndefined("TNSProtocolNeverAvailable methods should be skipped as it is unavailable");
84+
expect(TNSInterfaceAlwaysAvailable.staticMethodFromProtocolNeverAvailable).toBeUndefined("TNSProtocolNeverAvailable static methods should be skipped as it is unavailable");
85+
});
86+
87+
it("Methods of a protocol which is available should be present", function() {
88+
const obj = new TNSInterfaceAlwaysAvailable();
89+
expect(obj.methodFromProtocolAlwaysAvailable).toBeDefined("TNSProtocolAlwaysAvailable methods should be present as it is available");
90+
obj.methodFromProtocolAlwaysAvailable();
91+
expect(TNSGetOutput()).toBe("methodFromProtocolAlwaysAvailable called");
92+
TNSClearOutput();
93+
94+
expect(TNSInterfaceAlwaysAvailable.staticMethodFromProtocolAlwaysAvailable).toBeDefined("TNSProtocolAlwaysAvailable static methods should be present as it is available");
95+
TNSInterfaceAlwaysAvailable.staticMethodFromProtocolAlwaysAvailable();
96+
expect(TNSGetOutput()).toBe("staticMethodFromProtocolAlwaysAvailable called");
97+
});
8198
});

0 commit comments

Comments
 (0)