]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaStaticField.java
(refs #7866) Better error location for the NPE in compilation
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / JavaStaticField.java
1 package org.simantics.scl.compiler.constants;
2
3 import java.lang.reflect.Field;
4
5 import org.cojen.classfile.TypeDesc;
6 import org.objectweb.asm.Label;
7 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
8 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
9 import org.simantics.scl.compiler.internal.codegen.references.IVal;
10 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
11 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
12 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
13 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
14 import org.simantics.scl.compiler.runtime.MutableClassLoader;
15 import org.simantics.scl.compiler.types.Type;
16
17 public class JavaStaticField extends Constant {
18     
19     String className;
20     String fieldName;
21     
22     TypeDesc fieldType;
23     Type effect;
24     
25     int constructorTag;
26     
27     public JavaStaticField(String className, String fieldName, Type effect, TypeDesc fieldType, Type type, int constructorTag) {
28         super(type);        
29         this.className = className;
30         this.fieldName = fieldName;
31         this.fieldType = fieldType;
32         this.effect = effect;
33         this.constructorTag = constructorTag;
34     }
35     
36     public JavaStaticField(String className, String fieldName, Type type, int constructorTag) {
37         this(className, fieldName, null, null, type, constructorTag);
38     }
39     
40     @Override
41     public void push(MethodBuilder mb) {
42         if(fieldType == null) {
43             JavaTypeTranslator tt = mb.getJavaTypeTranslator();
44             fieldType = tt.toTypeDesc(getType());
45         }
46         
47         mb.loadStaticField(className, fieldName, fieldType);
48     }
49
50     public String getClassName() {
51                 return className;
52         }
53     
54     public String getFieldName() {
55                 return fieldName;
56         }
57
58     @Override
59     public Object realizeValue(TransientClassBuilder classBuilder) {
60         MutableClassLoader classLoader = classBuilder.classLoader;
61         try {
62             Class<?> clazz = classLoader.loadClass(className.replace('/', '.'));
63             Field field = clazz.getDeclaredField(fieldName);
64             return field.get(null);
65         } catch (IllegalArgumentException e) {
66             throw new InternalCompilerError(e);
67         } catch (IllegalAccessException e) {
68             throw new InternalCompilerError(e);
69         } catch (ClassNotFoundException e) {
70             throw new InternalCompilerError(e);
71         } catch (SecurityException e) {
72             throw new InternalCompilerError(e);
73         } catch (NoSuchFieldException e) {
74             throw new InternalCompilerError(e);
75         }
76     }
77     
78     @Override
79     public void deconstruct(MethodBuilder mb, IVal parameter, Cont success,
80             Label failure) {
81         push(mb);
82         mb.push(parameter, getType());
83         mb.invokeVirtual(TypeDesc.OBJECT, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
84         mb.ifZeroComparisonBranch(failure, "==");
85         mb.jump(success);
86     }
87     
88     public int constructorTag() {
89         return constructorTag;
90     }
91     
92     @Override
93     public String toString() {
94         return "JavaStaticField(" + className + "." + fieldName +")";
95     }
96 }