Skip to content

Commit a152054

Browse files
[interop] Resolved Namespace typedef and exception improvements (#459)
* resolved some issues - improved exception for not finding type - resolved def if cannot find file in path/module (i.e maybe a module already resolved by ts/node) * made resolutions * formatting * fixed typealias issue and ready now * changed transformation system * merged method signture and method decl together * Added test case for `typedef`
1 parent bdab462 commit a152054

File tree

9 files changed

+213
-151
lines changed

9 files changed

+213
-151
lines changed

web_generator/lib/src/ast/declarations.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ class EnumMember {
481481
String? dartName;
482482
}
483483

484-
class TypeAliasDeclaration extends NamedDeclaration
484+
class TypeAliasDeclaration extends NestableDeclaration
485485
implements ExportableDeclaration, DocumentedDeclaration {
486486
@override
487487
String name;
@@ -507,7 +507,8 @@ class TypeAliasDeclaration extends NamedDeclaration
507507
this.typeParameters = const [],
508508
required this.type,
509509
required this.exported,
510-
this.documentation})
510+
this.documentation,
511+
this.parent})
511512
: dartName = null;
512513

513514
@override
@@ -518,11 +519,14 @@ class TypeAliasDeclaration extends NamedDeclaration
518519
return TypeDef((t) => t
519520
..docs.addAll([...doc])
520521
..annotations.addAll([...annotations])
521-
..name = name
522+
..name = completedDartName
522523
..types
523524
.addAll(typeParameters.map((t) => t.emit(options?.toTypeOptions())))
524525
..definition = type.emit(options?.toTypeOptions()));
525526
}
527+
528+
@override
529+
NestableDeclaration? parent;
526530
}
527531

528532
/// The declaration node for a TypeScript Namespace

web_generator/lib/src/ast/merger.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import 'types.dart';
6666
ClassDeclaration? classDecl; // there can be only 1 class
6767
TypeAliasDeclaration? typealiasDecl; // there can be only 1 typedef
6868
final namespaces = <NamespaceDeclaration>[];
69+
final otherVariableDeclarations = <VariableDeclaration>[];
6970
final varDeclarations = <VariableDeclaration>[];
7071
final varDeclarationsWithBuiltinTypes = <VariableDeclaration>[];
7172
final otherDeclarations = <Declaration>[];
@@ -97,6 +98,8 @@ import 'types.dart';
9798
)
9899
when modifier == VariableModifier.$var:
99100
varDeclarationsWithBuiltinTypes.add(decl);
101+
case final VariableDeclaration v:
102+
otherVariableDeclarations.add(v);
100103
default:
101104
otherDeclarations.add(decl);
102105
break;
@@ -115,7 +118,7 @@ import 'types.dart';
115118
assert(interfaces.isEmpty && namespaces.isEmpty,
116119
'Typedefs in TS do not allow other decls');
117120

118-
for (final varDecl in varDeclarations) {
121+
for (final varDecl in [...varDeclarations, ...otherVariableDeclarations]) {
119122
final VariableDeclaration(
120123
type: varDeclType,
121124
name: varDeclName,
@@ -126,10 +129,11 @@ import 'types.dart';
126129
referredDecl.name == typealiasDecl.name) {
127130
// change type of var decl
128131
varDecl.type = referredDecl.type;
132+
output.add(varDecl);
129133
}
130134
}
131135

132-
output.addAll([...functions, ...varDeclarations]);
136+
output.addAll([...functions]);
133137
} else if (mergedNamespace != null) {
134138
var mergedComposite = mergedNamespace.asComposite
135139
..mergeType(mergedInterface);
@@ -158,7 +162,7 @@ import 'types.dart';
158162

159163
additionals.addAll([if (enumDecl != null) enumDecl]);
160164

161-
output.add(mergedComposite);
165+
output.addAll([mergedComposite, ...otherVariableDeclarations]);
162166
} else if (mergedInterface != null) {
163167
// merge em and vars
164168
mergedInterface = _mergeInterfaceWithVars(mergedInterface, varDeclarations)
@@ -182,7 +186,7 @@ import 'types.dart';
182186
}
183187

184188
// that's it
185-
output.addAll(functions);
189+
output.addAll([...functions, ...otherVariableDeclarations]);
186190
} else {
187191
return (declarations, additionals: []);
188192
}

web_generator/lib/src/interop_gen/transform.dart

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,16 @@ class ProgramMap {
177177
/// The files in the given project
178178
final p.PathSet files;
179179

180+
/// A list of declarations to include
180181
final List<String> filterDeclSet;
181182

183+
/// The declarations as globs
184+
List<RegExp> get filterDeclSetPatterns => filterDeclSet.map((decl) {
185+
final escapedDecl = RegExp.escape(decl);
186+
if (escapedDecl == decl) return RegExp('^$decl\$');
187+
return RegExp(decl);
188+
}).toList();
189+
182190
final bool generateAll;
183191

184192
final bool strictUnsupported;
@@ -201,28 +209,42 @@ class ProgramMap {
201209
} else {
202210
final src = program.getSourceFile(file);
203211

204-
final transformer =
205-
_activeTransformers.putIfAbsent(file, () => Transformer(this, src));
212+
if (src == null && !strictUnsupported) {
213+
// print warning
214+
print('WARN: Could not find file $file');
215+
// try to transform by yourself
216+
final anonymousTransformer = _activeTransformers.putIfAbsent(
217+
file, () => Transformer(this, null, file: file));
218+
219+
// TODO: Replace with .transformAndReturn once #388 lands
220+
return anonymousTransformer.transformAndReturn(node);
221+
} else {
222+
final transformer =
223+
_activeTransformers.putIfAbsent(file, () => Transformer(this, src));
206224

207-
if (!transformer.nodes.contains(node)) {
208-
if (declName case final d?
209-
when transformer.nodeMap.findByName(d).isEmpty) {
210-
// find the source file decl
211-
if (src == null) return null;
225+
if (!transformer.nodes.contains(node)) {
226+
if (declName case final d?
227+
when transformer.nodeMap.findByName(d).isEmpty) {
228+
// find the source file decl
229+
if (src == null) return null;
212230

213-
final symbol = typeChecker.getSymbolAtLocation(src)!;
214-
final exports = symbol.exports?.toDart ?? {};
231+
final symbol = typeChecker.getSymbolAtLocation(src)!;
232+
final exports = symbol.exports?.toDart ?? {};
215233

216-
final targetSymbol = exports[d.toJS]!;
234+
final targetSymbol = exports[d.toJS]!;
217235

218-
transformer.transform(targetSymbol.getDeclarations()!.toDart.first);
219-
} else {
220-
transformer.transform(node);
236+
for (final decl in targetSymbol.getDeclarations()?.toDart ??
237+
<TSDeclaration>[]) {
238+
transformer.transform(decl);
239+
}
240+
} else {
241+
transformer.transform(node);
242+
}
221243
}
222-
}
223244

224-
nodeMap = transformer.processAndReturn();
225-
_activeTransformers[file] = transformer;
245+
nodeMap = transformer.processAndReturn();
246+
_activeTransformers[file] = transformer;
247+
}
226248
}
227249

228250
final name = declName ?? (node as TSNamedDeclaration).name?.text;
@@ -287,8 +309,14 @@ class ProgramMap {
287309
} else {
288310
final exportedSymbols = sourceSymbol.exports?.toDart;
289311

290-
for (final MapEntry(value: symbol)
312+
for (final MapEntry(key: symbolName, value: symbol)
291313
in exportedSymbols?.entries ?? <MapEntry<JSString, TSSymbol>>[]) {
314+
// if there are decls to filter by and it does not match any, skip
315+
if (!filterDeclSetPatterns
316+
.any((f) => f.hasMatch(symbolName.toDart)) &&
317+
filterDeclSet.isNotEmpty) {
318+
continue;
319+
}
292320
final decls = symbol.getDeclarations()?.toDart ?? [];
293321
try {
294322
final aliasedSymbol = typeChecker.getAliasedSymbol(symbol);

0 commit comments

Comments
 (0)