package slangc.model; import slangc.api.Reporter; import slangc.parser.Branch; import slangc.parser.ErrorType; import slangc.parser.Node; import slangc.parser.NodeType; /** * This is the base type used both for method parameters and (other/temporary) local variables. * These are typically accessed the same way at runtime (offset from the stack base of the * invoked method), so the same rules usually apply and they can usually be handled the same way. * * @author Zak * */ public abstract class LocalStorageModel implements StorageSlot { MethodModel owner; int index; Branch source; private TypeModel baseStorageType; public LocalStorageModel(MethodModel owner, int index, Branch source, TypeModel assignedType) { this.owner = owner; this.index = index; this.source = source; if (assignedType == null) { if (source.getSubnode(1) == null) { source.annotate(ErrorType.MISSING_PART, "Can't find type information!"); } else { //baseStorageType = ((UserTypeModel)owner.getOwner()).resolveTypeReference(sourceFile.getSubnode(1)); } } else { baseStorageType = assignedType; } } public abstract Node getNameNode(); public String getName() { return UserTypeModel.plainName(getNameNode()); } public int countAdditionalIndices() { Node n = getNameNode(); int i = 0; while (n.getNodeType() == NodeType.INDEXED_NAME) { n = ((Branch) n).getSubnode(0); i++; } return i; } public TypeModel getStorageType() { TypeModel effectiveType = baseStorageType; if (effectiveType == null) { return null; } for (int i = 0; i < countAdditionalIndices(); i++) { effectiveType = effectiveType.getOrCreateArrayInstance(); } return effectiveType; } public void dump(Reporter reporter, String indent, String incr) { reporter.note("DUMP", indent + "> '" + getName() + "', storage type " + getStorageType()); } public int getIndex() { return index; } }