001: package kawa.lang;
002:
003: import gnu.bytecode.*;
004: import gnu.mapping.*;
005: import gnu.lists.*;
006:
007: public class RecordConstructor extends ProcedureN {
008: ClassType type;
009: Field[] fields;
010:
011: public RecordConstructor(ClassType type, Field[] fields) {
012: this .type = type;
013: this .fields = fields;
014: }
015:
016: public RecordConstructor(Class clas, Field[] fields) {
017: this ((ClassType) Type.make(clas), fields);
018: }
019:
020: public RecordConstructor(Class clas) {
021: init((ClassType) Type.make(clas));
022: }
023:
024: public RecordConstructor(ClassType type) {
025: init(type);
026: }
027:
028: private void init(ClassType type) {
029: this .type = type;
030: Field list = type.getFields();
031: int count = 0;
032: for (Field fld = list; fld != null; fld = fld.getNext()) {
033: if ((fld.getModifiers() & (Access.PUBLIC | Access.STATIC)) == Access.PUBLIC)
034: count++;
035: }
036: fields = new Field[count];
037: int i = 0;
038: for (Field fld = list; fld != null; fld = fld.getNext()) {
039: if ((fld.getModifiers() & (Access.PUBLIC | Access.STATIC)) == Access.PUBLIC)
040: fields[i++] = fld;
041: }
042: }
043:
044: public RecordConstructor(Class clas, Object fieldsList) {
045: this ((ClassType) Type.make(clas), fieldsList);
046: }
047:
048: public RecordConstructor(ClassType type, Object fieldsList) {
049: this .type = type;
050: if (fieldsList == null)
051: init(type);
052: else {
053: int nfields = LList.listLength(fieldsList, false);
054: this .fields = new Field[nfields];
055: Field list = type.getFields();
056: for (int i = 0; i < nfields; i++) {
057: Pair pair = (Pair) fieldsList;
058: String fname = pair.car.toString();
059: for (Field fld = list;; fld = fld.getNext()) {
060: if (fld == null)
061: throw new RuntimeException("no such field "
062: + fname + " in " + type.getName());
063: if (fld.getSourceName() == fname) {
064: this .fields[i] = fld;
065: break;
066: }
067: }
068: fieldsList = pair.cdr;
069: }
070: }
071: }
072:
073: public int numArgs() {
074: int nargs = fields.length;
075: return (nargs << 12) | nargs;
076: }
077:
078: public String getName() {
079: return type.getName() + " constructor";
080: }
081:
082: public Object applyN(Object[] args) {
083: Object obj;
084: try {
085: obj = type.getReflectClass().newInstance();
086: } catch (InstantiationException ex) {
087: throw new GenericError(ex.toString());
088: } catch (IllegalAccessException ex) {
089: throw new GenericError(ex.toString());
090: }
091: if (args.length != fields.length)
092: throw new WrongArguments(this , args.length);
093: for (int i = 0; i < args.length; i++) {
094: Field fld = fields[i];
095: try {
096: fld.getReflectField().set(obj, args[i]);
097: } catch (Exception ex) {
098: throw new WrappedException("illegal access for field "
099: + fld.getName(), ex);
100: }
101: }
102: return obj;
103: }
104: }
|