package slangc.model; import slangc.api.Reporter; import slangc.model.clauses.*; import slangc.parser.Branch; import slangc.parser.Node; import slangc.parser.NodeType; /** * A "clause" is basically used for any substatement/subexpression which can't be interpreted * as a statement or expression by itself. * *
There are still some subexpressions which may work more like a clause (not producing a normal * expression result but only helping to resolve an outer expression), but in ambiguous cases these * are treated as normal expressions rather than clauses * (particularly subreferences like "x.y", which could refer to a field "y" within a local variable * "x", or to a class "y" within package "x", or to a package "x.y" from which the class "x.y.Z" can * be resolved in an outer subreference - but since this might just be a simple expression referring * to a field it's stored in an ExpressionModel instead). * * @author Zak * */ public abstract class ClauseModel { private StatementOwner owner; private Node source; public ClauseModel(StatementOwner owner, Node source) { this.owner = owner; this.source = source; } public StatementOwner getOwner() { return owner; } public Node getSource() { return source; } public static ClauseModel construct(StatementOwner owner, Node source) { switch (source.getNodeType()) { case NodeType.NO_ELSE_CLAUSE: case NodeType.NO_FINALLY_CLAUSE: return null; case NodeType.CATCH_CLAUSE: return new CatchClause(owner, (Branch)source); case NodeType.FINALLY_CLAUSE: return new FinallyClause(owner, (Branch)source); case NodeType.ELSE_CLAUSE: return new ElseClause(owner, (Branch)source); case NodeType.ARRAY_EXPRESSIONS: case NodeType.EXPRESSIONS: return new Expressions((ExpressionOwner)owner, (Branch)source); case NodeType.ARGUMENTS: return new Arguments((ExpressionOwner)owner, (Branch)source); case NodeType.SIMPLE_ARGUMENT_DECLARATION: case NodeType.FOR_VARIABLES: return new Variables(owner, (Branch) source); case NodeType.SWITCH_MEMBERS: return new SwitchMembers(owner, (Branch) source); default: Log.line("Unrecognised clause is type " + source.getNodeType()); return new UnrecognisedClause(owner, source); } } public static ClauseModel[] constructMultiple(StatementOwner owner, Branch source) { ClauseModel[] result = new ClauseModel[source.countSubnodes()]; for (int i = 0; i < result.length; i++) { result[i] = construct(owner, source.getSubnode(i)); } return result; } public void dump(Reporter reporter, String indent, String incr) { reporter.note("DUMP", indent + incr + "TODO: dump " + Type.of(this)); } public Named lookupSimpleName(String name) { return getOwner().lookupSimpleName(name); } public MethodModel[] lookupSimpleMethod(String name) { return getOwner().lookupSimpleMethod(name); } public abstract int resolveExpressions(); }