Skip to content

Commit

Permalink
refactor(cli): add tsc2 (#7942)
Browse files Browse the repository at this point in the history
Ref #7225
  • Loading branch information
kitsonk authored Oct 13, 2020
1 parent 374d433 commit 10654fa
Show file tree
Hide file tree
Showing 15 changed files with 877 additions and 80 deletions.
23 changes: 20 additions & 3 deletions cli/checksum.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

pub fn gen(v: &[&[u8]]) -> String {
let mut ctx = ring::digest::Context::new(&ring::digest::SHA256);
use ring::digest::Context;
use ring::digest::SHA256;

pub fn gen(v: &[impl AsRef<[u8]>]) -> String {
let mut ctx = Context::new(&SHA256);
for src in v {
ctx.update(src);
ctx.update(src.as_ref());
}
let digest = ctx.finish();
let out: Vec<String> = digest
Expand All @@ -13,3 +16,17 @@ pub fn gen(v: &[&[u8]]) -> String {
.collect();
out.join("")
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_gen() {
let actual = gen(&[b"hello world"]);
assert_eq!(
actual,
"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
);
}
}
30 changes: 15 additions & 15 deletions cli/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fn format_message(msg: &str, code: &u64) -> String {
}
}

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum DiagnosticCategory {
Warning,
Error,
Expand Down Expand Up @@ -172,7 +172,7 @@ impl From<i64> for DiagnosticCategory {
}
}

#[derive(Debug, Deserialize, Clone)]
#[derive(Debug, Deserialize, Clone, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticMessageChain {
message_text: String,
Expand All @@ -199,26 +199,26 @@ impl DiagnosticMessageChain {
}
}

#[derive(Debug, Deserialize, Clone)]
#[derive(Debug, Deserialize, Clone, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Position {
pub line: u64,
pub character: u64,
}

#[derive(Debug, Deserialize, Clone)]
#[derive(Debug, Deserialize, Clone, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Diagnostic {
category: DiagnosticCategory,
code: u64,
start: Option<Position>,
end: Option<Position>,
message_text: Option<String>,
message_chain: Option<DiagnosticMessageChain>,
source: Option<String>,
source_line: Option<String>,
file_name: Option<String>,
related_information: Option<Vec<Diagnostic>>,
pub category: DiagnosticCategory,
pub code: u64,
pub start: Option<Position>,
pub end: Option<Position>,
pub message_text: Option<String>,
pub message_chain: Option<DiagnosticMessageChain>,
pub source: Option<String>,
pub source_line: Option<String>,
pub file_name: Option<String>,
pub related_information: Option<Vec<Diagnostic>>,
}

