summaryrefslogtreecommitdiff
path: root/cli/tsc.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-07-11 18:30:30 +0200
committerGitHub <noreply@github.com>2020-07-11 18:30:30 +0200
commit871f9255e37b4d2e63439c84da8e9bed6b388034 (patch)
tree9b6ea85f35a5cec6f8c9d16c69ad437c25f3c5a0 /cli/tsc.rs
parenta26b4a9f1eaed65e801a1de0ed73b4da76d37e63 (diff)
fix: harden pragma and reference parsing in module analysis (#6702)
Diffstat (limited to 'cli/tsc.rs')
-rw-r--r--cli/tsc.rs97
1 files changed, 53 insertions, 44 deletions
diff --git a/cli/tsc.rs b/cli/tsc.rs
index 99b1449f8..90531b9fb 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -165,10 +165,22 @@ impl Future for CompilerWorker {
}
}
-// TODO(bartlomieju): use JSONC parser from dprint instead of Regex
lazy_static! {
+ // TODO(bartlomieju): use JSONC parser from dprint instead of Regex
static ref CHECK_JS_RE: Regex =
Regex::new(r#""checkJs"\s*?:\s*?true"#).unwrap();
+ static ref DENO_TYPES_RE: Regex =
+ Regex::new(r"^\s*@deno-types\s?=\s?(\S+)\s*(.*)\s*$").unwrap();
+ // These regexes were adapted from TypeScript
+ // https://github.com/microsoft/TypeScript/blob/87fd1827f2f2f3dafa76c14f13b9defc69481766/src/compiler/parser.ts#L8780-L8781
+ static ref XML_COMMENT_START_RE: Regex =
+ Regex::new(r"^/\s*<(\S+)\s.*?/>").unwrap();
+ static ref PATH_REFERENCE_RE: Regex =
+ Regex::new(r#"(\spath\s*=\s*)('|")(.+?)('|")"#).unwrap();
+ static ref TYPES_REFERENCE_RE: Regex =
+ Regex::new(r#"(\stypes\s*=\s*)('|")(.+?)('|")"#).unwrap();
+ static ref LIB_REFERENCE_RE: Regex =
+ Regex::new(r#"(\slib\s*=\s*)('|")(.+?)('|")"#).unwrap();
}
/// Create a new worker with snapshot of TS compiler and setup compiler's
@@ -1478,54 +1490,37 @@ fn get_deno_types(parser: &AstParser, span: Span) -> Option<String> {
parse_deno_types(&comment)
}
-// TODO(bartlomieju): refactor
fn parse_ts_reference(comment: &str) -> Option<(TsReferenceKind, String)> {
- let (kind, specifier_in_quotes) = if comment.starts_with("/ <reference path=")
- {
- (
- TsReferenceKind::Path,
- comment.trim_start_matches("/ <reference path="),
- )
- } else if comment.starts_with("/ <reference lib=") {
- (
- TsReferenceKind::Lib,
- comment.trim_start_matches("/ <reference lib="),
- )
- } else if comment.starts_with("/ <reference types=") {
- (
- TsReferenceKind::Types,
- comment.trim_start_matches("/ <reference types="),
- )
- } else {
+ if !XML_COMMENT_START_RE.is_match(comment) {
return None;
- };
-
- let specifier = specifier_in_quotes
- .trim_end_matches("/>")
- .trim_end()
- .trim_start_matches('\"')
- .trim_start_matches('\'')
- .trim_end_matches('\"')
- .trim_end_matches('\'')
- .to_string();
-
- Some((kind, specifier))
+ }
+
+ let (kind, specifier) =
+ if let Some(capture_groups) = PATH_REFERENCE_RE.captures(comment) {
+ (TsReferenceKind::Path, capture_groups.get(3).unwrap())
+ } else if let Some(capture_groups) = TYPES_REFERENCE_RE.captures(comment) {
+ (TsReferenceKind::Types, capture_groups.get(3).unwrap())
+ } else if let Some(capture_groups) = LIB_REFERENCE_RE.captures(comment) {
+ (TsReferenceKind::Lib, capture_groups.get(3).unwrap())
+ } else {
+ return None;
+ };
+
+ Some((kind, specifier.as_str().to_string()))
}
fn parse_deno_types(comment: &str) -> Option<String> {
- if comment.starts_with("@deno-types") {
- let split: Vec<String> =
- comment.split('=').map(|s| s.to_string()).collect();
- assert_eq!(split.len(), 2);
- let specifier_in_quotes = split.get(1).unwrap().to_string();
- let specifier = specifier_in_quotes
- .trim()
- .trim_start_matches('\"')
- .trim_start_matches('\'')
- .trim_end_matches('\"')
- .trim_end_matches('\'')
- .to_string();
- return Some(specifier);
+ if let Some(capture_groups) = DENO_TYPES_RE.captures(comment) {
+ if let Some(specifier) = capture_groups.get(1) {
+ let s = specifier
+ .as_str()
+ .trim_start_matches('\"')
+ .trim_start_matches('\'')
+ .trim_end_matches('\"')
+ .trim_end_matches('\'')
+ .to_string();
+ return Some(s);
+ }
}
None
@@ -1548,6 +1543,10 @@ mod tests {
Some("./a/b/c.d.ts".to_string())
);
assert_eq!(
+ parse_deno_types("@deno-types=\"./a/b/c.d.ts\""),
+ Some("./a/b/c.d.ts".to_string())
+ );
+ assert_eq!(
parse_deno_types("@deno-types = https://dneo.land/x/some/package/a.d.ts"),
Some("https://dneo.land/x/some/package/a.d.ts".to_string())
);
@@ -1557,6 +1556,16 @@ mod tests {
);
assert!(parse_deno_types("asdf").is_none());
assert!(parse_deno_types("// deno-types = fooo").is_none());
+ assert_eq!(
+ parse_deno_types("@deno-types=./a/b/c.d.ts some comment"),
+ Some("./a/b/c.d.ts".to_string())
+ );
+ assert_eq!(
+ parse_deno_types(
+ "@deno-types=./a/b/c.d.ts // some comment after slashes"
+ ),
+ Some("./a/b/c.d.ts".to_string())
+ );
}
#[test]