public <U extends IValue, V extends IValue> Result<U> fieldUpdate(String name, Result<V> repl, TypeStore store) {
if (!getType().hasField(name, store) && !getValue().getConstructorType().hasKeywordParameter(name)) {
throw new UndeclaredField(name, getType(), ctx.getCurrentAST());
}
Type nodeType = getValue().getConstructorType();
if (!nodeType.hasField(name) && !nodeType.hasKeywordParameter(name)) {
throw RuntimeExceptionFactory.noSuchField(name, ctx.getCurrentAST(), null);
}
if (nodeType.hasKeywordParameter(name)) {
Type fieldType = nodeType.getKeywordParameterType(name);
if (!repl.getType().isSubtypeOf(fieldType)) {
throw new UnexpectedType(fieldType, repl.getType(), ctx.getCurrentAST());
}
return makeResult(getType(), getValue().asWithKeywordParameters().setParameter(name, repl.getValue()), ctx);
}
else {
int index = nodeType.getFieldIndex(name);
Type fieldType = nodeType.getFieldType(index);
if (!repl.getType().isSubtypeOf(fieldType)) {
throw new UnexpectedType(fieldType, repl.getType(), ctx.getCurrentAST());
}
return makeResult(getType(), getValue().set(index, repl.getValue()), ctx);