@@ -29,7 +29,10 @@ class Method extends Node {
2929 required this .name,
3030 required this .returnType,
3131 required this .parameters,
32+ required this .location,
33+ this .isRequired = true ,
3234 this .isAsynchronous = false ,
35+ this .isStatic = false ,
3336 this .offset,
3437 this .objcSelector = '' ,
3538 this .swiftFunction = '' ,
@@ -68,6 +71,18 @@ class Method extends Node {
6871 /// For example: [" List of documentation comments, separated by line.", ...]
6972 List <String > documentationComments;
7073
74+ /// Where the implementation of this method is located, host or Flutter.
75+ ApiLocation location;
76+
77+ /// Whether this method is required to be implemented.
78+ ///
79+ /// This flag is typically used to determine whether a callback method for
80+ /// a `ProxyApi` is nullable or not.
81+ bool isRequired;
82+
83+ /// Whether this is a static method of a ProxyApi.
84+ bool isStatic;
85+
7186 @override
7287 String toString () {
7388 final String objcSelectorStr =
@@ -78,29 +93,177 @@ class Method extends Node {
7893 }
7994}
8095
81- /// Represents a collection of [Method] s that are hosted on a given [location] .
82- class Api extends Node {
96+ /// Represents a collection of [Method] s that are implemented on the platform
97+ /// side.
98+ class AstHostApi extends Api {
99+ /// Parametric constructor for [AstHostApi] .
100+ AstHostApi ({
101+ required super .name,
102+ required super .methods,
103+ super .documentationComments = const < String > [],
104+ this .dartHostTestHandler,
105+ });
106+
107+ /// The name of the Dart test interface to generate to help with testing.
108+ String ? dartHostTestHandler;
109+
110+ @override
111+ String toString () {
112+ return '(HostApi name:$name methods:$methods documentationComments:$documentationComments dartHostTestHandler:$dartHostTestHandler )' ;
113+ }
114+ }
115+
116+ /// Represents a collection of [Method] s that are hosted on the Flutter side.
117+ class AstFlutterApi extends Api {
118+ /// Parametric constructor for [AstFlutterApi] .
119+ AstFlutterApi ({
120+ required super .name,
121+ required super .methods,
122+ super .documentationComments = const < String > [],
123+ });
124+
125+ @override
126+ String toString () {
127+ return '(FlutterApi name:$name methods:$methods documentationComments:$documentationComments )' ;
128+ }
129+ }
130+
131+ /// Represents an API that wraps a native class.
132+ class AstProxyApi extends Api {
133+ /// Parametric constructor for [AstProxyApi] .
134+ AstProxyApi ({
135+ required super .name,
136+ required super .methods,
137+ super .documentationComments = const < String > [],
138+ required this .constructors,
139+ required this .fields,
140+ this .superClass,
141+ this .interfaces = const < TypeDeclaration > {},
142+ });
143+
144+ /// List of constructors inside the API.
145+ final List <Constructor > constructors;
146+
147+ /// List of fields inside the API.
148+ List <ApiField > fields;
149+
150+ /// Name of the class this class considers the super class.
151+ TypeDeclaration ? superClass;
152+
153+ /// Name of the classes this class considers to be implemented.
154+ Set <TypeDeclaration > interfaces;
155+
156+ /// Methods implemented in the host platform language.
157+ Iterable <Method > get hostMethods => methods.where (
158+ (Method method) => method.location == ApiLocation .host,
159+ );
160+
161+ /// Methods implemented in Flutter.
162+ Iterable <Method > get flutterMethods => methods.where (
163+ (Method method) => method.location == ApiLocation .flutter,
164+ );
165+
166+ /// All fields that are attached.
167+ ///
168+ /// See [attached] .
169+ Iterable <ApiField > get attachedFields => fields.where (
170+ (ApiField field) => field.isAttached,
171+ );
172+
173+ /// All fields that are not attached.
174+ ///
175+ /// See [attached] .
176+ Iterable <ApiField > get unattachedFields => fields.where (
177+ (ApiField field) => ! field.isAttached,
178+ );
179+
180+ @override
181+ String toString () {
182+ return '(ProxyApi name:$name methods:$methods field:$fields '
183+ 'documentationComments:$documentationComments '
184+ 'superClassName:$superClass interfacesNames:$interfaces )' ;
185+ }
186+ }
187+
188+ /// Represents a constructor for an API.
189+ class Constructor extends Method {
190+ /// Parametric constructor for [Constructor] .
191+ Constructor ({
192+ required super .name,
193+ required super .parameters,
194+ super .offset,
195+ super .swiftFunction = '' ,
196+ super .documentationComments = const < String > [],
197+ }) : super (
198+ returnType: const TypeDeclaration .voidDeclaration (),
199+ location: ApiLocation .host,
200+ );
201+
202+ @override
203+ String toString () {
204+ final String swiftFunctionStr =
205+ swiftFunction.isEmpty ? '' : ' swiftFunction:$swiftFunction ' ;
206+ return '(Constructor name:$name parameters:$parameters $swiftFunctionStr documentationComments:$documentationComments )' ;
207+ }
208+ }
209+
210+ /// Represents a field of an API.
211+ class ApiField extends NamedType {
212+ /// Constructor for [ApiField] .
213+ ApiField ({
214+ required super .name,
215+ required super .type,
216+ super .offset,
217+ super .documentationComments,
218+ this .isAttached = false ,
219+ this .isStatic = false ,
220+ }) : assert (! isStatic || isAttached);
221+
222+ /// Whether this is an attached field for a [AstProxyApi] .
223+ ///
224+ /// See [attached] .
225+ final bool isAttached;
226+
227+ /// Whether this is a static field of a [AstProxyApi] .
228+ ///
229+ /// A static field must also be attached. See [attached] .
230+ final bool isStatic;
231+
232+ /// Returns a copy of [Parameter] instance with new attached [TypeDeclaration] .
233+ @override
234+ ApiField copyWithType (TypeDeclaration type) {
235+ return ApiField (
236+ name: name,
237+ type: type,
238+ offset: offset,
239+ documentationComments: documentationComments,
240+ isAttached: isAttached,
241+ isStatic: isStatic,
242+ );
243+ }
244+
245+ @override
246+ String toString () {
247+ return '(Field name:$name type:$type isAttached:$isAttached '
248+ 'isStatic:$isStatic documentationComments:$documentationComments )' ;
249+ }
250+ }
251+
252+ /// Represents a collection of [Method] s.
253+ sealed class Api extends Node {
83254 /// Parametric constructor for [Api] .
84255 Api ({
85256 required this .name,
86- required this .location,
87257 required this .methods,
88- this .dartHostTestHandler,
89258 this .documentationComments = const < String > [],
90259 });
91260
92261 /// The name of the API.
93262 String name;
94263
95- /// Where the API's implementation is located, host or Flutter.
96- ApiLocation location;
97-
98264 /// List of methods inside the API.
99265 List <Method > methods;
100266
101- /// The name of the Dart test interface to generate to help with testing.
102- String ? dartHostTestHandler;
103-
104267 /// List of documentation comments, separated by line.
105268 ///
106269 /// Lines should not include the comment marker itself, but should include any
@@ -110,7 +273,7 @@ class Api extends Node {
110273
111274 @override
112275 String toString () {
113- return '(Api name:$name location:$ location methods:$methods documentationComments:$documentationComments )' ;
276+ return '(Api name:$name methods:$methods documentationComments:$documentationComments )' ;
114277 }
115278}
116279
@@ -123,6 +286,7 @@ class TypeDeclaration {
123286 required this .isNullable,
124287 this .associatedEnum,
125288 this .associatedClass,
289+ this .associatedProxyApi,
126290 this .typeArguments = const < TypeDeclaration > [],
127291 });
128292
@@ -132,6 +296,7 @@ class TypeDeclaration {
132296 isNullable = false ,
133297 associatedEnum = null ,
134298 associatedClass = null ,
299+ associatedProxyApi = null ,
135300 typeArguments = const < TypeDeclaration > [];
136301
137302 /// The base name of the [TypeDeclaration] (ex 'Foo' to 'Foo<Bar>?').
@@ -158,6 +323,12 @@ class TypeDeclaration {
158323 /// Associated [Class] , if any.
159324 final Class ? associatedClass;
160325
326+ /// Whether the [TypeDeclaration] has an [associatedProxyApi] .
327+ bool get isProxyApi => associatedProxyApi != null ;
328+
329+ /// Associated [AstProxyApi] , if any.
330+ final AstProxyApi ? associatedProxyApi;
331+
161332 @override
162333 int get hashCode {
163334 // This has to be implemented because TypeDeclaration is used as a Key to a
@@ -207,11 +378,21 @@ class TypeDeclaration {
207378 );
208379 }
209380
381+ /// Returns duplicated `TypeDeclaration` with attached `associatedProxyApi` value.
382+ TypeDeclaration copyWithProxyApi (AstProxyApi proxyApiDefinition) {
383+ return TypeDeclaration (
384+ baseName: baseName,
385+ isNullable: isNullable,
386+ associatedProxyApi: proxyApiDefinition,
387+ typeArguments: typeArguments,
388+ );
389+ }
390+
210391 @override
211392 String toString () {
212393 final String typeArgumentsStr =
213394 typeArguments.isEmpty ? '' : 'typeArguments:$typeArguments ' ;
214- return '(TypeDeclaration baseName:$baseName isNullable:$isNullable $typeArgumentsStr isEnum:$isEnum isClass:$isClass )' ;
395+ return '(TypeDeclaration baseName:$baseName isNullable:$isNullable $typeArgumentsStr isEnum:$isEnum isClass:$isClass isProxyApi:$ isProxyApi )' ;
215396 }
216397}
217398
@@ -247,6 +428,7 @@ class NamedType extends Node {
247428 final List <String > documentationComments;
248429
249430 /// Returns a copy of [NamedType] instance with new attached [TypeDeclaration] .
431+ @mustBeOverridden
250432 NamedType copyWithType (TypeDeclaration type) {
251433 return NamedType (
252434 name: name,
0 commit comments