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) {
AbstractConfigValue val = values.get(left.path().first());
if (val == null) {
throw new ConfigException.BugOrBroken("Could not resolve substitution " + this.left.toString() + " in conditional expression");
}
if (val.equals(this.right)) {
return this.body;
} else {
return null;
public SimpleConfigObject resolve(ResolveContext context, ResolveSource source) {
try {
AbstractConfigValue val = source.lookupSubst(context, this.left, 0).result.value;
if (val.equals(this.right)) {
return this.body;
} else {
return SimpleConfigObject.empty();
}
} 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) {

View File

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

View File

@ -26,8 +26,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
final private boolean resolved;
SimpleConfigList(ConfigOrigin origin, List<AbstractConfigValue> value) {
this(origin, value, ResolveStatus
.fromValues(value));
this(origin, value, ResolveStatus.fromValues(value, new ArrayList<ConfigConditional>()));
}
SimpleConfigList(ConfigOrigin origin, List<AbstractConfigValue> value,
@ -37,7 +36,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
this.resolved = status == ResolveStatus.RESOLVED;
// 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(
"SimpleConfigList created with wrong resolve status: " + this);
}

View File

@ -47,7 +47,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
this.conditionals = conditionals;
// 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);
}
@ -60,13 +60,13 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
SimpleConfigObject(ConfigOrigin origin,
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,
Map<String, AbstractConfigValue> value,
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
@ -131,8 +131,8 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
Map<String, AbstractConfigValue> updated = new HashMap<String, AbstractConfigValue>(
value);
updated.put(key, v);
return new SimpleConfigObject(origin(), updated, ResolveStatus.fromValues(updated
.values()), ignoresFallbacks);
return new SimpleConfigObject(origin(), updated,
ResolveStatus.fromValues(updated.values(), conditionals), ignoresFallbacks);
} else if (next != null || v == null) {
// can't descend, nothing to remove
return this;
@ -143,8 +143,8 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
if (!old.getKey().equals(key))
smaller.put(old.getKey(), old.getValue());
}
return new SimpleConfigObject(origin(), smaller, ResolveStatus.fromValues(smaller
.values()), ignoresFallbacks);
return new SimpleConfigObject(origin(), smaller,
ResolveStatus.fromValues(smaller.values(), conditionals), ignoresFallbacks);
}
}
@ -162,7 +162,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
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);
}
@ -225,7 +225,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
else
newChildren.remove(old.getKey());
return new SimpleConfigObject(origin(), newChildren, ResolveStatus.fromValues(newChildren.values()),
return new SimpleConfigObject(origin(), newChildren, ResolveStatus.fromValues(newChildren.values(), conditionals),
ignoresFallbacks);
}
}
@ -322,6 +322,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
private SimpleConfigObject modifyMayThrow(Modifier modifier) throws Exception {
Map<String, AbstractConfigValue> changes = null;
for (String k : keySet()) {
AbstractConfigValue v = value.get(k);
// "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);
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();
} catch (NotPossibleToResolve e) {
throw e;