ObjectExpression.java
package org.sterling.runtime.expression;
import static java.util.Collections.sort;
import static org.sterling.runtime.expression.ExpressionConversions.convertSymbol;
import static org.sterling.runtime.expression.ExpressionFactory.declaration;
import static org.sterling.runtime.expression.ExpressionFactory.member;
import static org.sterling.util.StringUtil.stringify;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import org.sterling.SterlingException;
public class ObjectExpression extends Expression {
private final Map<Symbol, Expression> members;
public ObjectExpression(Set<DeclaredExpression> members) {
Map<Symbol, Expression> map = new HashMap<>();
for (DeclaredExpression declaration : members) {
map.put(declaration.getSymbol(), declaration.getExpression());
}
this.members = new ConcurrentHashMap<>(map);
}
@Override
public <R, D> R accept(ExpressionVisitor<R, D> visitor, D data) throws SterlingException {
return visitor.visitObjectExpression(this, data);
}
@Override
public Expression access(Expression member) throws SterlingException {
Symbol symbol = convertSymbol(member);
if (members.containsKey(symbol)) {
return member(this, members.get(symbol));
} else {
return super.access(symbol);
}
}
@Override
public boolean equals(Object o) {
return o == this || o instanceof ObjectExpression && members.equals(((ObjectExpression) o).members);
}
public Set<DeclaredExpression> getMembers() {
Set<DeclaredExpression> declarations = new HashSet<>();
for (Symbol symbol : members.keySet()) {
declarations.add(declaration(symbol, members.get(symbol)));
}
return declarations;
}
@Override
public int hashCode() {
return Objects.hash(members);
}
@Override
public String toString() {
List<DeclaredExpression> declarations = new ArrayList<>();
for (Symbol symbol : members.keySet()) {
declarations.add(declaration(symbol, members.get(symbol)));
}
sort(declarations, new DeclarationComparator());
return stringify(this, declarations);
}
private static final class DeclarationComparator implements Comparator<DeclaredExpression> {
@Override
public int compare(DeclaredExpression o1, DeclaredExpression o2) {
return o1.getSymbol().getValue().compareTo(o2.getSymbol().getValue());
}
}
}