diff --git a/cli/diagnostics.rs b/cli/diagnostics.rs index 1e7c2b5eb4..57fe56b6f7 100644 --- a/cli/diagnostics.rs +++ b/cli/diagnostics.rs @@ -80,7 +80,7 @@ pub struct DiagnosticItem { /// A chain of messages, code, and categories of messages which indicate the /// full diagnostic information. - pub message_chain: Option>, + pub message_chain: Option, /// Other diagnostic items that are related to the diagnostic, usually these /// are suggestions of why an error occurred. @@ -198,21 +198,12 @@ impl DisplayFormatter for DiagnosticItem { } fn format_message(&self, level: usize) -> String { + debug!("format_message"); if self.message_chain.is_none() { return format!("{:indent$}{}", "", self.message, indent = level); } - let mut s = String::new(); - let mut i = level / 2; - let mut item_o = self.message_chain.clone(); - while item_o.is_some() { - let item = item_o.unwrap(); - s.push_str(&std::iter::repeat(" ").take(i * 2).collect::()); - s.push_str(&item.message); - s.push('\n'); - item_o = item.next.clone(); - i += 1; - } + let mut s = self.message_chain.clone().unwrap().format_message(level); s.pop(); s @@ -280,15 +271,11 @@ pub struct DiagnosticMessageChain { pub message: String, pub code: i64, pub category: DiagnosticCategory, - pub next: Option>, + pub next: Option>, } impl DiagnosticMessageChain { - pub fn from_json_value(v: &serde_json::Value) -> Option> { - if !v.is_object() { - return None; - } - + fn from_value(v: &serde_json::Value) -> Self { let obj = v.as_object().unwrap(); let message = obj .get("message") @@ -301,16 +288,55 @@ impl DiagnosticMessageChain { let next_v = obj.get("next"); let next = match next_v { - Some(n) => DiagnosticMessageChain::from_json_value(n), + Some(n) => DiagnosticMessageChain::from_next_array(n), _ => None, }; - Some(Box::new(Self { + Self { message, code, category, next, - })) + } + } + + fn from_next_array(v: &serde_json::Value) -> Option> { + if !v.is_array() { + return None; + } + + let vec = v + .as_array() + .unwrap() + .iter() + .map(|item| Self::from_value(&item)) + .collect::>(); + + Some(vec) + } + + pub fn from_json_value(v: &serde_json::Value) -> Option { + if !v.is_object() { + return None; + } + + Some(Self::from_value(v)) + } + + pub fn format_message(&self, level: usize) -> String { + let mut s = String::new(); + + s.push_str(&std::iter::repeat(" ").take(level * 2).collect::()); + s.push_str(&self.message); + s.push('\n'); + if self.next.is_some() { + let arr = self.next.clone().unwrap(); + for dm in arr { + s.push_str(&dm.format_message(level + 1)); + } + } + + s } } @@ -348,22 +374,22 @@ mod tests { items: vec![ DiagnosticItem { message: "Type '(o: T) => { v: any; f: (x: B) => string; }[]' is not assignable to type '(r: B) => Value[]'.".to_string(), - message_chain: Some(Box::new(DiagnosticMessageChain { + message_chain: Some(DiagnosticMessageChain { message: "Type '(o: T) => { v: any; f: (x: B) => string; }[]' is not assignable to type '(r: B) => Value[]'.".to_string(), code: 2322, category: DiagnosticCategory::Error, - next: Some(Box::new(DiagnosticMessageChain { + next: Some(vec![DiagnosticMessageChain { message: "Types of parameters 'o' and 'r' are incompatible.".to_string(), code: 2328, category: DiagnosticCategory::Error, - next: Some(Box::new(DiagnosticMessageChain { + next: Some(vec![DiagnosticMessageChain { message: "Type 'B' is not assignable to type 'T'.".to_string(), code: 2322, category: DiagnosticCategory::Error, next: None, - })), - })), - })), + }]), + }]), + }), code: 2322, category: DiagnosticCategory::Error, start_position: Some(267), @@ -437,124 +463,67 @@ mod tests { &r#"{ "items": [ { - "message": "Type '(o: T) => { v: any; f: (x: B) => string; }[]' is not assignable to type '(r: B) => Value[]'.", + "message": "Type '{ a(): { b: number; }; }' is not assignable to type '{ a(): { b: string; }; }'.", "messageChain": { - "message": "Type '(o: T) => { v: any; f: (x: B) => string; }[]' is not assignable to type '(r: B) => Value[]'.", + "message": "Type '{ a(): { b: number; }; }' is not assignable to type '{ a(): { b: string; }; }'.", "code": 2322, "category": 3, - "next": { - "message": "Types of parameters 'o' and 'r' are incompatible.", - "code": 2328, - "category": 3, - "next": { - "message": "Type 'B' is not assignable to type 'T'.", - "code": 2322, + "next": [ + { + "message": "Types of property 'a' are incompatible.", + "code": 2326, "category": 3 } - } + ] }, "code": 2322, "category": 3, - "startPosition": 235, - "endPosition": 241, - "sourceLine": " values: o => [", - "lineNumber": 18, - "scriptResourceName": "/deno/tests/complex_diagnostics.ts", - "startColumn": 2, - "endColumn": 8, - "relatedInformation": [ - { - "message": "The expected type comes from property 'values' which is declared here on type 'C'", - "code": 6500, - "category": 2, - "startPosition": 78, - "endPosition": 84, - "sourceLine": " values?: (r: T) => Array>;", - "lineNumber": 6, - "scriptResourceName": "/deno/tests/complex_diagnostics.ts", - "startColumn": 2, - "endColumn": 8 - } - ] - }, - { - "message": "Property 't' does not exist on type 'T'.", - "code": 2339, - "category": 3, - "startPosition": 267, - "endPosition": 268, - "sourceLine": " v: o.t,", - "lineNumber": 20, - "scriptResourceName": "/deno/tests/complex_diagnostics.ts", - "startColumn": 11, - "endColumn": 12 + "startPosition": 352, + "endPosition": 353, + "sourceLine": "x = y;", + "lineNumber": 29, + "scriptResourceName": "/deno/tests/error_003_typescript.ts", + "startColumn": 0, + "endColumn": 1 } ] }"#, ).unwrap(); let r = Diagnostic::from_json_value(&v); - let expected = Some(Diagnostic { - items: vec![ - DiagnosticItem { - message: "Type '(o: T) => { v: any; f: (x: B) => string; }[]' is not assignable to type '(r: B) => Value[]'.".to_string(), - message_chain: Some(Box::new(DiagnosticMessageChain { - message: "Type '(o: T) => { v: any; f: (x: B) => string; }[]' is not assignable to type '(r: B) => Value[]'.".to_string(), - code: 2322, - category: DiagnosticCategory::Error, - next: Some(Box::new(DiagnosticMessageChain { - message: "Types of parameters 'o' and 'r' are incompatible.".to_string(), - code: 2328, - category: DiagnosticCategory::Error, - next: Some(Box::new(DiagnosticMessageChain { - message: "Type 'B' is not assignable to type 'T'.".to_string(), + let expected = Some( + Diagnostic { + items: vec![ + DiagnosticItem { + message: "Type \'{ a(): { b: number; }; }\' is not assignable to type \'{ a(): { b: string; }; }\'.".to_string(), + message_chain: Some( + DiagnosticMessageChain { + message: "Type \'{ a(): { b: number; }; }\' is not assignable to type \'{ a(): { b: string; }; }\'.".to_string(), code: 2322, category: DiagnosticCategory::Error, - next: None, - })), - })), - })), - related_information: Some(vec![ - DiagnosticItem { - message: "The expected type comes from property 'values' which is declared here on type 'C'".to_string(), - message_chain: None, - related_information: None, - source_line: Some(" values?: (r: T) => Array>;".to_string()), - line_number: Some(6), - script_resource_name: Some("/deno/tests/complex_diagnostics.ts".to_string()), - start_position: Some(78), - end_position: Some(84), - category: DiagnosticCategory::Info, - code: 6500, - start_column: Some(2), - end_column: Some(8), - } - ]), - source_line: Some(" values: o => [".to_string()), - line_number: Some(18), - script_resource_name: Some("/deno/tests/complex_diagnostics.ts".to_string()), - start_position: Some(235), - end_position: Some(241), - category: DiagnosticCategory::Error, - code: 2322, - start_column: Some(2), - end_column: Some(8), - }, - DiagnosticItem { - message: "Property 't' does not exist on type 'T'.".to_string(), - message_chain: None, - related_information: None, - source_line: Some(" v: o.t,".to_string()), - line_number: Some(20), - script_resource_name: Some("/deno/tests/complex_diagnostics.ts".to_string()), - start_position: Some(267), - end_position: Some(268), - category: DiagnosticCategory::Error, - code: 2339, - start_column: Some(11), - end_column: Some(12), - }, - ], - }); + next: Some(vec![ + DiagnosticMessageChain { + message: "Types of property \'a\' are incompatible.".to_string(), + code: 2326, + category: DiagnosticCategory::Error, + next: None, + } + ]) + } + ), + related_information: None, + source_line: Some("x = y;".to_string()), + line_number: Some(29), + script_resource_name: Some("/deno/tests/error_003_typescript.ts".to_string()), + start_position: Some(352), + end_position: Some(353), + category: DiagnosticCategory::Error, + code: 2322, + start_column: Some(0), + end_column: Some(1) + } + ] + } + ); assert_eq!(expected, r); } diff --git a/cli/tests/error_003_typescript.ts b/cli/tests/error_003_typescript.ts index 6fb077ea08..4ce86bb83b 100644 --- a/cli/tests/error_003_typescript.ts +++ b/cli/tests/error_003_typescript.ts @@ -1,26 +1,20 @@ /* eslint-disable */ -interface Value { - f?: (r: T) => any; - v?: string; -} - -interface C { - values?: (r: T) => Array>; -} - -class A { - constructor(private e?: T, public s?: C) {} -} - -class B { - t = "foo"; -} - -var a = new A(new B(), { - values: o => [ - { - v: o.t, - f: x => "bar" +let x = { + a: { + b: { + c() { + return { d: "hello" }; + } } - ] -}); + } +}; +let y = { + a: { + b: { + c() { + return { d: 1234 }; + } + } + } +}; +x = y; diff --git a/cli/tests/error_003_typescript.ts.out b/cli/tests/error_003_typescript.ts.out index f00a935e45..0b1d94db4b 100644 --- a/cli/tests/error_003_typescript.ts.out +++ b/cli/tests/error_003_typescript.ts.out @@ -1,28 +1,16 @@ -[WILDCARD]error TS2322: Type '(o: T) => { v: any; f: (x: B) => string; }[]' is not assignable to type '(r: B) => Value[]'. - Types of parameters 'o' and 'r' are incompatible. - Type 'B' is not assignable to type 'T'. - 'B' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +[WILDCARD]error TS2322: Type '{ a: { b: { c(): { d: number; }; }; }; }' is not assignable to type '{ a: { b: { c(): { d: string; }; }; }; }'. + Types of property 'a' are incompatible. + Type '{ b: { c(): { d: number; }; }; }' is not assignable to type '{ b: { c(): { d: string; }; }; }'. + Types of property 'b' are incompatible. + Type '{ c(): { d: number; }; }' is not assignable to type '{ c(): { d: string; }; }'. + Types of property 'c' are incompatible. + Type '() => { d: number; }' is not assignable to type '() => { d: string; }'. + Type '{ d: number; }' is not assignable to type '{ d: string; }'. + Types of property 'd' are incompatible. + Type 'number' is not assignable to type 'string'. -[WILDCARD]tests/error_003_typescript.ts:20:3 +[WILDCARD]/tests/error_003_typescript.ts:20:1 -20 values: o => [ - ~~~~~~ - - The expected type comes from property 'values' which is declared here on type 'C' - - [WILDCARD]tests/error_003_typescript.ts:8:3 - - 8 values?: (r: T) => Array>; - ~~~~~~ - - -error TS2339: Property 't' does not exist on type 'T'. - -[WILDCARD]tests/error_003_typescript.ts:22:12 - -22 v: o.t, - ^ - - -Found 2 errors. +20 x = y; + ^ diff --git a/deno_typescript/lib.rs b/deno_typescript/lib.rs index 3d5ab6b159..f6ec3104b1 100644 --- a/deno_typescript/lib.rs +++ b/deno_typescript/lib.rs @@ -245,6 +245,7 @@ pub fn get_asset(name: &str) -> Option<&'static str> { "lib.es2017.string.d.ts" => inc!("lib.es2017.string.d.ts"), "lib.es2017.intl.d.ts" => inc!("lib.es2017.intl.d.ts"), "lib.es2017.typedarrays.d.ts" => inc!("lib.es2017.typedarrays.d.ts"), + "lib.es2018.asyncgenerator.d.ts" => inc!("lib.es2018.asyncgenerator.d.ts"), "lib.es2018.asynciterable.d.ts" => inc!("lib.es2018.asynciterable.d.ts"), "lib.es2018.promise.d.ts" => inc!("lib.es2018.promise.d.ts"), "lib.es2018.regexp.d.ts" => inc!("lib.es2018.regexp.d.ts"), diff --git a/deno_typescript/typescript b/deno_typescript/typescript index cf7b2d4ae9..26655db1dd 160000 --- a/deno_typescript/typescript +++ b/deno_typescript/typescript @@ -1 +1 @@ -Subproject commit cf7b2d4ae91c4f27ba9ae7137ddf9a407815e590 +Subproject commit 26655db1dd04d93217002ac87f950aba812c53eb diff --git a/js/diagnostics.ts b/js/diagnostics.ts index c5377f979b..7cdb154b94 100644 --- a/js/diagnostics.ts +++ b/js/diagnostics.ts @@ -18,7 +18,7 @@ export interface DiagnosticMessageChain { message: string; category: DiagnosticCategory; code: number; - next?: DiagnosticMessageChain; + next?: DiagnosticMessageChain[]; } export interface DiagnosticItem { @@ -130,19 +130,20 @@ function getSourceInformation( /** Converts a TypeScript diagnostic message chain to a Deno one. */ function fromDiagnosticMessageChain( - messageChain: ts.DiagnosticMessageChain | undefined -): DiagnosticMessageChain | undefined { + messageChain: ts.DiagnosticMessageChain[] | undefined +): DiagnosticMessageChain[] | undefined { if (!messageChain) { return undefined; } - const { messageText: message, code, category, next } = messageChain; - return { - message, - code, - category: fromDiagnosticCategory(category), - next: fromDiagnosticMessageChain(next) - }; + return messageChain.map(({ messageText: message, code, category, next }) => { + return { + message, + code, + category: fromDiagnosticCategory(category), + next: fromDiagnosticMessageChain(next) + }; + }); } /** Parse out information from a TypeScript diagnostic structure. */ @@ -171,7 +172,7 @@ function parseDiagnostic( message = messageText; } else { message = messageText.messageText; - messageChain = fromDiagnosticMessageChain(messageText); + messageChain = fromDiagnosticMessageChain([messageText])![0]; } const base = { diff --git a/package.json b/package.json index 8a4a131eaf..0d5ad170ed 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,6 @@ "eslint-config-prettier": "4.1.0", "magic-string": "0.25.2", "prettier": "1.17.1", - "typescript": "3.5.1" + "typescript": "3.6.3" } } diff --git a/third_party b/third_party index 1915f1bb61..32c4689ee8 160000 --- a/third_party +++ b/third_party @@ -1 +1 @@ -Subproject commit 1915f1bb617bec93f480a8f63100f721c8dda28b +Subproject commit 32c4689ee8f3364544c902b80f19ab227d3e1117