1818import org .openzen .zenscript .codemodel .identifiers .instances .FieldInstance ;
1919import org .openzen .zenscript .codemodel .ssa .CodeBlockStatement ;
2020import org .openzen .zenscript .codemodel .ssa .SSAVariableCollector ;
21+ import org .openzen .zenscript .codemodel .type .ArrayTypeID ;
2122import org .openzen .zenscript .codemodel .type .TypeID ;
23+ import org .openzen .zenscript .codemodel .type .builtin .BuiltinMethodSymbol ;
2224import org .openzen .zenscript .javashared .JavaClass ;
2325import org .openzen .zenscript .javashared .JavaModifiers ;
2426import org .openzen .zenscript .javashared .JavaNativeField ;
2931import java .lang .reflect .Modifier ;
3032import java .util .*;
3133import java .util .stream .Collectors ;
34+ import java .util .stream .Stream ;
3235
3336public class JavaNativeTypeTemplate {
3437 protected final JavaRuntimeClass class_ ;
@@ -138,13 +141,16 @@ private void loadMethods() {
138141 for (Method method : class_ .cls .getMethods ()) {
139142 if (isNotAccessible (method ) || isOverridden (class_ .cls , method ))
140143 continue ;
144+
141145 if (expansion && !JavaModifiers .isStatic (method .getModifiers ()))
142146 continue ;
143147
144- Collection <MethodID > ids = new LinkedList <>();
145- boolean isStaticExpansion = false ;
148+ Collection <MethodID > ids = new LinkedHashSet <>(); // LinkedHashSet to prevent collision if a static method has both @Global and @Method
149+ boolean isStaticExpansionMethod = expansion && method .isAnnotationPresent (ZenCodeType .StaticExpansionMethod .class );
150+ boolean isStaticMethodInsideZc = (!expansion || isStaticExpansionMethod ) && JavaModifiers .isStatic (method .getModifiers ());
151+
146152 boolean implicit = false ;
147- boolean isStaticMethod = false ;
153+
148154 if (method .isAnnotationPresent (ZenCodeType .Operator .class )) {
149155 ZenCodeType .Operator operator = method .getAnnotation (ZenCodeType .Operator .class );
150156 MethodID id = MethodID .operator (OperatorType .valueOf (operator .value ().toString ()));
@@ -153,13 +159,13 @@ private void loadMethods() {
153159 if (method .isAnnotationPresent (ZenCodeType .Getter .class )) {
154160 ZenCodeType .Getter getter = method .getAnnotation (ZenCodeType .Getter .class );
155161 String name = getter .value ().isEmpty () ? method .getName () : getter .value ();
156- MethodID id = MethodID .getter (name );
162+ MethodID id = isStaticMethodInsideZc ? MethodID . staticGetter ( name ) : MethodID .getter (name );
157163 ids .add (id );
158164 }
159165 if (method .isAnnotationPresent (ZenCodeType .Setter .class )) {
160166 ZenCodeType .Setter setter = method .getAnnotation (ZenCodeType .Setter .class );
161167 String name = setter .value ().isEmpty () ? method .getName () : setter .value ();
162- MethodID id = MethodID .setter (name );
168+ MethodID id = isStaticMethodInsideZc ? MethodID . staticSetter ( name ) : MethodID .setter (name );
163169 ids .add (id );
164170 }
165171 if (method .isAnnotationPresent (ZenCodeType .Caster .class )) {
@@ -171,20 +177,17 @@ private void loadMethods() {
171177 if (method .isAnnotationPresent (ZenCodeType .Method .class )) {
172178 ZenCodeType .Method methodAnnotation = method .getAnnotation (ZenCodeType .Method .class );
173179 String name = methodAnnotation .value ().isEmpty () ? method .getName () : methodAnnotation .value ();
174- boolean hasStaticModifier = JavaModifiers .isStatic (method .getModifiers ());
175- MethodID id = hasStaticModifier && !expansion ? MethodID .staticMethod (name ) : MethodID .instanceMethod (name );
180+ MethodID id = isStaticMethodInsideZc ? MethodID .staticMethod (name ) : MethodID .instanceMethod (name );
176181 implicit |= methodAnnotation .implicit ();
177- isStaticMethod |= hasStaticModifier ;
178182 ids .add (id );
179183 }
180- if (expansion && method . isAnnotationPresent ( ZenCodeType . StaticExpansionMethod . class ) ) {
184+ if (isStaticExpansionMethod ) {
181185 ZenCodeType .StaticExpansionMethod methodAnnotation = method .getAnnotation (ZenCodeType .StaticExpansionMethod .class );
182186 String name = methodAnnotation .value ().isEmpty () ? method .getName () : methodAnnotation .value ();
183187 MethodID id = MethodID .staticMethod (name );
184188 ids .add (id );
185- isStaticExpansion = true ;
186189 }
187- if (! isStaticMethod && method .isAnnotationPresent (ZenCodeGlobals .Global .class ) && JavaModifiers . isStatic ( method . getModifiers () )) {
190+ if (isStaticMethodInsideZc && method .isAnnotationPresent (ZenCodeGlobals .Global .class )) {
188191 ZenCodeGlobals .Global methodAnnotation = method .getAnnotation (ZenCodeGlobals .Global .class );
189192 String name = methodAnnotation .value ().isEmpty () ? method .getName () : methodAnnotation .value ();
190193 MethodID id = MethodID .staticMethod (name );
@@ -194,18 +197,42 @@ private void loadMethods() {
194197 continue ;
195198
196199 FunctionHeader header = headerConverter .getHeader (typeVariableContext , method );
197-
198- if (expansion && !isStaticExpansion ) {
200+ if (expansion && !isStaticExpansionMethod ) {
199201 FunctionParameter [] withoutFirst = Arrays .copyOfRange (header .parameters , 1 , header .parameters .length );
200202 header = new FunctionHeader (header .typeParameters , header .getReturnType (), header .thrownType , withoutFirst );
201203 }
202204
203205 for (MethodID id : ids ) {
204- JavaRuntimeMethod runtimeMethod = new JavaRuntimeMethod (class_ , target , method , id , header , implicit , expansion && !isStaticExpansion );
206+ JavaRuntimeMethod runtimeMethod = new JavaRuntimeMethod (class_ , target , method , id , header , implicit , expansion && !isStaticExpansionMethod );
205207 methods .computeIfAbsent (id , x -> new ArrayList <>()).add (runtimeMethod );
206208 class_ .module .getCompiled ().setMethodInfo (runtimeMethod , runtimeMethod );
207209 }
208210 }
211+
212+
213+ if (class_ .cls .isEnum ()) {
214+ Stream .of (
215+ BuiltinMethodSymbol .ENUM_NAME ,
216+ BuiltinMethodSymbol .ENUM_ORDINAL ,
217+ //BuiltinMethodSymbol.ENUM_VALUES,
218+ BuiltinMethodSymbol .ENUM_COMPARE
219+ ).forEach (method -> methods
220+ .computeIfAbsent (method .getID (), x -> new ArrayList <>())
221+ .add (method )
222+ );
223+
224+ try {
225+ MethodID id = MethodID .staticGetter ("values" );
226+ FunctionHeader header = new FunctionHeader (new ArrayTypeID (target ));
227+ Method method = class_ .cls .getMethod ("values" );
228+ JavaRuntimeMethod runtimeMethod = new JavaRuntimeMethod (class_ , target , method , id , header , false , false );
229+ methods .computeIfAbsent (id , x -> new ArrayList <>()).add (runtimeMethod );
230+ class_ .module .getCompiled ().setMethodInfo (runtimeMethod , runtimeMethod );
231+ } catch (ReflectiveOperationException exception ) {
232+ throw new IllegalStateException ("We found an enum class without values() method: " + class_ .cls .getCanonicalName (), exception );
233+ }
234+
235+ }
209236 }
210237
211238 private void loadInnerTypes () {
0 commit comments