@@ -3210,7 +3210,10 @@ export class FunctionPrototype extends DeclaredElement {
3210
3210
get isBound ( ) : bool {
3211
3211
var parent = this . parent ;
3212
3212
return parent . kind == ElementKind . CLASS
3213
- || parent . kind == ElementKind . PROPERTY_PROTOTYPE && parent . parent . kind == ElementKind . CLASS ;
3213
+ || parent . kind == ElementKind . PROPERTY_PROTOTYPE && (
3214
+ parent . parent . kind == ElementKind . CLASS ||
3215
+ parent . parent . kind == ElementKind . INTERFACE
3216
+ ) ;
3214
3217
}
3215
3218
3216
3219
/** Creates a clone of this prototype that is bound to a concrete class instead. */
@@ -3415,8 +3418,9 @@ export class Function extends TypedElement {
3415
3418
/** Finalizes the function once compiled, releasing no longer needed resources. */
3416
3419
finalize ( module : Module , ref : FunctionRef ) : void {
3417
3420
this . ref = ref ;
3418
- assert ( ! this . breakStack || ! this . breakStack . length ) ; // internal error
3419
- this . breakStack = null ;
3421
+ var breakStack = this . breakStack ;
3422
+ assert ( ! breakStack || ! breakStack . length ) ; // internal error
3423
+ this . breakStack = breakStack = null ;
3420
3424
this . breakLabel = null ;
3421
3425
this . tempI32s = this . tempI64s = this . tempF32s = this . tempF64s = null ;
3422
3426
if ( this . program . options . sourceMap ) {
@@ -3571,13 +3575,18 @@ export class PropertyPrototype extends DeclaredElement {
3571
3575
getterPrototype : FunctionPrototype | null = null ;
3572
3576
/** Setter prototype. */
3573
3577
setterPrototype : FunctionPrototype | null = null ;
3578
+ /** Property instance, if resolved. */
3579
+ instance : Property | null = null ;
3580
+
3581
+ /** Clones of this prototype that are bound to specific classes. */
3582
+ private boundPrototypes : Map < Class , PropertyPrototype > | null = null ;
3574
3583
3575
3584
/** Constructs a new property prototype. */
3576
3585
constructor (
3577
3586
/** Simple name. */
3578
3587
name : string ,
3579
- /** Parent class. */
3580
- parent : ClassPrototype ,
3588
+ /** Parent element. Either a class prototype or instance . */
3589
+ parent : Element ,
3581
3590
/** Declaration of the getter or setter introducing the property. */
3582
3591
firstDeclaration : FunctionDeclaration
3583
3592
) {
@@ -3596,6 +3605,42 @@ export class PropertyPrototype extends DeclaredElement {
3596
3605
lookup ( name : string ) : Element | null {
3597
3606
return this . parent . lookup ( name ) ;
3598
3607
}
3608
+
3609
+ /** Tests if this prototype is bound to a class. */
3610
+ get isBound ( ) : bool {
3611
+ switch ( this . parent . kind ) {
3612
+ case ElementKind . CLASS :
3613
+ case ElementKind . INTERFACE : return true ;
3614
+ }
3615
+ return false ;
3616
+ }
3617
+
3618
+ /** Creates a clone of this prototype that is bound to a concrete class instead. */
3619
+ toBound ( classInstance : Class ) : PropertyPrototype {
3620
+ assert ( this . is ( CommonFlags . INSTANCE ) ) ;
3621
+ assert ( ! this . isBound ) ;
3622
+ var boundPrototypes = this . boundPrototypes ;
3623
+ if ( ! boundPrototypes ) this . boundPrototypes = boundPrototypes = new Map ( ) ;
3624
+ else if ( boundPrototypes . has ( classInstance ) ) return assert ( boundPrototypes . get ( classInstance ) ) ;
3625
+ var firstDeclaration = this . declaration ;
3626
+ assert ( firstDeclaration . kind == NodeKind . METHODDECLARATION ) ;
3627
+ var bound = new PropertyPrototype (
3628
+ this . name ,
3629
+ classInstance , // !
3630
+ < MethodDeclaration > firstDeclaration
3631
+ ) ;
3632
+ bound . flags = this . flags ;
3633
+ var getterPrototype = this . getterPrototype ;
3634
+ if ( getterPrototype ) {
3635
+ bound . getterPrototype = getterPrototype . toBound ( classInstance ) ;
3636
+ }
3637
+ var setterPrototype = this . setterPrototype ;
3638
+ if ( setterPrototype ) {
3639
+ bound . setterPrototype = setterPrototype . toBound ( classInstance ) ;
3640
+ }
3641
+ boundPrototypes . set ( classInstance , bound ) ;
3642
+ return bound ;
3643
+ }
3599
3644
}
3600
3645
3601
3646
/** A resolved property. */
@@ -3631,7 +3676,9 @@ export class Property extends VariableLikeElement {
3631
3676
this . prototype = prototype ;
3632
3677
this . flags = prototype . flags ;
3633
3678
this . decoratorFlags = prototype . decoratorFlags ;
3634
- registerConcreteElement ( this . program , this ) ;
3679
+ if ( this . is ( CommonFlags . INSTANCE ) ) {
3680
+ registerConcreteElement ( this . program , this ) ;
3681
+ }
3635
3682
}
3636
3683
3637
3684
/* @override */
@@ -3860,8 +3907,8 @@ export class Class extends TypedElement {
3860
3907
return lengthField !== null && (
3861
3908
lengthField . kind == ElementKind . FIELD ||
3862
3909
(
3863
- lengthField . kind == ElementKind . PROPERTY &&
3864
- ( < Property > lengthField ) . getterInstance !== null // TODO: resolve & check type?
3910
+ lengthField . kind == ElementKind . PROPERTY_PROTOTYPE &&
3911
+ ( < PropertyPrototype > lengthField ) . getterPrototype !== null // TODO: resolve & check type?
3865
3912
)
3866
3913
) && (
3867
3914
this . lookupOverload ( OperatorKind . INDEXED_GET ) !== null ||
@@ -3908,9 +3955,10 @@ export class Class extends TypedElement {
3908
3955
throw new Error ( "type argument count mismatch" ) ;
3909
3956
}
3910
3957
if ( numTypeArguments ) {
3911
- if ( ! this . contextualTypeArguments ) this . contextualTypeArguments = new Map ( ) ;
3958
+ let contextualTypeArguments = this . contextualTypeArguments ;
3959
+ if ( ! contextualTypeArguments ) this . contextualTypeArguments = contextualTypeArguments = new Map ( ) ;
3912
3960
for ( let i = 0 ; i < numTypeArguments ; ++ i ) {
3913
- this . contextualTypeArguments . set ( typeParameters [ i ] . name . text , typeArguments [ i ] ) ;
3961
+ contextualTypeArguments . set ( typeParameters [ i ] . name . text , typeArguments [ i ] ) ;
3914
3962
}
3915
3963
}
3916
3964
} else if ( typeParameters !== null && typeParameters . length > 0 ) {
@@ -4402,8 +4450,8 @@ export function mangleInternalName(name: string, parent: Element, isInstance: bo
4402
4450
assert ( ! isInstance ) ;
4403
4451
return parent . internalName + INNER_DELIMITER + name ;
4404
4452
}
4405
- case ElementKind . PROPERTY_PROTOTYPE :
4406
- case ElementKind . PROPERTY : {
4453
+ case ElementKind . PROPERTY_PROTOTYPE : // properties are just containers
4454
+ case ElementKind . PROPERTY : { //
4407
4455
parent = parent . parent ;
4408
4456
// fall-through
4409
4457
}
0 commit comments