use crate::context::*;
use go_parser::ast::*;
use go_parser::{AstObjects, IdentKey, Map, Token};
use go_types::{check::TypeInfo, ObjKey as TCObjKey, PackageKey as TCPackageKey, TCObjects};
use go_vm::types::*;
use go_vm::FfiCtx;
use std::rc::Rc;
pub(crate) struct PkgHelper<'a> {
tc_objs: &'a TCObjects,
ast_objs: &'a AstObjects,
pkg_map: &'a Map<TCPackageKey, PackageKey>,
}
impl<'a> PkgHelper<'a> {
pub fn new(
ast_objs: &'a AstObjects,
tc_objs: &'a TCObjects,
pkg_map: &'a Map<TCPackageKey, PackageKey>,
) -> PkgHelper<'a> {
PkgHelper {
tc_objs,
ast_objs,
pkg_map,
}
}
pub fn gen_imports(&self, tcpkg: TCPackageKey, fctx: &mut FuncCtx) {
let pkg = &self.tc_objs.pkgs[tcpkg];
let unsafe_ = self.tc_objs.universe().unsafe_pkg();
for tckey in pkg.imports().iter() {
if tckey != unsafe_ {
let key = self.pkg_map[tckey];
fctx.emit_import(key, None);
}
}
}
pub fn get_runtime_key(&self, tcpkg: TCPackageKey) -> PackageKey {
self.pkg_map[&tcpkg]
}
pub fn get_member_index(
&self,
fctx: &mut FuncCtx,
okey: TCObjKey,
ident: IdentKey,
) -> VirtualAddr {
let tc_pkg = self.tc_objs.lobjs[okey].pkg().unwrap();
let pkg = self.get_runtime_key(tc_pkg);
let pkg_addr = fctx.add_comparable(FfiCtx::new_package(pkg));
let index_addr = Addr::PkgMemberIndex(pkg, ident);
VirtualAddr::PackageMember(pkg_addr, index_addr)
}
pub fn sort_var_decls(
&self,
files: &Vec<File>,
ti: &TypeInfo,
) -> (Vec<IdentKey>, Vec<Rc<ValueSpec>>) {
let mut orders = Map::new();
for (i, init) in ti.init_order.iter().enumerate() {
for okey in init.lhs.iter() {
let name = self.tc_objs.lobjs[*okey].name();
orders.insert(name, i);
}
}
let mut names = vec![];
let mut decls = vec![];
for f in files.iter() {
for d in f.decls.iter() {
match d {
Decl::Gen(gdecl) => {
for spec_key in gdecl.specs.iter() {
if gdecl.token == Token::VAR {
let spec = &self.ast_objs.specs[*spec_key];
match spec {
Spec::Value(v) => {
names.extend(v.names.iter());
let name = &self.ast_objs.idents[v.names[0]].name;
if let Some(order) = orders.get(name) {
decls.push((v.clone(), order));
}
}
_ => unimplemented!(),
}
}
}
}
_ => {}
}
}
}
decls.sort_by(|a, b| a.1.cmp(&b.1));
(names, decls.into_iter().map(|x| x.0).collect())
}
}