conditional base classes

This commit is contained in:
Ryan O'Neill 2015-08-11 14:36:10 -07:00
parent 1d45880311
commit 48ecd996e8
5 changed files with 35 additions and 23 deletions

View File

@ -20,15 +20,17 @@ public class ConfigConditional {
} }
} }
public SimpleConfigObject resolve(Map<String, AbstractConfigValue> values) { public SimpleConfigObject resolve(ResolveContext context, ResolveSource source) {
AbstractConfigValue val = values.get(left.path().first()); try {
if (val == null) { AbstractConfigValue val = source.lookupSubst(context, this.left, 0).result.value;
throw new ConfigException.BugOrBroken("Could not resolve substitution " + this.left.toString() + " in conditional expression");
} if (val.equals(this.right)) {
if (val.equals(this.right)) { return this.body;
return this.body; } else {
} else { return SimpleConfigObject.empty();
return null; }
} catch (AbstractConfigValue.NotPossibleToResolve e){
throw new ConfigException.BugOrBroken("Could not resolve left side of conditional expression: " + this.left.toString());
} }
} }
} }

View File

@ -338,7 +338,7 @@ final class ConfigParser {
} }
} }
return new SimpleConfigObject(objectOrigin, values); return new SimpleConfigObject(objectOrigin, values, conditionals);
} }
private SimpleConfigList parseArray(ConfigNodeArray n) { private SimpleConfigList parseArray(ConfigNodeArray n) {

View File

@ -12,11 +12,13 @@ enum ResolveStatus {
UNRESOLVED, RESOLVED; UNRESOLVED, RESOLVED;
final static ResolveStatus fromValues( final static ResolveStatus fromValues(
Collection<? extends AbstractConfigValue> values) { Collection<? extends AbstractConfigValue> values, Collection<ConfigConditional> conditionals) {
for (AbstractConfigValue v : values) { for (AbstractConfigValue v : values) {
if (v.resolveStatus() == ResolveStatus.UNRESOLVED) if (v.resolveStatus() == ResolveStatus.UNRESOLVED)
return ResolveStatus.UNRESOLVED; return ResolveStatus.UNRESOLVED;
} }
if (conditionals.size() > 0)
return ResolveStatus.UNRESOLVED;
return ResolveStatus.RESOLVED; return ResolveStatus.RESOLVED;
} }

View File

@ -26,8 +26,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
final private boolean resolved; final private boolean resolved;
SimpleConfigList(ConfigOrigin origin, List<AbstractConfigValue> value) { SimpleConfigList(ConfigOrigin origin, List<AbstractConfigValue> value) {
this(origin, value, ResolveStatus this(origin, value, ResolveStatus.fromValues(value, new ArrayList<ConfigConditional>()));
.fromValues(value));
} }
SimpleConfigList(ConfigOrigin origin, List<AbstractConfigValue> value, SimpleConfigList(ConfigOrigin origin, List<AbstractConfigValue> value,
@ -37,7 +36,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
this.resolved = status == ResolveStatus.RESOLVED; this.resolved = status == ResolveStatus.RESOLVED;
// kind of an expensive debug check (makes this constructor pointless) // kind of an expensive debug check (makes this constructor pointless)
if (status != ResolveStatus.fromValues(value)) if (status != ResolveStatus.fromValues(value, new ArrayList<ConfigConditional>()))
throw new ConfigException.BugOrBroken( throw new ConfigException.BugOrBroken(
"SimpleConfigList created with wrong resolve status: " + this); "SimpleConfigList created with wrong resolve status: " + this);
} }

View File

@ -47,7 +47,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
this.conditionals = conditionals; this.conditionals = conditionals;
// Kind of an expensive debug check. Comment out? // Kind of an expensive debug check. Comment out?
if (status != ResolveStatus.fromValues(value.values())) if (status != ResolveStatus.fromValues(value.values(), conditionals))
throw new ConfigException.BugOrBroken("Wrong resolved status on " + this); throw new ConfigException.BugOrBroken("Wrong resolved status on " + this);
} }
@ -60,13 +60,13 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
SimpleConfigObject(ConfigOrigin origin, SimpleConfigObject(ConfigOrigin origin,
Map<String, AbstractConfigValue> value) { Map<String, AbstractConfigValue> value) {
this(origin, value, ResolveStatus.fromValues(value.values()), false /* ignoresFallbacks */, new ArrayList<ConfigConditional>()); this(origin, value, ResolveStatus.fromValues(value.values(), new ArrayList<ConfigConditional>()), false /* ignoresFallbacks */, new ArrayList<ConfigConditional>());
} }
SimpleConfigObject(ConfigOrigin origin, SimpleConfigObject(ConfigOrigin origin,
Map<String, AbstractConfigValue> value, Map<String, AbstractConfigValue> value,
List<ConfigConditional> conditionals) { List<ConfigConditional> conditionals) {
this(origin, value, ResolveStatus.fromValues(value.values()), false /* ignoresFallbacks */, conditionals); this(origin, value, ResolveStatus.fromValues(value.values(), conditionals), false /* ignoresFallbacks */, conditionals);
} }
@Override @Override
@ -131,8 +131,8 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
Map<String, AbstractConfigValue> updated = new HashMap<String, AbstractConfigValue>( Map<String, AbstractConfigValue> updated = new HashMap<String, AbstractConfigValue>(
value); value);
updated.put(key, v); updated.put(key, v);
return new SimpleConfigObject(origin(), updated, ResolveStatus.fromValues(updated return new SimpleConfigObject(origin(), updated,
.values()), ignoresFallbacks); ResolveStatus.fromValues(updated.values(), conditionals), ignoresFallbacks);
} else if (next != null || v == null) { } else if (next != null || v == null) {
// can't descend, nothing to remove // can't descend, nothing to remove
return this; return this;
@ -143,8 +143,8 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
if (!old.getKey().equals(key)) if (!old.getKey().equals(key))
smaller.put(old.getKey(), old.getValue()); smaller.put(old.getKey(), old.getValue());
} }
return new SimpleConfigObject(origin(), smaller, ResolveStatus.fromValues(smaller return new SimpleConfigObject(origin(), smaller,
.values()), ignoresFallbacks); ResolveStatus.fromValues(smaller.values(), conditionals), ignoresFallbacks);
} }
} }
@ -162,7 +162,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
newMap.put(key, (AbstractConfigValue) v); newMap.put(key, (AbstractConfigValue) v);
} }
return new SimpleConfigObject(origin(), newMap, ResolveStatus.fromValues(newMap.values()), return new SimpleConfigObject(origin(), newMap, ResolveStatus.fromValues(newMap.values(), conditionals),
ignoresFallbacks); ignoresFallbacks);
} }
@ -225,7 +225,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
else else
newChildren.remove(old.getKey()); newChildren.remove(old.getKey());
return new SimpleConfigObject(origin(), newChildren, ResolveStatus.fromValues(newChildren.values()), return new SimpleConfigObject(origin(), newChildren, ResolveStatus.fromValues(newChildren.values(), conditionals),
ignoresFallbacks); ignoresFallbacks);
} }
} }
@ -322,6 +322,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
private SimpleConfigObject modifyMayThrow(Modifier modifier) throws Exception { private SimpleConfigObject modifyMayThrow(Modifier modifier) throws Exception {
Map<String, AbstractConfigValue> changes = null; Map<String, AbstractConfigValue> changes = null;
for (String k : keySet()) { for (String k : keySet()) {
AbstractConfigValue v = value.get(k); AbstractConfigValue v = value.get(k);
// "modified" may be null, which means remove the child; // "modified" may be null, which means remove the child;
@ -413,6 +414,14 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
ResolveModifier modifier = new ResolveModifier(context, sourceWithParent); ResolveModifier modifier = new ResolveModifier(context, sourceWithParent);
AbstractConfigValue value = modifyMayThrow(modifier); AbstractConfigValue value = modifyMayThrow(modifier);
for (ConfigConditional cond: this.conditionals) {
SimpleConfigObject body = cond.resolve(context, sourceWithParent);
AbstractConfigObject resolvedBody = body.resolveSubstitutions(context, source).value;
value = this.mergedWithObject(resolvedBody);
}
this.conditionals.clear();
return ResolveResult.make(modifier.context, value).asObjectResult(); return ResolveResult.make(modifier.context, value).asObjectResult();
} catch (NotPossibleToResolve e) { } catch (NotPossibleToResolve e) {
throw e; throw e;