@@ -4,43 +4,74 @@ import supportsInterface from '../../supports/interface.js';
44import supportsMember from '../../supports/member.js' ;
55
66export class MemberFeature extends Feature {
7- constructor ( def , parent ) {
8- super ( def , parent ) ;
7+ static children = {
8+ /** The member needs to be an instance of this class */
9+ instanceof : { type : MemberFeature } ,
10+ }
11+
12+ static gatingTest = true ;
13+
14+ get base ( ) {
15+ return this . closest ( f => f instanceof InterfaceFeature ) ?. base ;
16+ }
917
10- let fromParent = this . def . fromParent ;
11- this . memberType = fromParent === 'properties' || fromParent === 'functions' ? 'static' : 'instance' ;
12- this . memberKind = fromParent === 'methods' || fromParent === 'functions' ? 'method' : 'property' ;
13- this . base = this . parent . base ;
18+ get memberType ( ) {
19+ return this . def . fromParent === 'instanceof' ? this . parent . def . fromParent : this . def . fromParent ;
1420 }
1521
1622 get code ( ) {
17- if ( this . memberKind === 'method ' ) {
23+ if ( this . def . fromParent === 'functions' || this . def . fromParent === 'methods ') {
1824 return this . id + '()' ;
1925 }
2026
27+ if ( this . def . fromParent === 'instanceof' ) {
28+ return 'instanceof ' + this . id ;
29+ }
30+
2131 return this . id ;
2232 }
2333
2434 testSelf ( ) {
25- let { memberType : type , memberKind : kind , base } = this ;
35+ let options = { } ;
2636
27- let interfaceName = base . id ;
28- let interfaceCallback = this . interface ?? base . interface ;
29- let context = { name : interfaceName , callback : interfaceCallback } ;
37+ let isInstanceOf = this . def . fromParent === 'instanceof' ;
38+ let memberType = this . memberType ;
3039
31- return supportsMember ( this . id , { type, kind, context} ) ;
40+ options . path = memberType === 'properties' || memberType === 'functions' ? '' : 'prototype' ;
41+ options . typeof = memberType === 'methods' || memberType === 'functions' ? 'function' : '' ;
42+ options . instanceof = isInstanceOf ? this . id : '' ;
43+ let member = isInstanceOf ? this . parent . id : this . id ;
44+ let base = this . base ;
45+ options . context = { name : base . id , callback : base . interface } ;
46+
47+ return supportsMember ( member , options ) ;
3248 }
3349}
3450
3551export default class InterfaceFeature extends Feature {
3652 static children = {
53+ /** @deprecated Alias of members */
3754 tests : { type : MemberFeature } ,
55+
56+ /** The object needs to be an instance of this class */
57+ instanceof : { type : InterfaceFeature } ,
58+
59+ /** The object should be a subclass of this class */
3860 extends : { type : InterfaceFeature } ,
39- members : { type : MemberFeature } ,
40- methods : { type : MemberFeature } ,
61+
62+ /** Properties that should exist on this object */
4163 properties : { type : MemberFeature } ,
64+
65+ /** Properties that should exist on this object and should be functions */
4266 functions : { type : MemberFeature } ,
67+
68+ /** Properties that should exist on this object's prototype */
69+ members : { type : MemberFeature } ,
70+
71+ /** Properties that should exist on this object's prototype and should be functions */
72+ methods : { type : MemberFeature } ,
4373 }
74+
4475 static gatingTest = true ;
4576
4677 constructor ( def , parent ) {
@@ -54,6 +85,10 @@ export default class InterfaceFeature extends Feature {
5485 return 'extends ' + this . id ;
5586 }
5687
88+ if ( this . def . fromParent === 'instanceof' ) {
89+ return 'instanceof ' + this . id ;
90+ }
91+
5792 return this . id ;
5893 }
5994
@@ -76,6 +111,13 @@ export default class InterfaceFeature extends Feature {
76111 return testExtends ( Class , SuperClass ) ;
77112 }
78113
114+ if ( this . def . fromParent === 'instanceof' ) {
115+ let Class = this . id ;
116+ let name = this . parent . id ;
117+
118+ return supportsInterface ( name , { instanceof : Class } ) ;
119+ }
120+
79121 return supportsInterface ( this . id ) ;
80122 }
81123}
0 commit comments