Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions web_generator/lib/src/ast/declarations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ class EnumMember {
String? dartName;
}

class TypeAliasDeclaration extends NamedDeclaration
class TypeAliasDeclaration extends NestableDeclaration
implements ExportableDeclaration, DocumentedDeclaration {
@override
String name;
Expand All @@ -452,7 +452,8 @@ class TypeAliasDeclaration extends NamedDeclaration
this.typeParameters = const [],
required this.type,
required this.exported,
this.documentation})
this.documentation,
this.parent})
: dartName = null;

@override
Expand All @@ -463,11 +464,14 @@ class TypeAliasDeclaration extends NamedDeclaration
return TypeDef((t) => t
..docs.addAll([...doc])
..annotations.addAll([...annotations])
..name = name
..name = completedDartName
..types
.addAll(typeParameters.map((t) => t.emit(options?.toTypeOptions())))
..definition = type.emit(options?.toTypeOptions()));
}

@override
NestableDeclaration? parent;
}

/// The declaration node for a TypeScript Namespace
Expand Down
41 changes: 26 additions & 15 deletions web_generator/lib/src/interop_gen/transform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -201,28 +201,39 @@ class ProgramMap {
} else {
final src = program.getSourceFile(file);

final transformer =
if (src == null && !strictUnsupported) {
// print warning

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: need a warning :)

// try to transform by yourself
final anonymousTransformer =
_activeTransformers.putIfAbsent(file, () => Transformer(this, null, file: file));

// TODO: Replace with .transformAndReturn once #388 lands
return anonymousTransformer.transformAndReturn(node);
} else {
final transformer =
_activeTransformers.putIfAbsent(file, () => Transformer(this, src));

if (!transformer.nodes.contains(node)) {
if (declName case final d?
when transformer.nodeMap.findByName(d).isEmpty) {
// find the source file decl
if (src == null) return null;
if (!transformer.nodes.contains(node)) {
if (declName case final d?
when transformer.nodeMap.findByName(d).isEmpty) {
// find the source file decl
if (src == null) return null;

final symbol = typeChecker.getSymbolAtLocation(src)!;
final exports = symbol.exports?.toDart ?? {};
final symbol = typeChecker.getSymbolAtLocation(src)!;
final exports = symbol.exports?.toDart ?? {};

final targetSymbol = exports[d.toJS]!;
final targetSymbol = exports[d.toJS]!;

transformer.transform(targetSymbol.getDeclarations()!.toDart.first);
} else {
transformer.transform(node);
transformer.transform(targetSymbol.getDeclarations()!.toDart.first);
} else {
transformer.transform(node);
}
}
}

nodeMap = transformer.filterAndReturn();
_activeTransformers[file] = transformer;
nodeMap = transformer.filterAndReturn();
_activeTransformers[file] = transformer;
}
}

