Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(compiler): add platform agnostic interface for wasm targets #414

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libs/wingc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ serde_json = "1.0"
colored = "2.0"
lazy_static = "1.4.0"
globset = "0.4.9"
wasm-bindgen = "0.2.83"

[lib]
path = "src/lib.rs"
Expand Down
7 changes: 4 additions & 3 deletions libs/wingc/src/jsify.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{fs, path::PathBuf};
use crate::platform::*;
use std::path::PathBuf;

use sha2::{Digest, Sha256};

Expand Down Expand Up @@ -452,10 +453,10 @@ fn jsify_inflight_function(func_def: &FunctionDefinition, out_dir: &PathBuf) ->
block
));
let proc_dir = format!("{}/proc.{}", out_dir.to_string_lossy(), procid);
fs::create_dir_all(&proc_dir).expect("Creating inflight proc dir");
Platform::ensure_directory(&proc_dir).expect("Creating inflight proc dir");
let file_path = format!("{}/index.js", proc_dir);
let relative_file_path = format!("proc.{}/index.js", procid);
fs::write(&file_path, proc_source.join("\n")).expect("Writing inflight proc source");
Platform::write_file(&file_path, proc_source.join("\n").as_str()).expect("Writing inflight proc source");
let props_block = render_block([
format!(
"code: {}.core.NodeJsCode.fromFile(require('path').resolve(__dirname, \"{}\")),",
Expand Down
9 changes: 5 additions & 4 deletions libs/wingc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::parser::bring;
use ast::Scope;
use diagnostic::{print_diagnostics, DiagnosticLevel, Diagnostics};

use platform::*;
use std::collections::HashSet;
use std::fs;
use std::path::PathBuf;

use crate::ast::Flight;
Expand All @@ -15,11 +15,12 @@ use crate::type_check::type_env::TypeEnv;
use crate::type_check::{TypeChecker, Types};

pub mod ast;
pub mod debug;
pub mod capture;
pub mod debug;
pub mod diagnostic;
pub mod jsify;
pub mod parser;
pub mod platform;
pub mod type_check;

pub fn type_check(scope: &mut Scope, types: &mut Types) -> Diagnostics {
Expand Down Expand Up @@ -66,12 +67,12 @@ pub fn compile(source_file: &str, out_dir: Option<&str>) -> String {

// prepare output directory for support inflight code
let out_dir = PathBuf::from(&out_dir.unwrap_or(format!("{}.out", source_file).as_str()));
fs::create_dir_all(&out_dir).expect("create output dir");
Platform::ensure_directory(&out_dir.to_str().unwrap()).expect("create output dir");

let intermediate_js = jsify::jsify(&scope, &out_dir, true);
let intermediate_name = std::env::var("WINGC_PREFLIGHT").unwrap_or("preflight.js".to_string());
let intermediate_file = out_dir.join(intermediate_name);
fs::write(&intermediate_file, &intermediate_js).expect("Write intermediate JS to disk");
Platform::write_file(&intermediate_file.to_str().unwrap(), &intermediate_js).expect("Write intermediate JS to disk");

return intermediate_js;
}
Expand Down
14 changes: 5 additions & 9 deletions libs/wingc/src/parser/bring.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use crate::platform::*;
use crate::Diagnostics;
use crate::Scope;

use crate::parser::Parser;
use std::cell::RefCell;
use std::collections::HashSet;
use std::fs;
use std::path::PathBuf;

pub fn bring(source_file: &str, context: Option<&str>, imports: &mut HashSet<String>) -> Option<(Scope, Diagnostics)> {
// default context directory to the current directory
let context_dir = PathBuf::from(&context.unwrap_or("."));
// turn "source_file" into a canonical path relative to context_dir
let source_file = context_dir.join(source_file).canonicalize().unwrap();
let source_file = source_file.to_str().unwrap();
let source_file = Platform::canonicalize_path(&context_dir.join(source_file).to_str().unwrap());
let source_file = source_file.as_str();

if imports.contains(source_file) {
return None;
Expand All @@ -22,12 +22,8 @@ pub fn bring(source_file: &str, context: Option<&str>, imports: &mut HashSet<Str
let mut parser = tree_sitter::Parser::new();
parser.set_language(language).unwrap();

let source = match fs::read(&source_file) {
Ok(source) => source,
Err(err) => {
panic!("Error reading source file: {}: {:?}", &source_file, err);
}
};
let source = Platform::read_file(source_file).expect("Unable to read file");
let source = source.as_bytes();

let tree = match parser.parse(&source[..], None) {
Some(tree) => tree,
Expand Down
18 changes: 18 additions & 0 deletions libs/wingc/src/platform.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use std::io::Result;

pub trait PlatformBase {
fn canonicalize_path(path: &str) -> String;
fn read_file(path: &str) -> Result<String>;
fn write_file(path: &str, content: &str) -> Result<()>;
fn ensure_directory(path: &str) -> Result<()>;
}

#[cfg(not(target_family="wasm"))]
mod native;
#[cfg(not(target_family="wasm"))]
pub use native::Platform;

#[cfg(target_family="wasm")]
mod node;
#[cfg(target_family="wasm")]
pub use node::Platform;
27 changes: 27 additions & 0 deletions libs/wingc/src/platform/native.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use super::PlatformBase;
use std::io::Result;
use std::{fs, path::PathBuf};

pub struct Platform {
// empty
}

impl PlatformBase for Platform {
fn canonicalize_path(path: &str) -> String {
let mut path = PathBuf::from(path);
path = path.canonicalize().unwrap();
path.to_str().unwrap().to_string()
}

fn read_file(path: &str) -> Result<String> {
fs::read_to_string(path)
}

fn write_file(path: &str, content: &str) -> Result<()> {
fs::write(path, content)
}

fn ensure_directory(path: &str) -> Result<()> {
fs::create_dir_all(path)
}
}
42 changes: 42 additions & 0 deletions libs/wingc/src/platform/node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use super::PlatformBase;
use std::io::Result;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = platform)]
pub fn wingc_platform_canonicalize_path(path: &str) -> String;

#[wasm_bindgen(js_namespace = platform)]
pub fn wingc_platform_read_file(path: &str) -> String;

#[wasm_bindgen(js_namespace = platform)]
pub fn wingc_platform_write_file(path: &str, content: &str);

#[wasm_bindgen(js_namespace = platform)]
pub fn wingc_platform_ensure_directory(path: &str);
}

pub struct Platform {
// empty
}

impl PlatformBase for Platform {
fn canonicalize_path(path: &str) -> String {
wingc_platform_canonicalize_path(path)
}

fn read_file(path: &str) -> Result<String> {
Ok(wingc_platform_read_file(path))
}

fn write_file(path: &str, content: &str) -> Result<()> {
wingc_platform_write_file(path, content);
Ok(()) // error handling happens in JS side with exceptions
}

fn ensure_directory(path: &str) -> Result<()> {
wingc_platform_ensure_directory(path);
Ok(()) // error handling happens in JS side with exceptions
}
}