lean4-htt/src/frontends/lean/json.cpp
2018-09-11 13:55:25 -07:00

121 lines
3.7 KiB
C++

/*
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Gabriel Ebner
*/
#ifdef LEAN_JSON
#include "frontends/lean/json.h"
#include <string>
#include "library/protected.h"
#include "kernel/declaration.h"
#include "library/type_context.h"
#include "library/scoped_ext.h"
#include "kernel/instantiate.h"
#include "frontends/lean/pp.h"
#include "frontends/lean/util.h"
namespace lean {
json json_of_severity(message_severity sev) {
switch (sev) {
case INFORMATION: return "information";
case WARNING: return "warning";
case ERROR: return "error";
default: lean_unreachable();
}
}
json json_of_message(message const & msg) {
json j;
j["file_name"] = msg.get_filename();
j["pos_line"] = msg.get_pos().first;
j["pos_col"] = msg.get_pos().second;
if (auto end_pos = msg.get_end_pos()) {
j["end_pos_line"] = end_pos->first;
j["end_pos_col"] = end_pos->second;
}
j["severity"] = json_of_severity(msg.get_severity());
j["caption"] = msg.get_caption();
j["text"] = msg.get_text();
return j;
}
#define LEAN_COMPLETE_CONSUME_IMPLICIT true // lean will add metavariables for implicit arguments in serialize_decl()
void add_source_info(environment const & /* env */, name const & /* d */, json & /* record */) {
// if (auto olean = get_decl_olean(env, d))
// record["source"]["file"] = *olean;
// if (auto pos = get_decl_pos_info(env, d)) {
// record["source"]["line"] = pos->first;
// record["source"]["column"] = pos->second;
// }
}
json serialize_decl(name const & short_name, name const & long_name, environment const & env, options const & o) {
constant_info info = env.get(long_name);
type_context_old tc(env);
auto fmter = mk_pretty_formatter_factory()(env, o, tc);
expr type = info.get_type();
if (LEAN_COMPLETE_CONSUME_IMPLICIT) {
while (true) {
if (!is_pi(type))
break;
if (!is_implicit(binding_info(type)) && !is_inst_implicit(binding_info(type)))
break;
std::string q("?");
q += binding_name(type).to_string();
expr m = mk_constant(name(q.c_str()));
type = instantiate(binding_body(type), m);
}
}
json completion;
completion["text"] = short_name.to_string();
// interactive_report_type(env, o, type, completion);
add_source_info(env, long_name, completion);
return completion;
}
json serialize_decl(name const & d, environment const & env, options const & o) {
// using namespace override resolution rule
names const & ns_list = get_namespaces(env);
for (name const & ns : ns_list) {
name new_d = d.replace_prefix(ns, name());
if (new_d != d &&
!new_d.is_anonymous() &&
(!new_d.is_atomic() || !is_protected(env, d))) {
return serialize_decl(new_d, d, env, o);
}
}
// if the alias is unique use it
if (auto it = is_uniquely_aliased(env, d)) {
return serialize_decl(*it, d, env, o);
} else {
return serialize_decl(d, d, env, o);
}
}
json json_of_name(name const & n0) {
json j = json::array();
name n = n0;
while (!n.is_anonymous()) {
if (n.is_numeral()) {
j.push_back(n.get_numeral().get_small_value()); // HACK: it will crash if nat is not small
} else if (n.is_string()) {
j.push_back(n.get_string().to_std_string());
} else {
j.push_back(json());
}
n = n.get_prefix();
}
return j;
}
void print_json(std::ostream & out, message const & msg) {
out << json_of_message(msg) << std::endl;
}
}
#endif