final name = declName ?? (node as TSNamedDeclaration).name?.text;
Expand Down
104 changes: 60 additions & 44 deletions web_generator/lib/src/interop_gen/transform/transformer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:collection';
import 'dart:js_interop';
import 'package:analyzer/dart/element/element2.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart' as p;
import '../../ast/base.dart';
Expand All @@ -13,6 +14,7 @@ import '../../ast/documentation.dart';
import '../../ast/helpers.dart';
import '../../ast/types.dart';
import '../../js/annotations.dart';
import '../../js/filesystem_api.dart';
import '../../js/helpers.dart';
import '../../js/typescript.dart' as ts;
import '../../js/typescript.types.dart';
Expand Down Expand Up @@ -101,14 +103,14 @@ class Transformer {
void transform(TSNode node) {
if (nodes.contains(node)) return;

final decls = _transform(node);
final decls = transformAndReturn(node);

nodeMap.addAll({for (final d in decls) d.id.toString(): d});

nodes.add(node);
}

List<Declaration> _transform(TSNode node,
List<Declaration> transformAndReturn(TSNode node,
{Set<ExportReference>? exportSet,
UniqueNamer? namer,
NamespaceDeclaration? parent}) {
Expand Down Expand Up @@ -287,6 +289,33 @@ class Transformer {
}
}

void transformDeclAndAppendParent(NamespaceDeclaration outputNamespace, TSNode decl) {
if (outputNamespace.nodes.contains(decl)) return;
final outputDecls =
transformAndReturn(decl, namer: scopedNamer, parent: outputNamespace);
switch (decl.kind) {
case TSSyntaxKind.ClassDeclaration ||
TSSyntaxKind.InterfaceDeclaration:
final outputDecl = outputDecls.first as TypeDeclaration;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should these by single calls instead of first here and in the below cases (besides default)?

outputDecl.parent = outputNamespace;
outputNamespace.nestableDeclarations.add(outputDecl);
case TSSyntaxKind.EnumDeclaration:
final outputDecl = outputDecls.first as EnumDeclaration;
outputDecl.parent = outputNamespace;
outputNamespace.nestableDeclarations.add(outputDecl);
case TSSyntaxKind.TypeAliasDeclaration:
final outputDecl = outputDecls.first as TypeAliasDeclaration;
outputDecl.parent = outputNamespace;
outputNamespace.nestableDeclarations.add(outputDecl);
default:
outputNamespace.topLevelDeclarations.addAll(outputDecls);
}
outputNamespace.nodes.add(decl);

// update namespace state
updateNSInParent();
}

// preload nodemap
updateNSInParent();

Expand All @@ -306,26 +335,7 @@ class Transformer {
for (final decl in decls) {
// TODO: We could also ignore namespace decls with the same name, as
// a single instance should consider such non-necessary
if (outputNamespace.nodes.contains(decl)) continue;
final outputDecls =
_transform(decl, namer: scopedNamer, parent: outputNamespace);
switch (decl.kind) {
case TSSyntaxKind.ClassDeclaration ||
TSSyntaxKind.InterfaceDeclaration:
final outputDecl = outputDecls.first as TypeDeclaration;
outputDecl.parent = outputNamespace;
outputNamespace.nestableDeclarations.add(outputDecl);
case TSSyntaxKind.EnumDeclaration:
final outputDecl = outputDecls.first as EnumDeclaration;
outputDecl.parent = outputNamespace;
outputNamespace.nestableDeclarations.add(outputDecl);
default:
outputNamespace.topLevelDeclarations.addAll(outputDecls);
}
outputNamespace.nodes.add(decl);

// update namespace state
updateNSInParent();
transformDeclAndAppendParent(outputNamespace, decl);
}
}
// fallback
Expand All @@ -334,24 +344,7 @@ class Transformer {
when namespaceBody.kind == TSSyntaxKind.ModuleBlock) {
for (final statement
in (namespaceBody as TSModuleBlock).statements.toDart) {
final outputDecls = _transform(statement,
namer: scopedNamer, parent: outputNamespace);
switch (statement.kind) {
case TSSyntaxKind.ClassDeclaration ||
TSSyntaxKind.InterfaceDeclaration:
final outputDecl = outputDecls.first as TypeDeclaration;
outputDecl.parent = outputNamespace;
outputNamespace.nestableDeclarations.add(outputDecl);
case TSSyntaxKind.EnumDeclaration:
final outputDecl = outputDecls.first as EnumDeclaration;
outputDecl.parent = outputNamespace;
outputNamespace.nestableDeclarations.add(outputDecl);
default:
outputNamespace.topLevelDeclarations.addAll(outputDecls);
}

// update namespace state
updateNSInParent();
transformDeclAndAppendParent(outputNamespace, statement);
}
} else if (namespace.body case final namespaceBody?) {
// namespace import
Expand Down Expand Up @@ -1041,7 +1034,7 @@ class Transformer {
default:
// TODO: Support Destructured Object Parameters
// and Destructured Array Parameters
throw Exception('Unsupported Parameter Name kind ${parameter.kind}');
throw Exception('Unsupported Parameter Name kind ${parameter.name.kind}');
}
}

Expand Down Expand Up @@ -1527,6 +1520,17 @@ class Transformer {
bool isNotTypableDeclaration = false,
bool typeArg = false,
bool isNullable = false}) {
print((
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: stray print

name.map((d) => d.part).join('.'),
parentName: parent?.qualifiedName,
symbol.getDeclarations()?.toDart.map((d) => d.kind),
isNullable: isNullable,
typeArg: typeArg,
parentDecls: {
...?parent?.namespaceDeclarations,
...?parent?.nestableDeclarations
}.map((d) => d.name)
));
// get name and map
final firstName = name.first.part;

Expand Down Expand Up @@ -1577,9 +1581,11 @@ class Transformer {
...parent.topLevelDeclarations
].map((d) => d.id.toString()))
: null;


// TODO: multi-decls
final transformedDecls =
_transform(firstDecl, namer: namer, parent: parent);
transformAndReturn(firstDecl, namer: namer, parent: parent);

if (parent != null) {
switch (firstDecl.kind) {
Expand Down Expand Up @@ -1613,6 +1619,12 @@ class Transformer {
}

// get node finally
print((
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: stray print

name: name.map((n) => n.part).join('.'),
declarationsMatching.map((d) => (d.id, d is NamedDeclaration)),
symbol.getDeclarations()?.toDart.map((d) => d.kind),
name.first
));
final decl = declarationsMatching.whereType<NamedDeclaration>().first;

// are we done?
Expand Down Expand Up @@ -1869,7 +1881,11 @@ class Transformer {
} else {
// if import there and not this file, imported from specified file
final importUrl =
!nameImport.endsWith('.d.ts') ? '$nameImport.d.ts' : nameImport;
!nameImport.endsWith('.d.ts') && fs.existsSync(
(p.isAbsolute('$nameImport.d.ts')
? '$nameImport.d.ts'
: p.join(p.dirname(file), '$nameImport.d.ts')).toJS
).toDart ? '$nameImport.d.ts' : nameImport;
final relativePath = programMap.files.contains(importUrl)
? p.relative(importUrl, from: p.dirname(file))
: null;
Expand Down Expand Up @@ -1915,7 +1931,7 @@ class Transformer {
}
}
}
throw Exception('Could not resolve type for node');
throw Exception('Could not resolve type for node ${fullyQualifiedName.asName}${nameImport == null ? '' : ' from $nameImport'}');
}

/// Get the type of a type node named [typeName] by referencing its
Expand Down
Loading