@Override public <U extends IValue, V extends IValue> Result<U> fieldUpdate( String name, Result<V> repl, TypeStore store) { IConstructor tree = getValue(); if (TreeAdapter.isAppl(tree)) { int found = -1; IConstructor foundType = null; IConstructor prod = TreeAdapter.getProduction(tree); IList syms = ProductionAdapter.getSymbols(prod); // TODO: find deeper into optionals, alternatives and sequences checking the actual arguments // for presence/absence of optional trees. for (int i = 0; i < syms.length(); i++) { IConstructor sym = (IConstructor) syms.get(i); if (SymbolAdapter.isLabel(sym)) { if (SymbolAdapter.getLabel(sym).equals(name)) { found = i; foundType = SymbolAdapter.delabel(sym); break; } } } if (found != -1) { Type nont = RascalTypeFactory.getInstance().nonTerminalType(foundType); if (repl.getType().isSubtypeOf(nont)) { IList args = TreeAdapter.getArgs(tree).put(found, repl.getValue()); return makeResult(getType(), tree.set("args", args), ctx); } throw new UnexpectedType(nont, repl.getType(), ctx.getCurrentAST()); } if (Factory.Tree_Appl.hasField(name)) { Type fieldType = Factory.Tree_Appl.getFieldType(name); if (repl.getType().isSubtypeOf(fieldType)) { throw new UnsupportedOperation( "changing " + name + " in concrete tree", ctx.getCurrentAST()); } throw new UnexpectedType(fieldType, repl.getType(), ctx.getCurrentAST()); } throw RuntimeExceptionFactory.noSuchField(name, ctx.getCurrentAST(), ctx.getStackTrace()); } throw new UnsupportedOperation("field update", ctx.getCurrentAST()); }
@Override public <U extends IValue> Result<U> fieldAccess(String name, TypeStore store) { IConstructor tree = getValue(); if (TreeAdapter.isAppl(tree)) { int found = -1; IConstructor foundType = null; IConstructor prod = TreeAdapter.getProduction(tree); if (!ProductionAdapter.isRegular(prod)) { IList syms = ProductionAdapter.getSymbols(prod); // TODO: find deeper into optionals, checking the actual arguments for presence/absence of // optional trees. for (int i = 0; i < syms.length(); i++) { IConstructor sym = (IConstructor) syms.get(i); while (SymbolAdapter.isConditional(sym)) { sym = SymbolAdapter.getSymbol(sym); } if (SymbolAdapter.isLabel(sym)) { if (SymbolAdapter.getLabel(sym).equals(name)) { found = i; foundType = SymbolAdapter.delabel(sym); } } } if (found != -1) { Type nont = RascalTypeFactory.getInstance().nonTerminalType(foundType); IValue child = TreeAdapter.getArgs(tree).get(found); return makeResult(nont, child, ctx); } } } if (tree.getConstructorType().hasField(name)) { return makeResult(tree.getConstructorType().getFieldType(name), tree.get(name), ctx); } throw RuntimeExceptionFactory.noSuchField(name, ctx.getCurrentAST(), ctx.getStackTrace()); }