9
9
import com .heinthanth .uit .Utils .TypeMapper ;
10
10
11
11
public class UitClass implements UitCallable {
12
- final String name ;
13
-
12
+ public final String name ;
13
+ private final UitClass parent ;
14
14
private final Map <String , Token > accessModifier ;
15
15
private final Map <String , Object > properties ;
16
16
private final Map <String , UitFunction > methods ;
17
17
18
- public UitClass (String name , Map <String , Object > props , Map <String , UitFunction > methods ,
18
+ public UitClass (String name , UitClass parent , Map <String , Object > props , Map <String , UitFunction > methods ,
19
19
Map <String , Token > accessModifier ) {
20
20
this .name = name ;
21
+ this .parent = parent ;
21
22
this .properties = props ;
22
23
this .methods = methods ;
23
24
this .accessModifier = accessModifier ;
24
25
}
25
26
26
- public Object findProp (Token member , boolean fromThis ) {
27
+ public Object findProp (Token member , boolean fromThis , boolean fromChild ) {
27
28
if (properties .containsKey (member .lexeme )) {
28
29
Token am = accessModifier .get (member .lexeme );
29
- if (fromThis || am .type == token_t .PUBLIC ) {
30
+ if ((fromChild && (am .type == token_t .PUBLIC || am .type == token_t .PROTECTED ))
31
+ || (!fromChild && (fromThis || am .type == token_t .PUBLIC ))) {
30
32
return properties .get (member .lexeme );
31
33
} else {
32
- throw new RuntimeError (am , "Cannot access '" + am .lexeme + "' member outside of class." );
34
+ throw new RuntimeError (am , "Cannot access '" + am .lexeme + "' member outside of '" + name + "' class." );
33
35
}
34
36
}
37
+ if (parent != null ) {
38
+ return parent .findProp (member , fromThis , true );
39
+ }
35
40
return null ;
36
-
37
41
}
38
42
39
- public UitFunction findMethod (Token member , boolean fromThis ) {
43
+ public UitFunction findMethod (Token member , boolean fromThis , boolean fromChild ) {
40
44
if (methods .containsKey (member .lexeme )) {
41
45
Token am = accessModifier .get (member .lexeme );
42
- if (fromThis || am .type == token_t .PUBLIC ) {
46
+ if ((fromChild && (am .type == token_t .PUBLIC || am .type == token_t .PROTECTED ))
47
+ || (!fromChild && (fromThis || am .type == token_t .PUBLIC ))) {
43
48
return methods .get (member .lexeme );
44
49
} else {
45
- throw new RuntimeError (am , "Cannot access '" + am .lexeme + "' member outside of class." );
50
+ throw new RuntimeError (am , "Cannot access '" + am .lexeme + "' member outside of '" + name + "' class." );
46
51
}
47
52
}
53
+ if (parent != null ) {
54
+ return parent .findMethod (member , fromThis , true );
55
+ }
48
56
return null ;
49
57
}
50
58
51
- public void setProp (Token member , Object value , boolean fromThis ) {
59
+ public void setProp (Token member , Object value , boolean fromThis , boolean fromChild ) {
52
60
if (properties .containsKey (member .lexeme )) {
53
61
Token am = accessModifier .get (member .lexeme );
54
- if (fromThis || am .type == token_t .PUBLIC ) {
62
+ if ((fromChild && (am .type == token_t .PUBLIC || am .type == token_t .PROTECTED ))
63
+ || (!fromChild && (fromThis || am .type == token_t .PUBLIC ))) {
55
64
Object old = properties .get (member .lexeme );
56
65
if (value .getClass () == old .getClass ()) {
57
66
properties .put (member .lexeme , value );
@@ -67,20 +76,24 @@ public void setProp(Token member, Object value, boolean fromThis) {
67
76
throw new RuntimeError (member , msg .toString ());
68
77
}
69
78
} else {
70
- throw new RuntimeError (am , "Cannot access '" + am .lexeme + "' member outside of class." );
79
+ throw new RuntimeError (am , "Cannot access '" + am .lexeme + "' member outside of '" + name + "' class." );
71
80
}
72
81
} else if (methods .containsKey (member .lexeme )) {
73
82
throw new RuntimeError (member , "Cannot re-assign method '" + member .lexeme + "'." );
74
83
} else {
75
- throw new RuntimeError (member , "No member named '" + member .lexeme + "' in '" + name + "' class." );
84
+ if (parent != null ) {
85
+ parent .setProp (member , value , fromThis , true );
86
+ } else {
87
+ throw new RuntimeError (member , "No member named '" + member .lexeme + "' in '" + name + "' class." );
88
+ }
76
89
}
77
90
}
78
91
79
92
@ Override
80
93
public Object invoke (Interpreter interpreter , List <Object > arguments ) {
81
94
UitInstance instance = new UitInstance (this );
82
- UitFunction initializer = findMethod (new Token (token_t .IDENTIFIER , "__construct" , -1 , -1 ), true );
83
- if (initializer .declaration .type .type != token_t .FRT_VOID )
95
+ UitFunction initializer = findMethod (new Token (token_t .IDENTIFIER , "__construct" , -1 , -1 ), true , false );
96
+ if (initializer != null && initializer .declaration .type .type != token_t .FRT_VOID )
84
97
throw new RuntimeError (initializer .declaration .type , "Object constructor must be void method." );
85
98
if (initializer != null ) {
86
99
initializer .bind (instance ).invoke (interpreter , arguments );
@@ -90,7 +103,7 @@ public Object invoke(Interpreter interpreter, List<Object> arguments) {
90
103
91
104
@ Override
92
105
public int argsCount () {
93
- UitFunction initializer = findMethod (new Token (token_t .IDENTIFIER , "__construct" , -1 , -1 ), true );
106
+ UitFunction initializer = findMethod (new Token (token_t .IDENTIFIER , "__construct" , -1 , -1 ), true , false );
94
107
if (initializer == null )
95
108
return 0 ;
96
109
return initializer .argsCount ();
0 commit comments