001: package bsh;
002:
003: public class Variable implements java.io.Serializable {
004: static final int DECLARATION = 0, ASSIGNMENT = 1;
005: /** A null type means an untyped variable */
006: String name;
007: Class type = null;
008: String typeDescriptor;
009: Object value;
010: Modifiers modifiers;
011: LHS lhs;
012:
013: Variable(String name, Class type, LHS lhs) {
014: this .name = name;
015: this .lhs = lhs;
016: this .type = type;
017: }
018:
019: Variable(String name, Object value, Modifiers modifiers)
020: throws UtilEvalError {
021: this (name, (Class) null/*type*/, value, modifiers);
022: }
023:
024: /**
025: This constructor is used in class generation.
026: */
027: Variable(String name, String typeDescriptor, Object value,
028: Modifiers modifiers) throws UtilEvalError {
029: this (name, (Class) null/*type*/, value, modifiers);
030: this .typeDescriptor = typeDescriptor;
031: }
032:
033: /**
034: @param value may be null if this
035: */
036: Variable(String name, Class type, Object value, Modifiers modifiers)
037: throws UtilEvalError {
038:
039: this .name = name;
040: this .type = type;
041: this .modifiers = modifiers;
042: setValue(value, DECLARATION);
043: }
044:
045: /**
046: Set the value of the typed variable.
047: @param value should be an object or wrapped bsh Primitive type.
048: if value is null the appropriate default value will be set for the
049: type: e.g. false for boolean, zero for integer types.
050: */
051: public void setValue(Object value, int context)
052: throws UtilEvalError {
053:
054: // check this.value
055: if (hasModifier("final") && this .value != null)
056: throw new UtilEvalError("Final variable, can't re-assign.");
057:
058: if (value == null)
059: value = Primitive.getDefaultValue(type);
060:
061: if (lhs != null) {
062: lhs.assign(Primitive.unwrap(value), false/*strictjava*/);
063: return;
064: }
065:
066: // TODO: should add isJavaCastable() test for strictJava
067: // (as opposed to isJavaAssignable())
068: if (type != null)
069: value = Types.castObject(value, type,
070: context == DECLARATION ? Types.CAST
071: : Types.ASSIGNMENT);
072:
073: this .value = value;
074: }
075:
076: /*
077: Note: UtilEvalError here comes from lhs.getValue().
078: A Variable can represent an LHS for the case of an imported class or
079: object field.
080: */
081: Object getValue() throws UtilEvalError {
082: if (lhs != null)
083: return type == null ? lhs.getValue() : Primitive.wrap(lhs
084: .getValue(), type);
085:
086: return value;
087: }
088:
089: /** A type of null means loosely typed variable */
090: public Class getType() {
091: return type;
092: }
093:
094: public String getTypeDescriptor() {
095: return typeDescriptor;
096: }
097:
098: public Modifiers getModifiers() {
099: return modifiers;
100: }
101:
102: public String getName() {
103: return name;
104: }
105:
106: public boolean hasModifier(String name) {
107: return modifiers != null && modifiers.hasModifier(name);
108: }
109:
110: public String toString() {
111: return "Variable: " + super .toString() + " " + name + ", type:"
112: + type + ", value:" + value + ", lhs = " + lhs;
113: }
114: }
|