@expo/expo-modules-macros-plugin 0.0.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +118 -0
- package/.github/workflows/swift.yml +59 -0
- package/apple/ExpoModulesMacros-tool +0 -0
- package/apple/Package.swift +11 -4
- package/apple/Sources/ExpoModulesMacros/DecorateFunctionBuilder.swift +174 -0
- package/apple/Sources/ExpoModulesMacros/ExpoModuleMacro.swift +170 -19
- package/apple/Sources/ExpoModulesMacros/MacroHelpers.swift +116 -0
- package/apple/Sources/ExpoModulesMacros/RecordMacro.swift +424 -135
- package/apple/Sources/ExpoModulesMacros/SharedObjectMacro.swift +17 -20
- package/apple/build.js +129 -12
- package/package.json +1 -1
|
@@ -39,6 +39,122 @@ internal func classListArgument(of attribute: AttributeSyntax, label: String) ->
|
|
|
39
39
|
return []
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
Returns true if the class's inheritance clause names any of the given identifiers.
|
|
44
|
+
Matches by base identifier only, so `Module`, `ExpoModulesCore.Module`, and
|
|
45
|
+
`Module<Foo>` all match an entry of "Module".
|
|
46
|
+
*/
|
|
47
|
+
internal func inheritsFromAny(_ classDecl: ClassDeclSyntax, names: Set<String>) -> Bool {
|
|
48
|
+
guard let inherited = classDecl.inheritanceClause?.inheritedTypes else {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
for entry in inherited {
|
|
52
|
+
if let name = baseIdentifier(of: entry.type), names.contains(name) {
|
|
53
|
+
return true
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return false
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
Returns the rightmost identifier of a type, e.g. `Foo` for `Foo`, `Foo` for
|
|
61
|
+
`Module.Foo`, and nil for composed or generic shapes the macro doesn't need to handle.
|
|
62
|
+
*/
|
|
63
|
+
internal func baseIdentifier(of type: TypeSyntax) -> String? {
|
|
64
|
+
if let identifier = type.as(IdentifierTypeSyntax.self) {
|
|
65
|
+
return identifier.name.text
|
|
66
|
+
}
|
|
67
|
+
if let member = type.as(MemberTypeSyntax.self) {
|
|
68
|
+
return member.name.text
|
|
69
|
+
}
|
|
70
|
+
return nil
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
True if the declaration carries a `@JS` attribute. Works for functions, properties, and inits;
|
|
75
|
+
returns false for any other decl kind.
|
|
76
|
+
*/
|
|
77
|
+
internal func memberHasJSAttribute(_ decl: DeclSyntaxProtocol) -> Bool {
|
|
78
|
+
if let funcDecl = decl.as(FunctionDeclSyntax.self) {
|
|
79
|
+
return funcDecl.attributes.firstAttribute(named: "JS") != nil
|
|
80
|
+
}
|
|
81
|
+
if let varDecl = decl.as(VariableDeclSyntax.self) {
|
|
82
|
+
return varDecl.attributes.firstAttribute(named: "JS") != nil
|
|
83
|
+
}
|
|
84
|
+
if let initDecl = decl.as(InitializerDeclSyntax.self) {
|
|
85
|
+
return initDecl.attributes.firstAttribute(named: "JS") != nil
|
|
86
|
+
}
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
Decides whether the macro should stamp `@JavaScriptActor` on a `@JS`-marked member.
|
|
92
|
+
The macro defers to the user when they've already chosen an isolation:
|
|
93
|
+
- the `nonisolated` modifier is present on the member
|
|
94
|
+
- any attribute whose name matches a known global actor (`@MainActor`, `@JavaScriptActor`)
|
|
95
|
+
or follows the `*Actor` naming convention is present on the member or its enclosing type
|
|
96
|
+
Async members never get the stamp because `AsyncFunction` controls their dispatch separately.
|
|
97
|
+
*/
|
|
98
|
+
internal func shouldStampJavaScriptActor(
|
|
99
|
+
on member: DeclSyntaxProtocol,
|
|
100
|
+
enclosedBy enclosing: some DeclGroupSyntax
|
|
101
|
+
) -> Bool {
|
|
102
|
+
let modifiers = memberModifiers(of: member)
|
|
103
|
+
if modifiers.contains(where: { $0.name.text == "nonisolated" }) {
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if let funcDecl = member.as(FunctionDeclSyntax.self),
|
|
108
|
+
funcDecl.signature.effectSpecifiers?.asyncSpecifier != nil {
|
|
109
|
+
return false
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let memberAttributes = memberAttributes(of: member)
|
|
113
|
+
if memberAttributes.contains(where: hasGlobalActorShape) {
|
|
114
|
+
return false
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if enclosing.attributes.contains(where: hasGlobalActorShape) {
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private func memberModifiers(of decl: DeclSyntaxProtocol) -> DeclModifierListSyntax {
|
|
125
|
+
if let funcDecl = decl.as(FunctionDeclSyntax.self) {
|
|
126
|
+
return funcDecl.modifiers
|
|
127
|
+
}
|
|
128
|
+
if let varDecl = decl.as(VariableDeclSyntax.self) {
|
|
129
|
+
return varDecl.modifiers
|
|
130
|
+
}
|
|
131
|
+
if let initDecl = decl.as(InitializerDeclSyntax.self) {
|
|
132
|
+
return initDecl.modifiers
|
|
133
|
+
}
|
|
134
|
+
return DeclModifierListSyntax()
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
internal func memberAttributes(of decl: DeclSyntaxProtocol) -> AttributeListSyntax {
|
|
138
|
+
if let funcDecl = decl.as(FunctionDeclSyntax.self) {
|
|
139
|
+
return funcDecl.attributes
|
|
140
|
+
}
|
|
141
|
+
if let varDecl = decl.as(VariableDeclSyntax.self) {
|
|
142
|
+
return varDecl.attributes
|
|
143
|
+
}
|
|
144
|
+
if let initDecl = decl.as(InitializerDeclSyntax.self) {
|
|
145
|
+
return initDecl.attributes
|
|
146
|
+
}
|
|
147
|
+
return AttributeListSyntax()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private func hasGlobalActorShape(_ element: AttributeListSyntax.Element) -> Bool {
|
|
151
|
+
guard let attribute = element.as(AttributeSyntax.self) else {
|
|
152
|
+
return false
|
|
153
|
+
}
|
|
154
|
+
let name = attribute.attributeName.trimmedDescription
|
|
155
|
+
return name.hasSuffix("Actor")
|
|
156
|
+
}
|
|
157
|
+
|
|
42
158
|
extension AttributeListSyntax {
|
|
43
159
|
internal func firstAttribute(named name: String) -> AttributeSyntax? {
|
|
44
160
|
for element in self {
|