@@ -82,7 +82,10 @@ import {
82
82
IndexSignature ,
83
83
File ,
84
84
mangleInternalName ,
85
- Interface
85
+ Interface ,
86
+ TypedElement ,
87
+ FieldPrototype ,
88
+ DeclaredElement
86
89
} from "./program" ;
87
90
88
91
import {
@@ -2953,49 +2956,7 @@ export class Compiler extends DiagnosticEmitter {
2953
2956
fromType . toString ( ) ,
2954
2957
toType . toString ( ) ) ;
2955
2958
} else {
2956
- const _interface = ( < Interface > toType . classReference ! ) ;
2957
- let _class = fromType . classReference ! ;
2958
- let incorrectMethods = _interface . checkClass ( _class ) ;
2959
- if ( incorrectMethods . length == 0 ) {
2960
- _interface . implementers . add ( fromType . classReference ! ) ;
2961
- } else {
2962
- this . error (
2963
- DiagnosticCode . Type_0_is_not_assignable_to_type_1 ,
2964
- reportNode . range ,
2965
- fromType . toString ( ) ,
2966
- toType . toString ( ) ) ;
2967
- let missingMethods = false ;
2968
- // tslint:disable-next-line: as-types
2969
- for ( let i : i32 = 0 ; i < incorrectMethods . length ; i ++ ) {
2970
- const ifunc = incorrectMethods [ i ] ;
2971
- if ( _class . members == null || ! _class . members . has ( ifunc . name ) ) {
2972
- if ( ! missingMethods ) {
2973
- missingMethods = true ;
2974
- this . error (
2975
- DiagnosticCode . Class_0_incorrectly_implements_interface_1 ,
2976
- _class . identifierNode . range ,
2977
- fromType . toString ( ) ,
2978
- toType . toString ( )
2979
- ) ;
2980
- }
2981
- this . error (
2982
- DiagnosticCode . Property_0_is_missing_in_type_1_but_required_in_type_2 ,
2983
- _class . identifierNode . range ,
2984
- ifunc . name ,
2985
- fromType . toString ( ) ,
2986
- toType . toString ( )
2987
- ) ;
2988
- } else {
2989
- let otherFunc = _class . members . get ( ifunc . name ) ! ;
2990
- this . error (
2991
- DiagnosticCode . Type_0_is_not_assignable_to_type_1 ,
2992
- otherFunc . identifierNode . range ,
2993
- _class . name + "." + otherFunc . name ,
2994
- _interface . name + "." + ifunc . name ) ;
2995
- }
2996
- }
2997
- }
2998
-
2959
+ this . checkInterfaceImplementation ( toType , fromType , reportNode ) ;
2999
2960
}
3000
2961
}
3001
2962
else if ( ! fromType . isAssignableTo ( toType ) ) {
@@ -9312,6 +9273,125 @@ export class Compiler extends DiagnosticEmitter {
9312
9273
module . removeFunction ( func . internalName ) ;
9313
9274
return module . addFunction ( func . internalName , typeRef , null , body ) ;
9314
9275
}
9276
+
9277
+ checkInterfaceImplementation ( toType : Type , fromType : Type , reportNode : Node ) : void {
9278
+ const _interface = ( < Interface > toType . classReference ! ) ;
9279
+ const _class = fromType . classReference ! ;
9280
+ var imems : Map < string , Element > ;
9281
+ var mems : Map < string , Element > ;
9282
+ if ( _interface . prototype . instanceMembers == null ) {
9283
+ return ;
9284
+ } else {
9285
+ imems = _interface . prototype . instanceMembers ;
9286
+ if ( _class . prototype . instanceMembers == null ) {
9287
+ // All members missing
9288
+
9289
+ return ;
9290
+ } else {
9291
+ mems = _class . prototype . instanceMembers ;
9292
+ }
9293
+ }
9294
+ var error = false ;
9295
+ var incorrectMember = false ;
9296
+ for ( const [ name , imem ] of imems . entries ( ) ) {
9297
+ error = error || incorrectMember ;
9298
+ incorrectMember = true ;
9299
+ let mem = mems . get ( name ) ;
9300
+ if ( mem == null ) {
9301
+ // Error!
9302
+ this . error (
9303
+ DiagnosticCode . Property_0_is_missing_in_type_1_but_required_in_type_2 ,
9304
+ _class . identifierNode . range ,
9305
+ name ,
9306
+ _class . name ,
9307
+ _interface . name
9308
+ ) ;
9309
+ continue ;
9310
+ }
9311
+ if ( imem . kind != mem . kind ) {
9312
+ // Interfaces can't have properties
9313
+ if ( ! ( mem . kind == ElementKind . PROPERTY_PROTOTYPE && imem . kind == ElementKind . FIELD_PROTOTYPE ) ) {
9314
+ this . error (
9315
+ DiagnosticCode . Type_0_is_not_assignable_to_type_1 ,
9316
+ ( < DeclaredElement > mem ) . declaration . range ,
9317
+ mem . name ,
9318
+ name ) ;
9319
+ continue ;
9320
+ }
9321
+ // Error
9322
+ }
9323
+ let from : Type = Type . void , to : Type = Type . void ;
9324
+ switch ( mem . kind ) {
9325
+ case ElementKind . FIELD_PROTOTYPE : {
9326
+ from = this . resolver . resolveType ( ( < FieldPrototype > mem ) . typeNode ! , _class ) ! ;
9327
+ to = this . resolver . resolveType ( ( < FieldPrototype > imem ) . typeNode ! , _interface ) ! ;
9328
+ break ;
9329
+ }
9330
+ case ElementKind . FUNCTION_PROTOTYPE : {
9331
+ let func = ( < FunctionPrototype > mem ) ;
9332
+ mem . parent = _class ;
9333
+ imem . parent = _interface ;
9334
+ from = this . resolver . resolveType ( func . functionTypeNode , func , _class . contextualTypeArguments ) ! ; //, ReportMode.REPORT, false)!.type;
9335
+ to = this . resolver . resolveType ( ( < FunctionPrototype > imem ) . functionTypeNode , imem , _interface . contextualTypeArguments , ReportMode . REPORT ) ! ;
9336
+ break ;
9337
+ }
9338
+ case ElementKind . PROPERTY_PROTOTYPE : {
9339
+ const property = < PropertyPrototype > mem ;
9340
+ const iproperty = < FieldPrototype > imem ;
9341
+ if ( ! iproperty . is ( CommonFlags . READONLY ) ) {
9342
+ if ( property . setterPrototype == null ) {
9343
+ this . error (
9344
+ DiagnosticCode . Property_0_is_missing_in_type_1_but_required_in_type_2 ,
9345
+ _class . identifierNode . range ,
9346
+ "set " + name ,
9347
+ _class . name ,
9348
+ _interface . name
9349
+ ) ;
9350
+ error = true ;
9351
+ // Error
9352
+ break ;
9353
+ }
9354
+ }
9355
+ if ( property . getterPrototype == null ) {
9356
+ this . error (
9357
+ DiagnosticCode . Property_0_is_missing_in_type_1_but_required_in_type_2 ,
9358
+ _class . identifierNode . range ,
9359
+ "get " + name ,
9360
+ _class . name ,
9361
+ _interface . name
9362
+ ) ;
9363
+ continue ;
9364
+ // Error
9365
+ }
9366
+ from = this . resolver . resolveType ( property . getterPrototype . functionTypeNode , property . getterPrototype , _class . contextualTypeArguments , ReportMode . REPORT ) ! ;
9367
+ to = this . resolver . resolveType ( ( < FieldPrototype > imem ) . typeNode ! , _interface ) ! ;
9368
+ }
9369
+ default : {
9370
+ // Error
9371
+ continue ;
9372
+ }
9373
+ }
9374
+ if ( ! from . isAssignableTo ( to ) ) {
9375
+ this . error (
9376
+ DiagnosticCode . Type_0_is_not_assignable_to_type_1 ,
9377
+ ( < DeclaredElement > mem ) . declaration . range ,
9378
+ from . toString ( ) ,
9379
+ to . toString ( )
9380
+ ) ;
9381
+ continue ;
9382
+ // Error
9383
+ }
9384
+ incorrectMember = false ;
9385
+ }
9386
+ if ( error ) {
9387
+ this . error (
9388
+ DiagnosticCode . Class_0_incorrectly_implements_interface_1 ,
9389
+ _class . identifierNode . range ,
9390
+ fromType . toString ( ) ,
9391
+ toType . toString ( )
9392
+ ) ;
9393
+ }
9394
+ }
9315
9395
}
9316
9396
9317
9397
// helpers
0 commit comments