mirror of
https://github.com/denoland/deno.git
synced 2025-08-04 10:59:13 +00:00
perf: use emit from swc instead of tsc (#15118)
This commit is contained in:
parent
7610764980
commit
0c87dd1e98
28 changed files with 664 additions and 525 deletions
215
cli/cache/check.rs
vendored
Normal file
215
cli/cache/check.rs
vendored
Normal file
|
@ -0,0 +1,215 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||
use deno_runtime::deno_webstorage::rusqlite::Connection;
|
||||
|
||||
use super::common::run_sqlite_pragma;
|
||||
|
||||
/// The cache used to tell whether type checking should occur again.
|
||||
///
|
||||
/// This simply stores a hash of the inputs of each successful type check
|
||||
/// and only clears them out when changing CLI versions.
|
||||
pub struct TypeCheckCache {
|
||||
conn: Connection,
|
||||
}
|
||||
|
||||
impl TypeCheckCache {
|
||||
pub fn new(db_file_path: &Path) -> Result<Self, AnyError> {
|
||||
let conn = Connection::open(db_file_path).with_context(|| {
|
||||
format!(
|
||||
concat!(
|
||||
"Error opening type checking cache at {} -- ",
|
||||
"Perhaps it's corrupt. Maybe try deleting it."
|
||||
),
|
||||
db_file_path.display()
|
||||
)
|
||||
})?;
|
||||
Self::from_connection(conn, crate::version::deno())
|
||||
}
|
||||
|
||||
fn from_connection(
|
||||
conn: Connection,
|
||||
cli_version: String,
|
||||
) -> Result<Self, AnyError> {
|
||||
run_sqlite_pragma(&conn)?;
|
||||
create_tables(&conn, cli_version)?;
|
||||
|
||||
Ok(Self { conn })
|
||||
}
|
||||
|
||||
pub fn has_check_hash(&self, hash: u64) -> bool {
|
||||
match self.hash_check_hash_result(hash) {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
if cfg!(debug_assertions) {
|
||||
panic!("Error retrieving hash: {}", err);
|
||||
} else {
|
||||
log::debug!("Error retrieving hash: {}", err);
|
||||
// fail silently when not debugging
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_check_hash_result(&self, hash: u64) -> Result<bool, AnyError> {
|
||||
let query = "SELECT * FROM checkcache WHERE check_hash=?1 LIMIT 1";
|
||||
let mut stmt = self.conn.prepare_cached(query)?;
|
||||
Ok(stmt.exists(params![hash.to_string()])?)
|
||||
}
|
||||
|
||||
pub fn add_check_hash(&self, check_hash: u64) {
|
||||
if let Err(err) = self.add_check_hash_result(check_hash) {
|
||||
if cfg!(debug_assertions) {
|
||||
panic!("Error saving check hash: {}", err);
|
||||
} else {
|
||||
log::debug!("Error saving check hash: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_check_hash_result(&self, check_hash: u64) -> Result<(), AnyError> {
|
||||
let sql = "
|
||||
INSERT OR REPLACE INTO
|
||||
checkcache (check_hash)
|
||||
VALUES
|
||||
(?1)";
|
||||
let mut stmt = self.conn.prepare_cached(sql)?;
|
||||
stmt.execute(params![&check_hash.to_string(),])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_tsbuildinfo(&self, specifier: &ModuleSpecifier) -> Option<String> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare_cached("SELECT text FROM tsbuildinfo WHERE specifier=?1 LIMIT 1")
|
||||
.ok()?;
|
||||
let mut rows = stmt.query(params![specifier.to_string()]).ok()?;
|
||||
let row = rows.next().ok().flatten()?;
|
||||
|
||||
row.get(0).ok()
|
||||
}
|
||||
|
||||
pub fn set_tsbuildinfo(&self, specifier: &ModuleSpecifier, text: &str) {
|
||||
if let Err(err) = self.set_tsbuildinfo_result(specifier, text) {
|
||||
// should never error here, but if it ever does don't fail
|
||||
if cfg!(debug_assertions) {
|
||||
panic!("Error saving tsbuildinfo: {}", err);
|
||||
} else {
|
||||
log::debug!("Error saving tsbuildinfo: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_tsbuildinfo_result(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
text: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
let mut stmt = self.conn.prepare_cached(
|
||||
"INSERT OR REPLACE INTO tsbuildinfo (specifier, text) VALUES (?1, ?2)",
|
||||
)?;
|
||||
stmt.execute(params![specifier.to_string(), text])?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn create_tables(
|
||||
conn: &Connection,
|
||||
cli_version: String,
|
||||
) -> Result<(), AnyError> {
|
||||
// INT doesn't store up to u64, so use TEXT
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS checkcache (
|
||||
check_hash TEXT PRIMARY KEY
|
||||
)",
|
||||
[],
|
||||
)?;
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS tsbuildinfo (
|
||||
specifier TEXT PRIMARY KEY,
|
||||
text TEXT NOT NULL
|
||||
)",
|
||||
[],
|
||||
)?;
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS info (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
)",
|
||||
[],
|
||||
)?;
|
||||
|
||||
// delete the cache when the CLI version changes
|
||||
let data_cli_version: Option<String> = conn
|
||||
.query_row(
|
||||
"SELECT value FROM info WHERE key='CLI_VERSION' LIMIT 1",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)
|
||||
.ok();
|
||||
if data_cli_version != Some(cli_version.to_string()) {
|
||||
conn.execute("DELETE FROM checkcache", params![])?;
|
||||
conn.execute("DELETE FROM tsbuildinfo", params![])?;
|
||||
let mut stmt = conn
|
||||
.prepare("INSERT OR REPLACE INTO info (key, value) VALUES (?1, ?2)")?;
|
||||
stmt.execute(params!["CLI_VERSION", &cli_version])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
pub fn check_cache_general_use() {
|
||||
let conn = Connection::open_in_memory().unwrap();
|
||||
let cache =
|
||||
TypeCheckCache::from_connection(conn, "1.0.0".to_string()).unwrap();
|
||||
|
||||
assert!(!cache.has_check_hash(1));
|
||||
cache.add_check_hash(1);
|
||||
assert!(cache.has_check_hash(1));
|
||||
assert!(!cache.has_check_hash(2));
|
||||
|
||||
let specifier1 = ModuleSpecifier::parse("file:///test.json").unwrap();
|
||||
assert_eq!(cache.get_tsbuildinfo(&specifier1), None);
|
||||
cache.set_tsbuildinfo(&specifier1, "test");
|
||||
assert_eq!(cache.get_tsbuildinfo(&specifier1), Some("test".to_string()));
|
||||
|
||||
// try changing the cli version (should clear)
|
||||
let conn = cache.conn;
|
||||
let cache =
|
||||
TypeCheckCache::from_connection(conn, "2.0.0".to_string()).unwrap();
|
||||
assert!(!cache.has_check_hash(1));
|
||||
cache.add_check_hash(1);
|
||||
assert!(cache.has_check_hash(1));
|
||||
assert_eq!(cache.get_tsbuildinfo(&specifier1), None);
|
||||
cache.set_tsbuildinfo(&specifier1, "test");
|
||||
assert_eq!(cache.get_tsbuildinfo(&specifier1), Some("test".to_string()));
|
||||
|
||||
// recreating the cache should not remove the data because the CLI version and state hash is the same
|
||||
let conn = cache.conn;
|
||||
let cache =
|
||||
TypeCheckCache::from_connection(conn, "2.0.0".to_string()).unwrap();
|
||||
assert!(cache.has_check_hash(1));
|
||||
assert!(!cache.has_check_hash(2));
|
||||
assert_eq!(cache.get_tsbuildinfo(&specifier1), Some("test".to_string()));
|
||||
|
||||
// adding when already exists should not cause issue
|
||||
cache.add_check_hash(1);
|
||||
assert!(cache.has_check_hash(1));
|
||||
cache.set_tsbuildinfo(&specifier1, "other");
|
||||
assert_eq!(
|
||||
cache.get_tsbuildinfo(&specifier1),
|
||||
Some("other".to_string())
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue