From 036354179ed73a2e60e63d2efa664ddd7ab93550 Mon Sep 17 00:00:00 2001 From: Gary Miller Date: Tue, 18 Apr 2023 21:11:06 +1000 Subject: [PATCH] simple npm packge import --- adl/adlc/adlc/config/typescript.adl | 3 + adl/tests/test31/lib/common/flyway/api.adl | 3 + .../test31/lib/common/flyway/internals.adl | 3 + rust/compiler/src/cli/tsgen/generate.rs | 63 ++++++++++++++----- rust/compiler/src/cli/tsgen/mod.rs | 3 +- 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/adl/adlc/adlc/config/typescript.adl b/adl/adlc/adlc/config/typescript.adl index 78081f8b..b1aeca63 100644 --- a/adl/adlc/adlc/config/typescript.adl +++ b/adl/adlc/adlc/config/typescript.adl @@ -1,5 +1,8 @@ module adlc.config.typescript { +/// ADL module annotation to specify a target npm package this module belongs to. +type NpmPackage = String; + /// ADL module or declaration annotation to control /// whether code is actually generated. diff --git a/adl/tests/test31/lib/common/flyway/api.adl b/adl/tests/test31/lib/common/flyway/api.adl index d1ad8c40..94f9cbb9 100644 --- a/adl/tests/test31/lib/common/flyway/api.adl +++ b/adl/tests/test31/lib/common/flyway/api.adl @@ -1,5 +1,8 @@ +@NpmPackage "@adl-lang/common" module common.flyway.api { +import adlc.config.typescript.*; + import common.flyway.internals.FlywayAction; import common.flyway.internals.FlywayContext; import common.http.HttpPost; diff --git a/adl/tests/test31/lib/common/flyway/internals.adl b/adl/tests/test31/lib/common/flyway/internals.adl index 64d13279..36259f91 100644 --- a/adl/tests/test31/lib/common/flyway/internals.adl +++ b/adl/tests/test31/lib/common/flyway/internals.adl @@ -1,5 +1,8 @@ +@NpmPackage "@adl-lang/common" module common.flyway.internals { +import adlc.config.typescript.*; + struct FlywayCommand { FlywayContext ctx; /// The action to take on application startup diff --git a/rust/compiler/src/cli/tsgen/generate.rs b/rust/compiler/src/cli/tsgen/generate.rs index 9f626c69..f6b92919 100644 --- a/rust/compiler/src/cli/tsgen/generate.rs +++ b/rust/compiler/src/cli/tsgen/generate.rs @@ -8,8 +8,8 @@ use genco::prelude::*; use genco::tokens::{Item, ItemStr}; use crate::adlgen::sys::adlast2::{ - DeclType, NewType, PrimitiveType, ScopedName, TypeDef, - TypeExpr, TypeRef, Annotations, Module1, Decl1, Struct1, Union1 + Annotations, Decl1, DeclType, Module1, NewType, PrimitiveType, ScopedName, Struct1, TypeDef, + TypeExpr, TypeRef, Union1, }; use crate::cli::TsOpts; use crate::parser::docstring_scoped_name; @@ -19,6 +19,7 @@ const SP: &str = " "; const SQ: &str = "'"; pub struct TsGenVisitor<'a> { + pub npm_pkg: &'a Option, pub module: &'a Module1, pub resolver: &'a Resolver, pub adlr: JsImport, @@ -37,18 +38,14 @@ struct RttiPayload<'a> { } impl TsGenVisitor<'_> { - pub fn gen_module( - &mut self, - t: &mut Tokens, - m: &Module1, - ) -> anyhow::Result<()> { + pub fn gen_module(&mut self, t: &mut Tokens) -> anyhow::Result<()> { quote_in! { *t => - $("/* @generated from adl module") $(m.name.clone()) $("*/") + $("/* @generated from adl module") $(self.module.name.clone()) $("*/") $['\n'] }; - self.gen_doc_comment(t, &m.annotations)?; - let mname = &m.name; - for decl in m.decls.iter() { + self.gen_doc_comment(t, &self.module.annotations)?; + let mname = &self.module.name; + for decl in self.module.decls.iter() { let payload = DeclPayload { decl: decl, mname: &mname.clone(), @@ -67,13 +64,13 @@ impl TsGenVisitor<'_> { t, "export const _AST_MAP: { [key: string]: ADL.ScopedDecl } = {\n", ); - m.decls.iter().fold(false, |rest, decl| { + self.module.decls.iter().fold(false, |rest, decl| { if rest { lit(t, ",\n") } lit(t, " "); quote_in! { *t => - $("\"")$(m.name.clone()).$(&decl.name)$("\"") : $(cap_opt(&decl.name, self.opts))_AST + $("\"")$(self.module.name.clone()).$(&decl.name)$("\"") : $(cap_opt(&decl.name, self.opts))_AST }; true }); @@ -330,9 +327,37 @@ impl TsGenVisitor<'_> { scoped_name: &ScopedName, params: &Vec>, ) -> Result<(bool, String), String> { + let npm_pkg2 = if let Some(m2) = self.resolver.get_module(&scoped_name.module_name) { + get_npm_pkg(m2) + } else { + None + }; + let npm_pkg = get_npm_pkg(self.module); let imp = self.map.entry(scoped_name.clone()).or_insert_with(|| { - let path = - crate::cli::tsgen::utils::rel_import(&self.module.name, &scoped_name.module_name); + let path = if npm_pkg2 != None && npm_pkg2 != npm_pkg { + let npm_pkg2 = npm_pkg2.unwrap(); + let mn_parts: Vec<&str> = scoped_name.module_name.split(".").collect(); + let npm_parts: Vec<&str> = npm_pkg2.rsplit("/").collect(); + let mut mn = mn_parts.iter().peekable(); + let mut npm = npm_parts.iter().peekable(); + while let (Some(m), Some(n)) = (&mn.peek(), &npm.peek()) { + if m != n { + break; + } + mn.next(); npm.next(); + } + let mut path = npm_pkg2; + path.push_str("/"); + while let Some(p) = mn.next() { + path.push_str(p); + if let Some(_) = mn.peek() { + path.push_str("/"); + } + } + path + } else { + crate::cli::tsgen::utils::rel_import(&self.module.name, &scoped_name.module_name) + }; let i_name = scoped_name .module_name .replace(".", "_") @@ -486,6 +511,14 @@ impl TsGenVisitor<'_> { } } +fn get_npm_pkg(module: &Module1) -> Option { + let npm_pkg = module.annotations.0.get(&ScopedName { + module_name: "adlc.config.typescript".to_string(), + name: "NpmPackage".to_string(), + }); + npm_pkg.map(|p| p.as_str().unwrap().to_string()) +} + fn lit(t: &mut Tokens, s: &'static str) { t.append(Item::Literal(ItemStr::Static(s))); } diff --git a/rust/compiler/src/cli/tsgen/mod.rs b/rust/compiler/src/cli/tsgen/mod.rs index 36fce667..d6e52c5c 100644 --- a/rust/compiler/src/cli/tsgen/mod.rs +++ b/rust/compiler/src/cli/tsgen/mod.rs @@ -137,12 +137,13 @@ fn gen_ts_module(m: &Module1, resolver: &Resolver, opts: &TsOpts) -> anyhow::Res }; let mut mgen = generate::TsGenVisitor { module: m, + npm_pkg: &None, resolver: resolver, adlr, map: &mut HashMap::new(), opts, }; - mgen.gen_module(tokens, m)?; + mgen.gen_module(tokens)?; // let stdout = std::io::stdout(); let mut w = fmt::IoWriter::new(Vec::::new()); // let mut w = fmt::IoWriter::new(stdout.lock());