@@ -3007,18 +3007,38 @@ export abstract class DeclaredElement extends Element {
30073007 isCompatibleOverride ( base : DeclaredElement ) : bool {
30083008 var self : DeclaredElement = this ; // TS
30093009 var kind = self . kind ;
3010+ var checkCompatibleOverride = false ;
30103011 if ( kind == base . kind ) {
30113012 switch ( kind ) {
3013+ case ElementKind . FUNCTION_PROTOTYPE : {
3014+ let selfFunction = this . program . resolver . resolveFunction ( < FunctionPrototype > self , null ) ;
3015+ if ( ! selfFunction ) return false ;
3016+ let baseFunction = this . program . resolver . resolveFunction ( < FunctionPrototype > base , null ) ;
3017+ if ( ! baseFunction ) return false ;
3018+ self = selfFunction ;
3019+ base = baseFunction ;
3020+ checkCompatibleOverride = true ;
3021+ // fall-through
3022+ }
30123023 case ElementKind . FUNCTION : {
3013- return ( < Function > self ) . signature . isAssignableTo ( ( < Function > base ) . signature ) ;
3024+ return ( < Function > self ) . signature . isAssignableTo ( ( < Function > base ) . signature , checkCompatibleOverride ) ;
3025+ }
3026+ case ElementKind . PROPERTY_PROTOTYPE : {
3027+ let selfProperty = this . program . resolver . resolveProperty ( < PropertyPrototype > self ) ;
3028+ if ( ! selfProperty ) return false ;
3029+ let baseProperty = this . program . resolver . resolveProperty ( < PropertyPrototype > base ) ;
3030+ if ( ! baseProperty ) return false ;
3031+ self = selfProperty ;
3032+ base = baseProperty ;
3033+ // fall-through
30143034 }
30153035 case ElementKind . PROPERTY : {
30163036 let selfProperty = < Property > self ;
30173037 let baseProperty = < Property > base ;
30183038 let selfGetter = selfProperty . getterInstance ;
30193039 let baseGetter = baseProperty . getterInstance ;
30203040 if ( selfGetter ) {
3021- if ( ! baseGetter || ! selfGetter . signature . isAssignableTo ( baseGetter . signature ) ) {
3041+ if ( ! baseGetter || ! selfGetter . signature . isAssignableTo ( baseGetter . signature , true ) ) {
30223042 return false ;
30233043 }
30243044 } else if ( baseGetter ) {
@@ -3027,14 +3047,18 @@ export abstract class DeclaredElement extends Element {
30273047 let selfSetter = selfProperty . setterInstance ;
30283048 let baseSetter = baseProperty . setterInstance ;
30293049 if ( selfSetter ) {
3030- if ( ! baseSetter || ! selfSetter . signature . isAssignableTo ( baseSetter . signature ) ) {
3050+ if ( ! baseSetter || ! selfSetter . signature . isAssignableTo ( baseSetter . signature , true ) ) {
30313051 return false ;
30323052 }
30333053 } else if ( baseSetter ) {
30343054 return false ;
30353055 }
30363056 return true ;
30373057 }
3058+ // TODO: Implement properties overriding fields and vice-versa. Challenge is that anything overridable requires
3059+ // a virtual stub, but fields aren't functions. Either all (such) fields should become property-like, with a
3060+ // getter and a setter that can participate as a virtual stub, or it's allowed one-way, with fields integrated
3061+ // into what can be a virtual stub as get=load and set=store, then not necessarily with own accessor functions.
30383062 }
30393063 }
30403064 return false ;
@@ -4294,6 +4318,11 @@ export class Class extends TypedElement {
42944318 ) ;
42954319 }
42964320
4321+ /** Tests if this is an interface. */
4322+ get isInterface ( ) : bool {
4323+ return this . kind == ElementKind . INTERFACE ;
4324+ }
4325+
42974326 /** Constructs a new class. */
42984327 constructor (
42994328 /** Name incl. type parameters, i.e. `Foo<i32>`. */
0 commit comments