205 lines
5.2 KiB
Plaintext
205 lines
5.2 KiB
Plaintext
package slangc.model;
|
|
|
|
import slangc.api.Reporter;
|
|
import slangc.bytecode.FieldSignature;
|
|
import slangc.parser.Branch;
|
|
import slangc.parser.ErrorType;
|
|
import slangc.parser.Node;
|
|
import slangc.parser.NodeType;
|
|
|
|
public class FieldModel extends MemberModel implements ExpressionOwner, StorageSlot {
|
|
private Branch slotSource;
|
|
private TypeModel baseStorageType;
|
|
private ExpressionModel initialisation;
|
|
private LocalStorageModel upvalueReference;
|
|
private boolean isEnum = false;
|
|
|
|
public FieldModel(UserTypeModel owner, String name, Branch source, Branch slotSource) {
|
|
super(owner, name, source);
|
|
this.slotSource = slotSource;
|
|
baseStorageType = owner.resolveTypeReference(source.getSubnode(1));
|
|
//if (baseStorageType == null) {
|
|
// sourceFile.annotate(ErrorType.INTERNAL_ERROR, "Can't find storage type for field");
|
|
//}
|
|
if (hasInitialiser()) {
|
|
initialisation = ExpressionModel.construct(this, slotSource.getSubnode(2));
|
|
}
|
|
}
|
|
|
|
public FieldModel(UserTypeModel owner, String name, Branch source) {
|
|
super(owner, name, source);
|
|
isEnum = true;
|
|
}
|
|
|
|
public FieldModel(UserTypeModel owner, String name, LocalStorageModel upvalueReference) {
|
|
super(owner, name, null);
|
|
this.upvalueReference = upvalueReference;
|
|
baseStorageType = upvalueReference.getStorageType();
|
|
}
|
|
|
|
public Node getNameNode() {
|
|
return slotSource.getSubnode(0);
|
|
}
|
|
|
|
public String getName() {
|
|
if (isEnum) {
|
|
return super.getName();
|
|
}
|
|
if (upvalueReference != null) {
|
|
return upvalueReference.getName();
|
|
}
|
|
return UserTypeModel.plainName(getNameNode());
|
|
}
|
|
|
|
public int countAdditionalIndices() {
|
|
if (isUpvalue()) {
|
|
return 0;
|
|
}
|
|
Node n = getNameNode();
|
|
int i = 0;
|
|
while (n.getNodeType() == NodeType.INDEXED_NAME) {
|
|
n = ((Branch) n).getSubnode(0);
|
|
i++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
public TypeModel getStorageType() {
|
|
if (isEnum) {
|
|
return getOwner();
|
|
}
|
|
TypeModel effectiveType = baseStorageType;
|
|
if (effectiveType == null) {
|
|
return null;
|
|
}
|
|
for (int i = 0; i < countAdditionalIndices(); i++) {
|
|
effectiveType = effectiveType.getOrCreateArrayInstance();
|
|
}
|
|
return effectiveType;
|
|
}
|
|
|
|
@Override
|
|
public MemberCategory getCategory() {
|
|
return MemberCategory.FIELD;
|
|
}
|
|
|
|
public Branch getSlotSource() {
|
|
return slotSource;
|
|
}
|
|
|
|
public boolean hasInitialiser() {
|
|
if (isEnum) {
|
|
return false; // Kind of does have an initialiser but is treated specially.
|
|
}
|
|
if (isUpvalue()) {
|
|
return false; // Kind of does have an initialiser but is treated specially.
|
|
}
|
|
return getSlotSource().getNodeType() == NodeType.INITIALISED_SLOT;
|
|
}
|
|
|
|
//public TypeModel getStorageType() {
|
|
// return baseStorageType;
|
|
//}
|
|
|
|
public ExpressionModel getInitialisationExpression() {
|
|
return initialisation;
|
|
}
|
|
|
|
@Override
|
|
public void dump(Reporter reporter, String indent, String incr) {
|
|
super.dump(reporter, indent, incr);
|
|
if (baseStorageType != null) {
|
|
reporter.note("DUMP", indent + incr + "> Storage type is " + baseStorageType);
|
|
} else {
|
|
reporter.note("DUMP", "[no storage type information]");
|
|
}
|
|
if (hasInitialiser()) {
|
|
reporter.note("DUMP", indent + incr + "> Initialised with expression:");
|
|
initialisation.dump(reporter, indent + incr + incr, incr);
|
|
} else {
|
|
reporter.note("DUMP", indent + incr + "[this field is not initialised]");
|
|
}
|
|
}
|
|
|
|
//@Override
|
|
public TypeModel getExpectedResult(ExpressionModel e) {
|
|
return getStorageType();
|
|
}
|
|
|
|
//@Override
|
|
public InnerTypeScope getTypeScope() {
|
|
return getOwner();
|
|
}
|
|
|
|
//@Override
|
|
public TypeModel resolveType(Node typeReference) {
|
|
return ((UserTypeModel)getOwner()).resolveTypeReference(typeReference);
|
|
}
|
|
|
|
//@Override
|
|
public MemberModel getMethodOrField() {
|
|
return this;
|
|
}
|
|
|
|
//@Override
|
|
public StorageSlot.Kind getSlotKind() {
|
|
if (isStatic()) {
|
|
return StorageSlot.Kind.STATIC_FIELD;
|
|
} else {
|
|
return StorageSlot.Kind.INSTANCE_FIELD;
|
|
}
|
|
}
|
|
|
|
//@Override
|
|
public Named lookupSimpleName(String name) {
|
|
return getOwner().lookupSimpleName(name);
|
|
}
|
|
|
|
//@Override
|
|
public MethodModel[] lookupSimpleMethod(String name) {
|
|
return getOwner().lookupSimpleMethod(name);
|
|
}
|
|
|
|
@Override
|
|
public int resolveExpressions() {
|
|
if (hasInitialiser()) {
|
|
return getInitialisationExpression().resolveExpressions();
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isStatic() {
|
|
if (isEnum) { // Enum fields are always static
|
|
return true;
|
|
}
|
|
// Interface fields are assumed to be static
|
|
if (getOwner().getTypeType() == TypeType.INTERFACE || getOwner().getTypeType() == TypeType.INTERFACE_TEMPLATE) {
|
|
return true;
|
|
}
|
|
return super.isStatic();
|
|
}
|
|
|
|
public boolean isEnumField() {
|
|
return isEnum;
|
|
}
|
|
|
|
public boolean isUpvalue() {
|
|
return upvalueReference != null;
|
|
}
|
|
|
|
public LocalStorageModel getUpvalueReference() {
|
|
return upvalueReference;
|
|
}
|
|
|
|
@Override
|
|
public int getFlags() {
|
|
return super.getFlags() | (isUpvalue() ? (Flags.MASK_UPVALUE | Flags.MASK_SYNTHETIC | Flags.MASK_FINAL) : 0);
|
|
}
|
|
|
|
public FieldSignature getFieldSignature() {
|
|
return new FieldSignature(getOwner().getTypeSignature(), isStatic(), getStorageType().getTypeSignature(), getName());
|
|
}
|
|
}
|