@@ -19,8 +19,9 @@ export function isFunctionLikeProperty(
19
19
20
20
export default class DeclarationTranspiler extends base . TranspilerBase {
21
21
private tc : ts . TypeChecker ;
22
-
23
22
private extendsClass = false ;
23
+ private containsPromises = false ;
24
+ private promiseMethods : Set < ts . FunctionLikeDeclaration > = new Set ( ) ;
24
25
25
26
static NUM_FAKE_REST_PARAMETERS = 5 ;
26
27
@@ -446,7 +447,7 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
446
447
// instead.
447
448
this . visit ( fnType . type ) ;
448
449
this . visit ( paramDecl . name ) ;
449
- this . visitParameters ( fnType . parameters ) ;
450
+ this . visitParameters ( fnType . parameters , { namesOnly : false } ) ;
450
451
break ;
451
452
}
452
453
}
@@ -500,6 +501,11 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
500
501
case ts . SyntaxKind . SourceFile :
501
502
let sourceFile = node as ts . SourceFile ;
502
503
this . visitMergingOverloads ( sourceFile . statements ) ;
504
+ if ( this . containsPromises ) {
505
+ this . addImport ( 'dart:async' , 'Completer' ) ;
506
+ this . addImport ( 'package:js/js_util.dart' , 'promiseToFuture' ) ;
507
+ this . emit ( `@JS() abstract class Promise<T> {}\n` ) ;
508
+ }
503
509
break ;
504
510
case ts . SyntaxKind . ModuleBlock : {
505
511
let block = < ts . ModuleBlock > node ;
@@ -540,7 +546,7 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
540
546
this . emit ( 'external' ) ;
541
547
this . visit ( fn . type ) ;
542
548
this . emit ( 'call' ) ;
543
- this . visitParameters ( fn . parameters ) ;
549
+ this . visitParameters ( fn . parameters , { namesOnly : false } ) ;
544
550
this . emitNoSpace ( ';' ) ;
545
551
} break ;
546
552
case ts . SyntaxKind . IndexSignature :
@@ -641,7 +647,7 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
641
647
}
642
648
this . visitDeclarationMetadata ( ctorDecl ) ;
643
649
this . fc . visitTypeName ( classDecl . name ) ;
644
- this . visitParameters ( ctorDecl . parameters ) ;
650
+ this . visitParameters ( ctorDecl . parameters , { namesOnly : false } ) ;
645
651
this . emitNoSpace ( ';' ) ;
646
652
if ( isAnonymous ) {
647
653
this . exitCodeComment ( ) ;
@@ -681,6 +687,16 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
681
687
break ;
682
688
case ts . SyntaxKind . MethodSignature :
683
689
let methodSignatureDecl = < ts . FunctionLikeDeclaration > node ;
690
+ if ( base . isPromise ( methodSignatureDecl . type ) ) {
691
+ if ( this . promiseMethods . has ( methodSignatureDecl ) ) {
692
+ break ;
693
+ }
694
+ if ( ! this . containsPromises ) {
695
+ this . containsPromises = true ;
696
+ }
697
+ this . promiseMethods . add ( methodSignatureDecl ) ;
698
+ break ;
699
+ }
684
700
this . visitDeclarationMetadata ( methodSignatureDecl ) ;
685
701
this . visitFunctionLike ( methodSignatureDecl ) ;
686
702
break ;
@@ -759,7 +775,7 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
759
775
}
760
776
// Dart does not even allow the parens of an empty param list on getter
761
777
if ( accessor !== 'get' ) {
762
- this . visitParameters ( fn . parameters ) ;
778
+ this . visitParameters ( fn . parameters , { namesOnly : false } ) ;
763
779
} else {
764
780
if ( fn . parameters && fn . parameters . length > 0 ) {
765
781
this . reportError ( fn , 'getter should not accept parameters' ) ;
@@ -858,7 +874,12 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
858
874
( < ts . ConstructorDeclaration > ctor ) . parameters . forEach ( synthesizePropertyParam ) ) ;
859
875
860
876
this . visitClassBody ( decl , name ) ;
861
- this . emit ( '}\n\n' ) ;
877
+ this . emit ( '}\n' ) ;
878
+ if ( this . promiseMethods . size ) {
879
+ this . emitMethodsAsExtensions ( name , this . promiseMethods ) ;
880
+ this . promiseMethods . clear ( ) ;
881
+ }
882
+ this . emit ( '\n' ) ;
862
883
}
863
884
864
885
private visitDeclarationMetadata ( decl : ts . Declaration ) {
@@ -906,7 +927,42 @@ export default class DeclarationTranspiler extends base.TranspilerBase {
906
927
this . exitTypeArguments ( ) ;
907
928
this . emitNoSpace ( '>' ) ;
908
929
}
909
- this . visitParameters ( signature . parameters ) ;
930
+ this . visitParameters ( signature . parameters , { namesOnly : false } ) ;
910
931
this . emitNoSpace ( ';' ) ;
911
932
}
933
+
934
+ private emitMethodsAsExtensions (
935
+ className : ts . Identifier , methods : Set < ts . FunctionLikeDeclaration > ) {
936
+ // Emit private class containing external methods
937
+ this . emit ( `@JS('${ base . ident ( className ) } ')` ) ;
938
+ this . emit ( `abstract class _` ) ;
939
+ this . fc . visitTypeName ( className ) ;
940
+ this . emit ( '{' ) ;
941
+ for ( const declaration of methods ) {
942
+ this . visitFunctionLike ( declaration ) ;
943
+ }
944
+ this . emit ( '}\n' ) ;
945
+
946
+ // Emit extensions on public class to expose methods
947
+ this . emit ( 'extension on' ) ;
948
+ this . fc . visitTypeName ( className ) ;
949
+ this . emit ( '{' ) ;
950
+ for ( const declaration of methods ) {
951
+ if ( ! base . isPromise ( declaration . type ) ) {
952
+ continue ;
953
+ }
954
+ this . emit ( 'Future' ) ;
955
+ this . emit ( base . ident ( declaration . name ) ) ;
956
+ this . visitParameters ( declaration . parameters , { namesOnly : false } ) ;
957
+ this . emit ( '{' ) ;
958
+ this . emit ( 'final Object t = this;' ) ;
959
+ this . emit ( 'final _' ) ;
960
+ this . fc . visitTypeName ( className ) ;
961
+ this . emit ( 'tt = t;\n' ) ;
962
+ this . emit ( `return promiseToFuture(tt.${ base . ident ( declaration . name ) } ` ) ;
963
+ this . visitParameters ( declaration . parameters , { namesOnly : true } ) ;
964
+ this . emit ( ');}\n' ) ;
965
+ }
966
+ this . emit ( '}\n' ) ;
967
+ }
912
968
}
0 commit comments