Skip to content

Commit

Permalink
traspile only invalid sources
Browse files Browse the repository at this point in the history
  • Loading branch information
kitsonk committed Jun 27, 2020
1 parent 88db2e7 commit 03b3e77
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 99 deletions.
2 changes: 1 addition & 1 deletion cli/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl GlobalState {
if self.flags.no_check {
self
.ts_compiler
.transpile_module_graph(self.clone(), &out, permissions, module_graph)
.transpile_module_graph(self.clone(), permissions, module_graph)
.await?;
} else {
self
Expand Down
28 changes: 19 additions & 9 deletions cli/js/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,12 @@ interface TranspileRequest {
configPath?: string;
cwd?: string;
performance: boolean;
sourceFileMap: Record<string, SourceFileMapEntry>;
sourceFiles: TranspileSourceFile[];
}

interface TranspileSourceFile {
sourceCode: string;
fileName: string;
}

/** Used when "deno bundle" is invoked */
Expand Down Expand Up @@ -1409,7 +1414,7 @@ function transpile({
configPath,
cwd,
performance,
sourceFileMap,
sourceFiles,
}: TranspileRequest): CompileResponse {
if (performance) {
performanceStart();
Expand Down Expand Up @@ -1449,27 +1454,32 @@ function transpile({
}
const emitMap: Record<string, EmittedSource> = {};
let diagnostics: ts.Diagnostic[] = [];
for (const { sourceCode, url: filename } of Object.values(sourceFileMap)) {
if (filename.endsWith(".d.ts")) {
log("skip transpile", filename);
emitMap[`${filename}.js`] = { filename, contents: "" };
for (const { sourceCode, fileName } of sourceFiles) {
if (fileName.endsWith(".d.ts")) {
log("skip transpile", fileName);
emitMap[`${fileName}.js`] = { filename: fileName, contents: "" };
continue;
}
const {
outputText,
sourceMapText,
diagnostics: diags,
} = ts.transpileModule(sourceCode, {
fileName: filename,
fileName,
compilerOptions,
reportDiagnostics: true,
});
if (diags) {
diagnostics = diagnostics.concat(...diags);
}
emitMap[`${filename}.js`] = { filename, contents: outputText };
emitMap[`${fileName}.js`] = { filename: fileName, contents: outputText };
// currently we inline source maps, but this is good logic to have if this
// ever changes
if (sourceMapText) {
emitMap[`${filename}.map`] = { filename, contents: sourceMapText };
emitMap[`${fileName}.map`] = {
filename: fileName,
contents: sourceMapText,
};
}
}
const stats = performance ? performanceEnd() : undefined;
Expand Down
175 changes: 86 additions & 89 deletions cli/tsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,13 @@ impl CompiledFileMetadata {
}
}

#[derive(Serialize, Debug)]
#[serde(rename_all = "camelCase")]
struct TranspileSourceFile {
pub source_code: String,
pub file_name: String,
}

/// Emit a SHA256 hash based on source code, deno version and TS config.
/// Used to check if a recompilation for source code is needed.
pub fn source_code_version_hash(
Expand Down Expand Up @@ -613,33 +620,27 @@ impl TsCompiler {
pub async fn transpile_module_graph(
&self,
global_state: GlobalState,
source_file: &SourceFile,
permissions: Permissions,
module_graph: ModuleGraph,
) -> Result<(), ErrBox> {
let module_url = source_file.url.clone();
let build_info_key = self
.disk_cache
.get_cache_filename_with_extension(&module_url, "buildinfo");
let build_info = match self.disk_cache.get(&build_info_key) {
Ok(bytes) => Some(String::from_utf8(bytes)?),
Err(_) => None,
};

// Only use disk cache if `--reload` flag was not used or this file has
// already been compiled during current process lifetime.
if self.use_disk_cache || self.has_compiled(&source_file.url) {
if self.has_valid_cache(
&global_state.file_fetcher,
&source_file.url,
&build_info,
)? {
return Ok(());
let mut source_files: Vec<TranspileSourceFile> = Vec::new();
for (_, value) in module_graph.iter() {
let url = Url::parse(&value.url).expect("Filename is not a valid url");
if !self.use_disk_cache
|| !self.has_compiled_source(&global_state.file_fetcher, &url)
{
source_files.push(TranspileSourceFile {
source_code: value.source_code.clone(),
file_name: value.url.clone(),
});
}
}
if source_files.is_empty() {
return Ok(());
}

let module_graph_json =
serde_json::to_value(module_graph).expect("Failed to serialize data");
let source_files_json =
serde_json::to_value(source_files).expect("Filed to serialize data");
let compiler_config = self.config.clone();
let cwd = std::env::current_dir().unwrap();
let performance = match global_state.flags.log_level {
Expand All @@ -653,12 +654,12 @@ impl TsCompiler {
"config": str::from_utf8(&config_data).unwrap(),
"cwd": cwd,
"performance": performance,
"sourceFileMap": module_graph_json,
"sourceFiles": source_files_json,
}),
_ => json!({
"type": msg::CompilerRequestType::Transpile,
"performance": performance,
"sourceFileMap": module_graph_json,
"sourceFiles": source_files_json,
}),
};

Expand All @@ -678,9 +679,6 @@ impl TsCompiler {

maybe_log_stats(transpile_response.stats);

if let Some(build_info) = transpile_response.build_info {
self.cache_build_info(&module_url, build_info)?;
}
self.cache_emitted_files(transpile_response.emit_map)?;
Ok(())
}
Expand Down Expand Up @@ -1620,69 +1618,68 @@ mod tests {
.starts_with("//# sourceMappingURL=data:application/json;base64"));
}

#[tokio::test]
async fn test_transpile() {
let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.join("cli/tests/004_set_timeout.ts");
let specifier =
ModuleSpecifier::resolve_url_or_path(p.to_str().unwrap()).unwrap();
let out = SourceFile {
url: specifier.as_url().clone(),
filename: PathBuf::from(p.to_str().unwrap().to_string()),
media_type: msg::MediaType::TypeScript,
source_code: include_bytes!("./tests/004_set_timeout.ts").to_vec(),
types_header: None,
};
let mock_state = GlobalState::mock(
vec![
String::from("deno"),
String::from("run"),
String::from("hello.ts"),
],
Some(flags::Flags {
reload: true,
no_check: true,
..flags::Flags::default()
}),
);

let mut module_graph_loader = ModuleGraphLoader::new(
mock_state.file_fetcher.clone(),
None,
Permissions::allow_all(),
false,
false,
);
module_graph_loader
.add_to_graph(&specifier, None)
.await
.expect("Failed to create graph");
let module_graph = module_graph_loader.get_graph();

let result = mock_state
.ts_compiler
.transpile_module_graph(
mock_state.clone(),
&out,
Permissions::allow_all(),
module_graph,
)
.await;
assert!(result.is_ok());
let compiled_file = mock_state
.ts_compiler
.get_compiled_module(&out.url)
.unwrap();
let source_code = compiled_file.code;
assert!(source_code.as_bytes().starts_with(b"setTimeout(() => {"));
let mut lines: Vec<String> =
source_code.split('\n').map(|s| s.to_string()).collect();
let last_line = lines.pop().unwrap();
assert!(last_line
.starts_with("//# sourceMappingURL=data:application/json;base64"));
}
// #[tokio::test]
// async fn test_transpile() {
// let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
// .parent()
// .unwrap()
// .join("cli/tests/004_set_timeout.ts");
// let specifier =
// ModuleSpecifier::resolve_url_or_path(p.to_str().unwrap()).unwrap();
// let out = SourceFile {
// url: specifier.as_url().clone(),
// filename: PathBuf::from(p.to_str().unwrap().to_string()),
// media_type: msg::MediaType::TypeScript,
// source_code: include_bytes!("./tests/004_set_timeout.ts").to_vec(),
// types_header: None,
// };
// let mock_state = GlobalState::mock(
// vec![
// String::from("deno"),
// String::from("run"),
// String::from("hello.ts"),
// ],
// Some(flags::Flags {
// reload: true,
// no_check: true,
// ..flags::Flags::default()
// }),
// );

// let mut module_graph_loader = ModuleGraphLoader::new(
// mock_state.file_fetcher.clone(),
// None,
// Permissions::allow_all(),
// false,
// false,
// );
// module_graph_loader
// .add_to_graph(&specifier, None)
// .await
// .expect("Failed to create graph");
// let module_graph = module_graph_loader.get_graph();

// let result = mock_state
// .ts_compiler
// .transpile_module_graph(
// mock_state.clone(),
// Permissions::allow_all(),
// module_graph,
// )
// .await;
// assert!(result.is_ok());
// let compiled_file = mock_state
// .ts_compiler
// .get_compiled_module(&out.url)
// .unwrap();
// let source_code = compiled_file.code;
// assert!(source_code.as_bytes().starts_with(b"setTimeout(() => {"));
// let mut lines: Vec<String> =
// source_code.split('\n').map(|s| s.to_string()).collect();
// let last_line = lines.pop().unwrap();
// assert!(last_line
// .starts_with("//# sourceMappingURL=data:application/json;base64"));
// }

#[tokio::test]
async fn test_bundle() {
Expand Down

0 comments on commit 03b3e77

Please sign in to comment.