impl Diagnostic {
Expand Down Expand Up @@ -346,7 +346,7 @@ impl fmt::Display for Diagnostic {
}
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Diagnostics(pub Vec<Diagnostic>);

impl<'de> Deserialize<'de> for Diagnostics {
Expand Down
2 changes: 1 addition & 1 deletion cli/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn compiler_snapshot() {
.execute(
"<anon>",
r#"
if (!(bootstrapCompilerRuntime)) {
if (!(startup)) {
throw Error("bad");
}
console.log(`ts version: ${ts.version}`);
Expand Down
1 change: 1 addition & 0 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ mod test_runner;
mod text_encoding;
mod tokio_util;
mod tsc;
pub mod tsc2;
mod tsc_config;
mod upgrade;
mod version;
Expand Down
72 changes: 67 additions & 5 deletions cli/media_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::path::PathBuf;
// Update carefully!
#[allow(non_camel_case_types)]
#[repr(i32)]
#[derive(Clone, Copy, PartialEq, Debug)]
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum MediaType {
JavaScript = 0,
JSX = 1,
Expand All @@ -19,7 +19,9 @@ pub enum MediaType {
TSX = 4,
Json = 5,
Wasm = 6,
Unknown = 8,
TsBuildInfo = 7,
SourceMap = 8,
Unknown = 9,
}

impl fmt::Display for MediaType {
Expand All @@ -32,6 +34,8 @@ impl fmt::Display for MediaType {
MediaType::TSX => "TSX",
MediaType::Json => "Json",
MediaType::Wasm => "Wasm",
MediaType::TsBuildInfo => "TsBuildInfo",
MediaType::SourceMap => "SourceMap",
MediaType::Unknown => "Unknown",
};
write!(f, "{}", value)
Expand All @@ -56,10 +60,22 @@ impl<'a> From<&'a String> for MediaType {
}
}

impl Default for MediaType {
fn default() -> Self {
MediaType::Unknown
}
}

impl MediaType {
fn from_path(path: &Path) -> Self {
match path.extension() {
None => MediaType::Unknown,
None => match path.file_name() {
None => MediaType::Unknown,
Some(os_str) => match os_str.to_str() {
Some(".tsbuildinfo") => MediaType::TsBuildInfo,
_ => MediaType::Unknown,
},
},
Some(os_str) => match os_str.to_str() {
Some("ts") => MediaType::TypeScript,
Some("tsx") => MediaType::TSX,
Expand All @@ -69,10 +85,42 @@ impl MediaType {
Some("cjs") => MediaType::JavaScript,
Some("json") => MediaType::Json,
Some("wasm") => MediaType::Wasm,
Some("tsbuildinfo") => MediaType::TsBuildInfo,
Some("map") => MediaType::SourceMap,
_ => MediaType::Unknown,
},
}
}

/// Convert a MediaType to a `ts.Extension`.
///
/// *NOTE* This is defined in TypeScript as a string based enum. Changes to
/// that enum in TypeScript should be reflected here.
pub fn as_ts_extension(&self) -> String {
let ext = match self {
MediaType::JavaScript => ".js",
MediaType::JSX => ".jsx",
MediaType::TypeScript => ".ts",
MediaType::Dts => ".d.ts",
MediaType::TSX => ".tsx",
MediaType::Json => ".json",
// TypeScript doesn't have an "unknown", so we will treat WASM as JS for
// mapping purposes, though in reality, it is unlikely to ever be passed
// to the compiler.
MediaType::Wasm => ".js",
MediaType::TsBuildInfo => ".tsbuildinfo",
// TypeScript doesn't have an "source map", so we will treat SourceMap as
// JS for mapping purposes, though in reality, it is unlikely to ever be
// passed to the compiler.
MediaType::SourceMap => ".js",
// TypeScript doesn't have an "unknown", so we will treat WASM as JS for
// mapping purposes, though in reality, it is unlikely to ever be passed
// to the compiler.
MediaType::Unknown => ".js",
};

ext.into()
}
}

impl Serialize for MediaType {
Expand All @@ -88,7 +136,9 @@ impl Serialize for MediaType {
MediaType::TSX => 4 as i32,
MediaType::Json => 5 as i32,
MediaType::Wasm => 6 as i32,
MediaType::Unknown => 8 as i32,
MediaType::TsBuildInfo => 7 as i32,
MediaType::SourceMap => 8 as i32,
MediaType::Unknown => 9 as i32,
};
Serialize::serialize(&value, serializer)
}
Expand Down Expand Up @@ -132,6 +182,14 @@ mod tests {
MediaType::from(Path::new("foo/bar.cjs")),
MediaType::JavaScript
);
assert_eq!(
MediaType::from(Path::new("foo/.tsbuildinfo")),
MediaType::TsBuildInfo
);
assert_eq!(
MediaType::from(Path::new("foo/bar.js.map")),
MediaType::SourceMap
);
assert_eq!(
MediaType::from(Path::new("foo/bar.txt")),
MediaType::Unknown
Expand All @@ -148,7 +206,9 @@ mod tests {
assert_eq!(json!(MediaType::TSX), json!(4));
assert_eq!(json!(MediaType::Json), json!(5));
assert_eq!(json!(MediaType::Wasm), json!(6));
assert_eq!(json!(MediaType::Unknown), json!(8));
assert_eq!(json!(MediaType::TsBuildInfo), json!(7));
assert_eq!(json!(MediaType::SourceMap), json!(8));
assert_eq!(json!(MediaType::Unknown), json!(9));
}

#[test]
Expand All @@ -160,6 +220,8 @@ mod tests {
assert_eq!(format!("{}", MediaType::TSX), "TSX");
assert_eq!(format!("{}", MediaType::Json), "Json");
assert_eq!(format!("{}", MediaType::Wasm), "Wasm");
assert_eq!(format!("{}", MediaType::TsBuildInfo), "TsBuildInfo");
assert_eq!(format!("{}", MediaType::SourceMap), "SourceMap");
assert_eq!(format!("{}", MediaType::Unknown), "Unknown");
}
}
4 changes: 2 additions & 2 deletions cli/module_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ impl ModuleGraphLoader {
filename: source_file.filename.to_str().unwrap().to_string(),
version_hash: checksum::gen(&[
&source_file.source_code.as_bytes(),
version::DENO.as_bytes(),
&version::DENO.as_bytes(),
]),
media_type: source_file.media_type,
source_code: "".to_string(),
Expand All @@ -481,7 +481,7 @@ impl ModuleGraphLoader {
let module_specifier = ModuleSpecifier::from(source_file.url.clone());
let version_hash = checksum::gen(&[
&source_file.source_code.as_bytes(),
version::DENO.as_bytes(),
&version::DENO.as_bytes(),
]);
let source_code = source_file.source_code.clone();

Expand Down
77 changes: 74 additions & 3 deletions cli/module_graph2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,8 @@ impl Module {
}
}

#[derive(Clone, Debug, PartialEq)]
pub struct Stats(Vec<(String, u128)>);
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Stats(pub Vec<(String, u128)>);

impl<'de> Deserialize<'de> for Stats {
fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
Expand Down Expand Up @@ -572,6 +572,27 @@ impl Graph2 {
Ok(())
}

pub fn get_media_type(
&self,
specifier: &ModuleSpecifier,
) -> Option<MediaType> {
if let Some(module) = self.modules.get(specifier) {
Some(module.media_type)
} else {
None
}
}

/// Get the source for a given module specifier. If the module is not part
/// of the graph, the result will be `None`.
pub fn get_source(&self, specifier: &ModuleSpecifier) -> Option<String> {
if let Some(module) = self.modules.get(specifier) {
Some(module.source.clone())
} else {
None
}
}

/// Verify the subresource integrity of the graph based upon the optional
/// lockfile, updating the lockfile with any missing resources. This will
/// error if any of the resources do not match their lock status.
Expand All @@ -595,6 +616,56 @@ impl Graph2 {
Ok(())
}

/// Given a string specifier and a referring module specifier, provide the
/// resulting module specifier and media type for the module that is part of
/// the graph.
pub fn resolve(
&self,
specifier: &str,
referrer: &ModuleSpecifier,
) -> Result<ModuleSpecifier, AnyError> {
if !self.modules.contains_key(referrer) {
return Err(MissingSpecifier(referrer.to_owned()).into());
}
let module = self.modules.get(referrer).unwrap();
if !module.dependencies.contains_key(specifier) {
return Err(
MissingDependency(referrer.to_owned(), specifier.to_owned()).into(),
);
}
let dependency = module.dependencies.get(specifier).unwrap();
// If there is a @deno-types pragma that impacts the dependency, then the
// maybe_type property will be set with that specifier, otherwise we use the
// specifier that point to the runtime code.
let resolved_specifier =
if let Some(type_specifier) = dependency.maybe_type.clone() {
type_specifier
} else if let Some(code_specifier) = dependency.maybe_code.clone() {
code_specifier
} else {
return Err(
MissingDependency(referrer.to_owned(), specifier.to_owned()).into(),
);
};
if !self.modules.contains_key(&resolved_specifier) {
return Err(
MissingDependency(referrer.to_owned(), resolved_specifier.to_string())
.into(),
);
}
let dep_module = self.modules.get(&resolved_specifier).unwrap();
// In the case that there is a X-TypeScript-Types or a triple-slash types,
// then the `maybe_types` specifier will be populated and we should use that
// instead.
let result = if let Some((_, types)) = dep_module.maybe_types.clone() {
types
} else {
resolved_specifier
};

Ok(result)
}

/// Transpile (only transform) the graph, updating any emitted modules
/// with the specifier handler. The result contains any performance stats
/// from the compiler and optionally any user provided configuration compiler
Expand Down Expand Up @@ -798,7 +869,7 @@ impl GraphBuilder2 {
}

#[cfg(test)]
mod tests {
pub mod tests {
use super::*;

use deno_core::futures::future;
Expand Down
1 change: 1 addition & 0 deletions cli/tests/tsc2/file_main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("hello deno");
3 changes: 3 additions & 0 deletions cli/tests/tsc2/https_deno.land-x-a.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as b from "./b.ts";

console.log(b);
1 change: 1 addition & 0 deletions cli/tests/tsc2/https_deno.land-x-b.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const b = "b";
1 change: 1 addition & 0 deletions cli/tests/tsc2/https_deno.land-x-mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("hello deno");
Loading

0 comments on commit 10654fa

Please sign in to comment.