Skip to content

Commit

Permalink
TypeScript 4.6.3, JSX, and quality of life changes
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveBeeblebrox committed Apr 14, 2022
1 parent 7fd2b60 commit 12101c2
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 21 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
/target
/.mtsc
test.js
/src/typescriptServices.js
*.js
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mtsc"
version = "4.4.4"
version = "4.6.3"
edition = "2018"
authors = ["S. Beeblebrox"] # <[email protected]>
license = "MIT"
Expand Down
79 changes: 67 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use clap::{Arg, App};
use std::convert::TryFrom;
use std::io::prelude::*;
use std::path::PathBuf;
use std::path::Path;
use std::fs::File;
use std::fs;

Expand Down Expand Up @@ -34,11 +35,29 @@ fn main() {
.takes_value(true)
)

.arg(Arg::with_name("jsx")
.short("x")
.long("jsx")
.value_name("JSX")
.help("Sets the JSX factory for compiled code (When this option is set but blank or when the file extension is .tsx, JSX is preserved as is; otherwise, it is interpreted as standard code)")
.default_value("")
.takes_value(true)
)

.arg(Arg::with_name("jsx-fragment")
.long("jsx-fragment")
.value_name("JSX-FRAGMENT")
.help("Sets the JSX fragment for compiled code (Requires the jsx option to be set as well)")
.default_value("null")
.takes_value(true)
)

.arg(Arg::with_name("output")
.short("o")
.long("out")
.value_name("OUTPUT")
.help("Sets the output file to write transpiled code to (Leave blank to write to the console)")
.help("Sets the output file to write transpiled code to instead of using the input file's name with the extension changed to .js (When set but blank, output is written to stdout; if set to a directory and an input file is provided, the output file will be written to the given directory with the extension changed to .js)")
.default_value("")
.takes_value(true)
)

Expand All @@ -48,30 +67,35 @@ fn main() {
)
.get_matches();

let (input_file, input_text) = match matches.value_of("INPUT") {
Some(value) => (Some(String::from(value)), fs::read_to_string(value).expect("Error reading target file")),
let (input_file, input_text, input_type) = match matches.value_of("INPUT") {
Some(value) => (Some(String::from(value)), fs::read_to_string(value).expect("Error reading target file"), Path::new(value).extension().expect("Error getting file extension").to_str().expect("Error getting file extension").to_string()),
None => {
let stdin = io::stdin();
let mut stdin = stdin.lock();
let mut line = String::new();

stdin.read_to_string(&mut line).expect("Error reading stdin");
(None, String::from(line))
(None, String::from(line), String::from(""))
}
};

let (use_jsx, jsx_factory, jsx_fragment) = match matches.value_of("jsx") {
Some("") if matches.occurrences_of("jsx") > 0 => (if matches.occurrences_of("jsx") > 0 {true} else {false}, None, None),
None | Some("") => (input_type == "tsx", None, None),
Some(value) => (true, Some(String::from(value)), Some(String::from(matches.value_of("jsx-fragment").unwrap()))),
};

let result = compile_typescript(input_text.as_str(), CompileOptions {
target: String::from(matches.value_of("target").unwrap()),
module: String::from(matches.value_of("module").unwrap())
module: String::from(matches.value_of("module").unwrap()),
use_jsx,
jsx_factory,
jsx_fragment
}).expect("Error compiling TypeScript");

match matches.value_of("output") {
Some("") => print!("{}", result.as_str()),
Some(path) => {
let mut file = File::create(path).expect("Error creating output file");
file.write_all(result.as_bytes()).expect("Error writing to output file");
},
None => {
Some("") if matches.occurrences_of("output") > 0 => print!("{}", result.as_str()),
None | Some("") => {
match input_file {
Some(input_file) => {
let mut path = PathBuf::from(input_file);
Expand All @@ -82,12 +106,28 @@ fn main() {
None => print!("{}", result.as_str())
}
}
Some(path) => {
let path = if Path::new(path).exists() && fs::metadata(path).expect("Error reading file metadata").is_dir() && input_file.is_some() {
let mut path = PathBuf::from(path);
path.push(Path::new(&input_file.unwrap().to_string()).file_name().expect("Error getting file name").to_str().expect("Error getting file name"));
path.set_extension("js");
path
} else {
PathBuf::from(path)
};

let mut file = File::create(path).expect("Error creating output file");
file.write_all(result.as_bytes()).expect("Error writing to output file");
}
}
}

struct CompileOptions {
target: String,
module: String
module: String,
use_jsx: bool,
jsx_factory: Option<String>,
jsx_fragment: Option<String>
}

fn compile_typescript(text: &str, options: CompileOptions) -> Option<String> {
Expand Down Expand Up @@ -125,6 +165,21 @@ fn compile_typescript(text: &str, options: CompileOptions) -> Option<String> {
let module_prop_value = v8::String::new(scope, options.module.as_str())?.into();
args.set(scope, module_prop_name, module_prop_value);

if options.use_jsx {
let jsx_factory_prop_name = v8::String::new(scope, "jsx")?.into();
let jsx_factory_prop_value = v8::String::new(scope, if options.jsx_factory.is_some() {"react"} else {"preserve"})?.into();
args.set(scope, jsx_factory_prop_name, jsx_factory_prop_value);

if options.jsx_factory.is_some() {
let jsx_factory_prop_name = v8::String::new(scope, "jsxFactory")?.into();
let jsx_factory_prop_value = v8::String::new(scope, options.jsx_factory.unwrap().as_str())?.into();
args.set(scope, jsx_factory_prop_name, jsx_factory_prop_value);

let jsx_fragment_prop_name = v8::String::new(scope, "jsxFragmentFactory")?.into();
let jsx_fragment_prop_value = v8::String::new(scope, options.jsx_fragment.unwrap().as_str())?.into();
args.set(scope, jsx_fragment_prop_name, jsx_fragment_prop_value);
}
}

return Some(transpile_function.call(scope, ts_obj, &[text, args.into()])?.to_string(scope)?
.to_rust_string_lossy(scope))
Expand Down
8 changes: 4 additions & 4 deletions test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
type MyNumber = number
const x: MyNumber = 1;
type NumberLike = number | string
const x: NumberLike = '7';
function doStuff(...args: string[]): boolean {
return true;
}
return +x === 7;
}
4 changes: 4 additions & 0 deletions test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let content = <>
<h1>Hello</h1>
<p>World</p>
</>

0 comments on commit 12101c2

Please sign in to comment.