121 lines
3.7 KiB
C++
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
|