TypeEnvironment implements Environment<Symbol, ExprType> { @Override public ExprType resolve(Symbol symbol) { for (TypeEnvironment cur = this; cur != null; cur = cur.parent) { Optional<ExprType> typeOptional = cur.symbolTable.lookup(symbol); if (typeOptional.isPresent()) { return typeOptional.get(); } } throw new SemanticCheckException( String.format("can't resolve %s in type env", symbol)); } TypeEnvironment(TypeEnvironment parent);  TypeEnvironment(TypeEnvironment parent, SymbolTable symbolTable); @Override ExprType resolve(Symbol symbol); Map<String, ExprType> lookupAllFields(Namespace namespace); void define(Symbol symbol, ExprType type); void define(ReferenceExpression ref); void remove(Symbol symbol); void remove(ReferenceExpression ref);  }
@Test public void resolveLiteralInEnvFailed() { SemanticCheckException exception = assertThrows(SemanticCheckException.class, () -> environment().resolve(new Symbol(Namespace.FIELD_NAME, "1"))); assertEquals("can't resolve Symbol(namespace=FIELD_NAME, name=1) in type env", exception.getMessage()); }