diff --git a/doc/TypeScript Language Specification (Change Markup).docx b/doc/TypeScript Language Specification (Change Markup).docx index 4dd2ee3a26..893f2e7ed2 100644 Binary files a/doc/TypeScript Language Specification (Change Markup).docx and b/doc/TypeScript Language Specification (Change Markup).docx differ diff --git a/doc/TypeScript Language Specification (Change Markup).pdf b/doc/TypeScript Language Specification (Change Markup).pdf index 36ca9d6321..1b4faab62e 100644 Binary files a/doc/TypeScript Language Specification (Change Markup).pdf and b/doc/TypeScript Language Specification (Change Markup).pdf differ diff --git a/doc/TypeScript Language Specification.docx b/doc/TypeScript Language Specification.docx index 65a7a57afd..4aaa3bf92f 100644 Binary files a/doc/TypeScript Language Specification.docx and b/doc/TypeScript Language Specification.docx differ diff --git a/doc/TypeScript Language Specification.pdf b/doc/TypeScript Language Specification.pdf index e4ad0acde4..277fcecf2d 100644 Binary files a/doc/TypeScript Language Specification.pdf and b/doc/TypeScript Language Specification.pdf differ diff --git a/doc/spec.md b/doc/spec.md index 67cfdac54b..fe2147be47 100644 --- a/doc/spec.md +++ b/doc/spec.md @@ -2,7 +2,7 @@ Version 1.6 -July, 2015 +August, 2015
@@ -24,7 +24,8 @@ TypeScript is a trademark of Microsoft Corporation. * [1.7 Enum Types](#1.7) * [1.8 Overloading on String Parameters](#1.8) * [1.9 Generic Types and Functions](#1.9) - * [1.10 Modules](#1.10) + * [1.10 Namespaces](#1.10) + * [1.11 Modules](#1.11) * [2 Basic Concepts](#2) * [2.1 Grammar Conventions](#2.1) * [2.2 Names](#2.2) @@ -82,9 +83,10 @@ TypeScript is a trademark of Microsoft Corporation. * [3.11.2 Type and Member Identity](#3.11.2) * [3.11.3 Subtypes and Supertypes](#3.11.3) * [3.11.4 Assignment Compatibility](#3.11.4) - * [3.11.5 Contextual Signature Instantiation](#3.11.5) - * [3.11.6 Type Inference](#3.11.6) - * [3.11.7 Recursive Types](#3.11.7) + * [3.11.5 Excess Properties](#3.11.5) + * [3.11.6 Contextual Signature Instantiation](#3.11.6) + * [3.11.7 Type Inference](#3.11.7) + * [3.11.8 Recursive Types](#3.11.8) * [3.12 Widened Types](#3.12) * [4 Expressions](#4) * [4.1 Values and References](#4.1) @@ -236,9 +238,11 @@ TypeScript is a trademark of Microsoft Corporation. JavaScript applications such as web e-mail, maps, document editing, and collaboration tools are becoming an increasingly important part of the everyday computing. We designed TypeScript to meet the needs of the JavaScript programming teams that build and maintain large JavaScript programs. TypeScript helps programming teams to define interfaces between software components and to gain insight into the behavior of existing JavaScript libraries. TypeScript also enables teams to reduce naming conflicts by organizing their code into dynamically-loadable modules. TypeScript's optional type system enables JavaScript programmers to use highly-productive development tools and practices: static checking, symbol-based navigation, statement completion, and code re-factoring. -TypeScript is a syntactic sugar for JavaScript. TypeScript syntax is a superset of Ecmascript 5 (ES5) syntax. Every JavaScript program is also a TypeScript program. The TypeScript compiler performs only file-local transformations on TypeScript programs and does not re-order variables declared in TypeScript. This leads to JavaScript output that closely matches the TypeScript input. TypeScript does not transform variable names, making tractable the direct debugging of emitted JavaScript. TypeScript optionally provides source maps, enabling source-level debugging. TypeScript tools typically emit JavaScript upon file save, preserving the test, edit, refresh cycle commonly used in JavaScript development. +TypeScript is a syntactic sugar for JavaScript. TypeScript syntax is a superset of ECMAScript 6 (ES6) syntax. Every JavaScript program is also a TypeScript program. The TypeScript compiler performs only file-local transformations on TypeScript programs and does not re-order variables declared in TypeScript. This leads to JavaScript output that closely matches the TypeScript input. TypeScript does not transform variable names, making tractable the direct debugging of emitted JavaScript. TypeScript optionally provides source maps, enabling source-level debugging. TypeScript tools typically emit JavaScript upon file save, preserving the test, edit, refresh cycle commonly used in JavaScript development. -TypeScript syntax includes several proposed features of Ecmascript 6 (ES6), including classes and modules. Classes enable programmers to express common object-oriented patterns in a standard way, making features like inheritance more readable and interoperable. Modules enable programmers to organize their code into components while avoiding naming conflicts. The TypeScript compiler provides module code generation options that support either static or dynamic loading of module contents. +TypeScript syntax includes all features of ECMAScript 6 (ES6), including classes and modules, and provides the ability to translate these features into ECMAScript 3 or 5 compliant code. + +Classes enable programmers to express common object-oriented patterns in a standard way, making features like inheritance more readable and interoperable. Modules enable programmers to organize their code into components while avoiding naming conflicts. The TypeScript compiler provides module code generation options that support either static or dynamic loading of module contents. TypeScript also provides to JavaScript programmers a system of optional type annotations. These type annotations are like the JSDoc comments found in the Closure system, but in TypeScript they are integrated directly into the language syntax. This integration makes the code more readable and reduces the maintenance cost of synchronizing type annotations with their corresponding variables. @@ -470,9 +474,9 @@ Section [4.23](#4.23) provides additional information about contextually typed e ## 1.6 Classes -JavaScript practice has at least two common design patterns: the module pattern and the class pattern. Roughly speaking, the module pattern uses closures to hide names and to encapsulate private data, while the class pattern uses prototype chains to implement many variations on object-oriented inheritance mechanisms. Libraries such as 'prototype.js' are typical of this practice. +JavaScript practice has two very common design patterns: the module pattern and the class pattern. Roughly speaking, the module pattern uses closures to hide names and to encapsulate private data, while the class pattern uses prototype chains to implement many variations on object-oriented inheritance mechanisms. Libraries such as 'prototype.js' are typical of this practice. TypeScript's namespaces are a formalization of the module pattern. (The term "module pattern" is somewhat unfortunate now that ECMAScript 6 formally supports modules in a manner different from what the module pattern prescribes. For this reason, TypeScript uses the term "namespace" for its formalization of the module pattern.) -This section and the module section below will show how TypeScript emits consistent, idiomatic JavaScript code to implement classes and modules that are closely aligned with the current ES6 proposal. The goal of TypeScript's translation is to emit exactly what a programmer would type when implementing a class or module unaided by a tool. This section will also describe how TypeScript infers a type for each class declaration. We'll start with a simple BankAccount class. +This section and the namespace section below will show how TypeScript emits consistent, idiomatic JavaScript when emitting ECMAScript 3 or 5 compliant code for classes and namespaces. The goal of TypeScript's translation is to emit exactly what a programmer would type when implementing a class or namespace unaided by a tool. This section will also describe how TypeScript infers a type for each class declaration. We'll start with a simple BankAccount class. ```TypeScript class BankAccount { @@ -570,7 +574,7 @@ Section [8](#8) provides additional information about classes. TypeScript enables programmers to summarize a set of numeric constants as an *enum type*. The example below creates an enum type to represent operators in a calculator application. ```TypeScript -enum Operator { +const enum Operator { ADD, DIV, MUL, @@ -585,7 +589,7 @@ function compute(op: Operator, a: number, b: number) { In this example, the compute function logs the operator 'op' using a feature of enum types: reverse mapping from the enum value ('op') to the string corresponding to that value. For example, the declaration of 'Operator' automatically assigns integers, starting from zero, to the listed enum members. Section [9](#9) describes how programmers can also explicitly assign integers to enum members, and can use any string to name an enum member. -If all enum members have explicitly assigned literal integers, or if an enum has all members automatically assigned, the TypeScript compiler will emit for an enum member a JavaScript constant corresponding to that member's assigned value (annotated with a comment). This improves performance on many JavaScript engines. +When enums are declared with the `const` modifier, the TypeScript compiler will emit for an enum member a JavaScript constant corresponding to that member's assigned value (annotated with a comment). This improves performance on many JavaScript engines. For example, the 'compute' function could contain a switch statement like the following. @@ -702,11 +706,11 @@ class List { Section [3.7](#3.7) provides further information about generic types. -## 1.10 Modules +## 1.10 Namespaces Classes and interfaces support large-scale JavaScript development by providing a mechanism for describing how to use a software component that can be separated from that component's implementation. TypeScript enforces *encapsulation* of implementation in classes at design time (by restricting use of private and protected members), but cannot enforce encapsulation at runtime because all object properties are accessible at runtime. Future versions of JavaScript may provide *private names* which would enable runtime enforcement of private and protected members. -In the current version of JavaScript, the only way to enforce encapsulation at runtime is to use the module pattern: encapsulate private fields and methods using closure variables. The module pattern is a natural way to provide organizational structure and dynamic loading options by drawing a boundary around a software component. A module can also provide the ability to introduce namespaces, avoiding use of the global namespace for most software components. +In JavaScript, a very common way to enforce encapsulation at runtime is to use the module pattern: encapsulate private fields and methods using closure variables. The module pattern is a natural way to provide organizational structure and dynamic loading options by drawing a boundary around a software component. The module pattern can also provide the ability to introduce namespaces, avoiding use of the global namespace for most software components. The following example illustrates the JavaScript module pattern. @@ -724,12 +728,12 @@ This example illustrates the two essential elements of the module pattern: a *mo The example assumes that an outer lexical scope defines the functions 'generateSecretKey' and 'sendSecureMessage'; it also assumes that the outer scope has assigned the module object to the variable 'MessageModule'. -TypeScript modules provide a mechanism for succinctly expressing the module pattern. In TypeScript, programmers can combine the module pattern with the class pattern by nesting modules and classes within an outer module. +TypeScript namespaces provide a mechanism for succinctly expressing the module pattern. In TypeScript, programmers can combine the module pattern with the class pattern by nesting namespaces and classes within an outer namespace. -The following example shows the definition and use of a simple module. +The following example shows the definition and use of a simple namespace. ```TypeScript -module M { +namespace M { var s = "hello"; export function f() { return s; @@ -740,7 +744,7 @@ M.f(); M.s; // Error, s is not exported ``` -In this example, variable 's' is a private feature of the module, but function 'f' is exported from the module and accessible to code outside of the module. If we were to describe the effect of module 'M' in terms of interfaces and variables, we would write +In this example, variable 's' is a private feature of the namespace, but function 'f' is exported from the namespace and accessible to code outside of the namespace. If we were to describe the effect of namespace 'M' in terms of interfaces and variables, we would write ```TypeScript interface M { @@ -750,9 +754,9 @@ interface M { var M: M; ``` -The interface 'M' summarizes the externally visible behavior of module 'M'. In this example, we can use the same name for the interface as for the initialized variable because in TypeScript type names and variable names do not conflict: each lexical scope contains a variable declaration space and type declaration space (see section [2.3](#2.3) for more details). +The interface 'M' summarizes the externally visible behavior of namespace 'M'. In this example, we can use the same name for the interface as for the initialized variable because in TypeScript type names and variable names do not conflict: each lexical scope contains a variable declaration space and type declaration space (see section [2.3](#2.3) for more details). -Module 'M' is an example of an *internal* module, because it is nested within the *global* module (see section [10](#10) for more details). The TypeScript compiler emits the following JavaScript code for this module. +The TypeScript compiler emits the following JavaScript code for the namespace: ```TypeScript var M; @@ -765,9 +769,11 @@ var M; })(M || (M = {})); ``` -In this case, the compiler assumes that the module object resides in global variable 'M', which may or may not have been initialized to the desired module object. +In this case, the compiler assumes that the namespace object resides in global variable 'M', which may or may not have been initialized to the desired namespace object. -TypeScript also supports *external* modules, which are files that contain top-level *export* and *import *directives. For this type of module the TypeScript compiler will emit code whose module closure and module object implementation vary according to the specified dynamic loading system, for example, the Asynchronous Module Definition system. +## 1.11 Modules + +TypeScript also supports ECMAScript 6 modules, which are files that contain top-level *export* and *import* directives. For this type of module the TypeScript compiler can emit both ECMAScript 6 compliant code and down-level ECMAScript 3 or 5 compliant code for a variety of module loading systems, including CommonJS, Asynchronous Module Definition (AMD), and Universal Module Definition (UMD).
@@ -1113,7 +1119,20 @@ var c = abc.charAt(2); // Property of String interface ###
3.2.4 The Symbol Type -*TODO: [Symbols](https://github.com/Microsoft/TypeScript/pull/1978)*. +The Symbol primitive type corresponds to the similarly named JavaScript primitive type and represents unique tokens that may be used as keys for object properties. + +The `symbol` keyword references the Symbol primitive type. Symbol values are obtained using the global object 'Symbol' which has a number of methods and properties and can be invoked as a function. In particular, the global object 'Symbol' defines a number of well-known symbols ([2.2.3](#2.2.3)) that can be used in a manner similar to identifiers. Note that the 'Symbol' object is available only in ECMAScript 6 environments. + +For purposes of determining type relationships (section [3.11](#3.11)) and accessing properties (section [4.13](#4.13)), the Symbol primitive type behaves as an object type with the same properties as the global interface type 'Symbol'. + +Some examples: + +```TypeScript +var secretKey = Symbol(); +var obj = {}; +obj[secretKey] = "secret message"; // Use symbol as property key +obj[Symbol.toStringTag] = "test"; // Use of well-known symbol +``` ### 3.2.5 The Void Type @@ -1418,7 +1437,7 @@ Type parameter names must be unique. A compile-time error occurs if two or more The scope of a type parameter extends over the entire declaration with which the type parameter list is associated, with the exception of static member declarations in classes. -Each type parameter has an associated type parameter ***constraint*** that establishes an upper bound for type arguments. Omitting a constraint corresponds to specifying the empty object type `{}`. Type parameters declared in a particular type parameter list may not be referenced in constraints in that type parameter list. +Each type parameter has an associated type parameter ***constraint*** that establishes an upper bound for type arguments. Omitting a constraint or specifying type `any` as the constraint corresponds to specifying the empty object type `{}`. Type parameters declared in a particular type parameter list may not be referenced in constraints in that type parameter list. The ***base constraint*** of a type parameter *T* is defined as follows: @@ -2105,7 +2124,7 @@ The ***apparent members*** of a type are the members observed in subtype, supert * The apparent members of the primitive types Number, Boolean, and String are the apparent members of the global interface types 'Number', 'Boolean', and 'String' respectively. * The apparent members of an enum type are the apparent members of the global interface type 'Number'. -* The apparent members of a type parameter are the apparent members of the base constraint (section [3.6.1](#3.6.1)) of that type parameter. +* The apparent members of a type parameter are the apparent members of the constraint (section [3.6.1](#3.6.1)) of that type parameter. * The apparent members of an object type *T* are the combination of the following: * The declared and/or inherited members of *T*. * The properties of the global interface type 'Object' that aren't hidden by properties with the same name in *T*. @@ -2118,8 +2137,8 @@ The ***apparent members*** of a type are the members observed in subtype, supert * When all constituent types of *U* have an apparent numeric index signature, *U* has an apparent numeric index signature of a union type of the respective numeric index signature types. * The apparent members of an intersection type *I* are determined as follows: * When one of more constituent types of *I* have an apparent property named *N*, *I* has an apparent property named *N* of an intersection type of the respective property types. - * When one or more constituent types of I have a call signature S, I has the apparent call signature S. The signatures are ordered as a concatenation of the signatures of each constituent type in the order of the constituent types within *I*. - * When one or more constituent types of I have a construct signature S, I has the apparent construct signature S. The signatures are ordered as a concatenation of the signatures of each constituent type in the order of the constituent types within *I*. + * When one or more constituent types of *I* have a call signature *S*, *I* has the apparent call signature *S*. The signatures are ordered as a concatenation of the signatures of each constituent type in the order of the constituent types within *I*. + * When one or more constituent types of *I* have a construct signature *S*, *I* has the apparent construct signature *S*. The signatures are ordered as a concatenation of the signatures of each constituent type in the order of the constituent types within *I*. * When one or more constituent types of *I* have an apparent string index signature, *I* has an apparent string index signature of an intersection type of the respective string index signature types. * When one or more constituent types of *I* have an apparent numeric index signature, *I* has an apparent numeric index signature of an intersection type of the respective numeric index signature types. @@ -2177,7 +2196,7 @@ the variables 'a' and 'b' are of identical types because the two type references ### 3.11.3 Subtypes and Supertypes -*S* is a ***subtype*** of a type *T*, and *T* is a ***supertype*** of *S*, if one of the following is true: +*S* is a ***subtype*** of a type *T*, and *T* is a ***supertype*** of *S*, if *S* has no excess properties with respect to *T* ([3.11.5](#3.11.5)) and one of the following is true: * *S* and *T* are identical types. * *T* is the Any type. @@ -2185,13 +2204,12 @@ the variables 'a' and 'b' are of identical types because the two type references * *S* is the Null type and *T* is not the Undefined type. * *S* is an enum type and *T* is the primitive type Number. * *S* is a string literal type and *T* is the primitive type String. -* *S* and *T* are type parameters, and *S* is directly or indirectly constrained to *T*. -* *S* is a type parameter whose base constraint is a union or intersection type that is a subtype of *T*. * *S* is a union type and each constituent type of *S* is a subtype of *T*. * *S* is an intersection type and at least one constituent type of *S* is a subtype of *T*. * *T* is a union type and *S* is a subtype of at least one constituent type of *T*. * *T* is an intersection type and *S* is a subtype of each constituent type of *T*. -* *S* is an object type, a type parameter, or the Number, Boolean, or String primitive type, *T* is an object type, and for each member *M* in *T*, one of the following is true: +* *S* is a type parameter and the constraint of *S* is a subtype of *T*. +* *S* is an object type, an intersection type, an enum type, or the Number, Boolean, or String primitive type, *T* is an object type, and for each member *M* in *T*, one of the following is true: * *M* is a property and *S* has an apparent property *N* where * *M* and *N* have the same name, * the type of *N* is a subtype of that of *M*, @@ -2202,8 +2220,8 @@ the variables 'a' and 'b' are of identical types because the two type references * *M* has a rest parameter or the number of non-optional parameters in *N* is less than or equal to the total number of parameters in *M*, * for parameter positions that are present in both signatures, each parameter type in *N* is a subtype or supertype of the corresponding parameter type in *M*, and * the result type of *M* is Void, or the result type of *N* is a subtype of that of *M*. - * *M* is a string index signature of type *U* and *S* has an apparent string index signature of a type that is a subtype of *U*. - * *M* is a numeric index signature of type *U* and *S* has an apparent string or numeric index signature of a type that is a subtype of *U*. + * *M* is a string index signature of type *U*, and *U* is the Any type or *S* has an apparent string index signature of a type that is a subtype of *U*. + * *M* is a numeric index signature of type *U*, and *U* is the Any type or *S* has an apparent string or numeric index signature of a type that is a subtype of *U*. When comparing call or construct signatures, parameter names are ignored and rest parameters correspond to an unbounded expansion of optional parameters of the rest parameter element type. @@ -2215,9 +2233,7 @@ Also note that type parameters are not considered object types. Thus, the only s Types are required to be assignment compatible in certain circumstances, such as expression and variable types in assignment statements and argument and parameter types in function calls. -*TODO: Update this section with rules for [strict object literal assignment checking](https://github.com/Microsoft/TypeScript/pull/3823)*. - -*S* is ***assignable to*** a type *T*, and *T* is ***assignable from*** *S*, if one of the following is true: +*S* is ***assignable to*** a type *T*, and *T* is ***assignable from*** *S*, if *S* has no excess properties with respect to *T* ([3.11.5](#3.11.5)) and one of the following is true: * *S* and *T* are identical types. * *S* or *T* is the Any type. @@ -2225,13 +2241,12 @@ Types are required to be assignment compatible in certain circumstances, such as * *S* is the Null type and *T* is not the Undefined type. * *S* or *T* is an enum type and* *the other is the primitive type Number. * *S* is a string literal type and *T* is the primitive type String. -* *S* and *T* are type parameters, and *S* is directly or indirectly constrained to *T*. -* *S* is a type parameter whose base constraint is a union or intersection type that is assignable to *T*. * *S* is a union type and each constituent type of *S* is assignable to *T*. * *S* is an intersection type and at least one constituent type of *S* is assignable to *T*. * *T* is a union type and *S* is assignable to at least one constituent type of *T*. * *T* is an intersection type and *S* is assignable to each constituent type of *T*. -* *S* is an object type, a type parameter, or the Number, Boolean, or String primitive type, *T* is an object type, and for each member *M* in *T*, one of the following is true: +* *S* is a type parameter and the constraint of *S* is assignable to *T*. +* *S* is an object type, an intersection type, an enum type, or the Number, Boolean, or String primitive type, *T* is an object type, and for each member *M* in *T*, one of the following is true: * *M* is a property and *S* has an apparent property *N* where * *M* and *N* have the same name, * the type of *N* is assignable to that of *M*, @@ -2267,19 +2282,76 @@ foo({ id: 1234, name: false }); // Error, name of wrong type foo({ name: "hello" }); // Error, id required but missing ``` -### 3.11.5 Contextual Signature Instantiation +### 3.11.5 Excess Properties + +The subtype and assignment compatibility relationships require that source types have no excess properties with respect to their target types. The purpose of this check is to detect excess or misspelled properties in object literals. + +A source type *S* is considered to have excess properties with respect to a target type *T* if + +* *S* is a fresh object literal type, as defined below, and +* *S* has one or more properties that aren't expected in *T*. + +A property *P* is said to be expected in a type *T* if one of the following is true: + +* *T* is not an object, union, or intersection type. +* *T* is an object type and + * *T* has a property with the same name as *P*, + * *T* has a string or numeric index signature, + * *T* has no properties, or + * *T* is the global type 'Object'. +* *T* is a union or intersection type and *P* is expected in at least one of the constituent types of *T*. + +The type inferred for an object literal (as described in section [4.5](#4.5)) is considered a ***fresh object literal type***. The freshness disappears when an object literal type is widened ([3.12](#3.12)) or is the type of the expression in a type assertion ([4.16](#4.16)). + +Consider the following example: + +```TypeScript +interface CompilerOptions { + strict?: boolean; + sourcePath?: string; + targetPath?: string; +} + +var options: CompilerOptions = { + strict: true, + sourcepath: "./src", // Error, excess or misspelled property + targetpath: "./bin" // Error, excess or misspelled property +}; +``` + +The 'CompilerOptions' type contains only optional properties, so without the excess property check, *any* object literal would be assignable to the 'options' variable (because a misspelled property would just be considered an excess property of a different name). + +In cases where excess properties are expected, an index signature can be added to the target type as an indicator of intent: + +```TypeScript +interface InputElement { + name: string; + visible?: boolean; + [x: string]: any; // Allow additional properties of any type +} + +var address: InputElement = { + name: "Address", + visible: true, + help: "Enter address here", // Allowed because of index signature + shortcut: "Alt-A" // Allowed because of index signature +}; +``` + +### 3.11.6 Contextual Signature Instantiation During type argument inference in a function call (section [4.15.2](#4.15.2)) it is in certain circumstances necessary to instantiate a generic call signature of an argument expression in the context of a non-generic call signature of a parameter such that further inferences can be made. A generic call signature *A* is ***instantiated in the context of*** non-generic call signature *B* as follows: -* Using the process described in [3.11.6](#3.11.6), inferences for *A*'s type parameters are made from each parameter type in *B* to the corresponding parameter type in *A* for those parameter positions that are present in both signatures, where rest parameters correspond to an unbounded expansion of optional parameters of the rest parameter element type. +* Using the process described in [3.11.7](#3.11.7), inferences for *A*'s type parameters are made from each parameter type in *B* to the corresponding parameter type in *A* for those parameter positions that are present in both signatures, where rest parameters correspond to an unbounded expansion of optional parameters of the rest parameter element type. * The inferred type argument for each type parameter is the union type of the set of inferences made for that type parameter. However, if the union type does not satisfy the constraint of the type parameter, the inferred type argument is instead the constraint. -### 3.11.6 Type Inference +### 3.11.7 Type Inference In certain contexts, inferences for a given set of type parameters are made *from* a type *S*, in which those type parameters do not occur, *to* another type *T*, in which those type parameters do occur. Inferences consist of a set of candidate type arguments collected for each of the type parameters. The inference process recursively relates *S* and *T* to gather as many inferences as possible: * If *T* is one of the type parameters for which inferences are being made, *S* is added to the set of inferences for that type parameter. * Otherwise, if *S* and *T* are references to the same generic type, inferences are made from each type argument in *S* to each corresponding type argument in *T*. +* Otherwise, if *S* and *T* are tuple types with the same number of elements, inferences are made from each element type in *S* to each corresponding element type in *T*. * Otherwise, if *T* is a union or intersection type: * First, inferences are made from *S* to each constituent type in *T* that isn't simply one of the type parameters for which inferences are being made. * If the first step produced no inferences then if T is a union type and exactly one constituent type in *T* is simply a type parameter for which inferences are being made, inferences are made from *S* to that type parameter. @@ -2294,7 +2366,7 @@ In certain contexts, inferences for a given set of type parameters are made *fro When comparing call or construct signatures, signatures in *S* correspond to signatures of the same kind in *T* pairwise in declaration order. If *S* and *T* have different numbers of a given kind of signature, the excess *first* signatures in declaration order of the longer list are ignored. -### 3.11.7 Recursive Types +### 3.11.8 Recursive Types Classes and interfaces can reference themselves in their internal structure, in effect creating recursive types with infinite nesting. For example, the type @@ -2343,7 +2415,7 @@ The following example shows the results of widening types to produce inferred va ```TypeScript var a = null; // var a: any var b = undefined; // var b: any -var c = { x: 0, y: null }; // var c: { x: number, y: any } +var c = { x: 0, y: null }; // var c: { x: number, y: any } var d = [ null, undefined ]; // var d: any[] ``` @@ -2826,13 +2898,13 @@ Type argument inference produces a set of candidate types for each type paramete In order to compute candidate types, the argument list is processed as follows: * Initially all inferred type arguments are considered ***unfixed*** with an empty set of candidate types. -* Proceeding from left to right, each argument expression *e* is ***inferentially typed*** by its corresponding parameter type *P*, possibly causing some inferred type arguments to become ***fixed***, and candidate type inferences (section [3.11.6](#3.11.6)) are made for unfixed inferred type arguments from the type computed for *e* to *P*. +* Proceeding from left to right, each argument expression *e* is ***inferentially typed*** by its corresponding parameter type *P*, possibly causing some inferred type arguments to become ***fixed***, and candidate type inferences (section [3.11.7](#3.11.7)) are made for unfixed inferred type arguments from the type computed for *e* to *P*. The process of inferentially typing an expression *e* by a type *T* is the same as that of contextually typing *e* by *T*, with the following exceptions: * Where expressions contained within *e* would be contextually typed, they are instead inferentially typed. * When a function expression is inferentially typed (section [4.10](#4.10)) and a type assigned to a parameter in that expression references type parameters for which inferences are being made, the corresponding inferred type arguments to become ***fixed*** and no further candidate inferences are made for them. -* If *e* is an expression of a function type that contains exactly one generic call signature and no other members, and *T* is a function type with exactly one non-generic call signature and no other members, then any inferences made for type parameters referenced by the parameters of *T*'s call signature are ***fixed***, and *e*'s type is changed to a function type with *e*'s call signature instantiated in the context of *T*'s call signature (section [3.11.5](#3.11.5)). +* If *e* is an expression of a function type that contains exactly one generic call signature and no other members, and *T* is a function type with exactly one non-generic call signature and no other members, then any inferences made for type parameters referenced by the parameters of *T*'s call signature are ***fixed***, and *e*'s type is changed to a function type with *e*'s call signature instantiated in the context of *T*'s call signature (section [3.11.6](#3.11.6)). An example: diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e842f9a404..50ba634b58 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -139,7 +139,7 @@ namespace ts { function getDeclarationName(node: Declaration): string { if (node.name) { if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) { - return '"' + (node.name).text + '"'; + return `"${(node.name).text}"`; } if (node.name.kind === SyntaxKind.ComputedPropertyName) { let nameExpression = (node.name).expression; @@ -830,7 +830,7 @@ namespace ts { // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the // string to contain unicode escapes (as per ES5). - return nodeText === '"use strict"' || nodeText === "'use strict'"; + return nodeText === "\"use strict\"" || nodeText === "'use strict'"; } function bindWorker(node: Node) { @@ -930,7 +930,7 @@ namespace ts { function bindSourceFileIfExternalModule() { setExportContextFlag(file); if (isExternalModule(file)) { - bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"'); + bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"`); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c37189488b..e1b7ba42f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -211,6 +211,9 @@ namespace ts { let assignableRelation: Map = {}; let identityRelation: Map = {}; + // This is for caching the result of getSymbolDisplayBuilder. Do not access directly. + let _displayBuilder: SymbolDisplayBuilder; + type TypeSystemEntity = Symbol | Type | Signature; const enum TypeSystemPropertyName { @@ -965,7 +968,7 @@ namespace ts { if (!moduleName) return; let isRelative = isExternalModuleNameRelative(moduleName); if (!isRelative) { - let symbol = getSymbol(globals, '"' + moduleName + '"', SymbolFlags.ValueModule); + let symbol = getSymbol(globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule); if (symbol) { return symbol; } @@ -1490,8 +1493,6 @@ namespace ts { return undefined; } - // This is for caching the result of getSymbolDisplayBuilder. Do not access directly. - let _displayBuilder: SymbolDisplayBuilder; function getSymbolDisplayBuilder(): SymbolDisplayBuilder { function getNameOfSymbol(symbol: Symbol): string { @@ -3448,7 +3449,7 @@ namespace ts { // type, a property is considered known if it is known in any constituent type. function isKnownProperty(type: Type, name: string): boolean { if (type.flags & TypeFlags.ObjectType && type !== globalObjectType) { - var resolved = resolveStructuredTypeMembers(type); + const resolved = resolveStructuredTypeMembers(type); return !!(resolved.properties.length === 0 || resolved.stringIndexType || resolved.numberIndexType || @@ -4668,19 +4669,21 @@ namespace ts { let result: Ternary; // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) return Ternary.True; - if (relation !== identityRelation) { - if (isTypeAny(target)) return Ternary.True; - if (source === undefinedType) return Ternary.True; - if (source === nullType && target !== undefinedType) return Ternary.True; - if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True; - if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True; - if (relation === assignableRelation) { - if (isTypeAny(source)) return Ternary.True; - if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True; - } + if (relation === identityRelation) { + return isIdenticalTo(source, target); } - if (relation !== identityRelation && source.flags & TypeFlags.FreshObjectLiteral) { + if (isTypeAny(target)) return Ternary.True; + if (source === undefinedType) return Ternary.True; + if (source === nullType && target !== undefinedType) return Ternary.True; + if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True; + if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True; + if (relation === assignableRelation) { + if (isTypeAny(source)) return Ternary.True; + if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True; + } + + if (source.flags & TypeFlags.FreshObjectLiteral) { if (hasExcessProperties(source, target, reportErrors)) { if (reportErrors) { reportRelationError(headMessage, source, target); @@ -4696,78 +4699,66 @@ namespace ts { let saveErrorInfo = errorInfo; - if (source.flags & TypeFlags.Reference && target.flags & TypeFlags.Reference && (source).target === (target).target) { - // We have type references to same target type, see if relationship holds for all type arguments - if (result = typesRelatedTo((source).typeArguments, (target).typeArguments, reportErrors)) { + // Note that the "each" checks must precede the "some" checks to produce the correct results + if (source.flags & TypeFlags.Union) { + if (result = eachTypeRelatedToType(source, target, reportErrors)) { return result; } } - else if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) { - if (result = typeParameterRelatedTo(source, target, reportErrors)) { + else if (target.flags & TypeFlags.Intersection) { + if (result = typeRelatedToEachType(source, target, reportErrors)) { return result; } } - else if (relation !== identityRelation) { - // Note that the "each" checks must precede the "some" checks to produce the correct results - if (source.flags & TypeFlags.Union) { - if (result = eachTypeRelatedToType(source, target, reportErrors)) { - return result; - } - } - else if (target.flags & TypeFlags.Intersection) { - if (result = typeRelatedToEachType(source, target, reportErrors)) { - return result; - } - } - else { - // It is necessary to try "each" checks on both sides because there may be nested "some" checks - // on either side that need to be prioritized. For example, A | B = (A | B) & (C | D) or - // A & B = (A & B) | (C & D). - if (source.flags & TypeFlags.Intersection) { - // If target is a union type the following check will report errors so we suppress them here - if (result = someTypeRelatedToType(source, target, reportErrors && !(target.flags & TypeFlags.Union))) { - return result; - } - } - if (target.flags & TypeFlags.Union) { - if (result = typeRelatedToSomeType(source, target, reportErrors)) { - return result; - } - } - } - } else { - if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union || - source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) { - if (result = eachTypeRelatedToSomeType(source, target)) { - if (result &= eachTypeRelatedToSomeType(target, source)) { - return result; - } + // It is necessary to try "some" checks on both sides because there may be nested "each" checks + // on either side that need to be prioritized. For example, A | B = (A | B) & (C | D) or + // A & B = (A & B) | (C & D). + if (source.flags & TypeFlags.Intersection) { + // If target is a union type the following check will report errors so we suppress them here + if (result = someTypeRelatedToType(source, target, reportErrors && !(target.flags & TypeFlags.Union))) { + return result; + } + } + if (target.flags & TypeFlags.Union) { + if (result = typeRelatedToSomeType(source, target, reportErrors)) { + return result; } } } - // Even if relationship doesn't hold for unions, type parameters, or generic type references, - // it may hold in a structural comparison. - // Report structural errors only if we haven't reported any errors yet - let reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo; - // Identity relation does not use apparent type - let sourceOrApparentType = relation === identityRelation ? source : getApparentType(source); - // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates - // to X. Failing both of those we want to check if the aggregation of A and B's members structurally - // relates to X. Thus, we include intersection types on the source side here. - if (sourceOrApparentType.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) { - if (result = objectTypeRelatedTo(sourceOrApparentType, target, reportStructuralErrors)) { + if (source.flags & TypeFlags.TypeParameter) { + let constraint = getConstraintOfTypeParameter(source); + if (!constraint || constraint.flags & TypeFlags.Any) { + constraint = emptyObjectType; + } + // Report constraint errors only if the constraint is not the empty object type + let reportConstraintErrors = reportErrors && constraint !== emptyObjectType; + if (result = isRelatedTo(constraint, target, reportConstraintErrors)) { errorInfo = saveErrorInfo; return result; } } - else if (source.flags & TypeFlags.TypeParameter && sourceOrApparentType.flags & TypeFlags.UnionOrIntersection) { - // We clear the errors first because the following check often gives a better error than - // the union or intersection comparison above if it is applicable. - errorInfo = saveErrorInfo; - if (result = isRelatedTo(sourceOrApparentType, target, reportErrors)) { - return result; + else { + if (source.flags & TypeFlags.Reference && target.flags & TypeFlags.Reference && (source).target === (target).target) { + // We have type references to same target type, see if relationship holds for all type arguments + if (result = typesRelatedTo((source).typeArguments, (target).typeArguments, reportErrors)) { + return result; + } + } + // Even if relationship doesn't hold for unions, intersections, or generic type references, + // it may hold in a structural comparison. + let apparentType = getApparentType(source); + // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates + // to X. Failing both of those we want to check if the aggregation of A and B's members structurally + // relates to X. Thus, we include intersection types on the source side here. + if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) { + // Report structural errors only if we haven't reported any errors yet + let reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo; + if (result = objectTypeRelatedTo(apparentType, target, reportStructuralErrors)) { + errorInfo = saveErrorInfo; + return result; + } } } @@ -4777,6 +4768,31 @@ namespace ts { return Ternary.False; } + function isIdenticalTo(source: Type, target: Type): Ternary { + let result: Ternary; + if (source.flags & TypeFlags.ObjectType && target.flags & TypeFlags.ObjectType) { + if (source.flags & TypeFlags.Reference && target.flags & TypeFlags.Reference && (source).target === (target).target) { + // We have type references to same target type, see if all type arguments are identical + if (result = typesRelatedTo((source).typeArguments, (target).typeArguments, /*reportErrors*/ false)) { + return result; + } + } + return objectTypeRelatedTo(source, target, /*reportErrors*/ false); + } + if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) { + return typeParameterIdenticalTo(source, target); + } + if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union || + source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) { + if (result = eachTypeRelatedToSomeType(source, target)) { + if (result &= eachTypeRelatedToSomeType(target, source)) { + return result; + } + } + } + return Ternary.False; + } + function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { for (let prop of getPropertiesOfObjectType(source)) { if (!isKnownProperty(target, prop.name)) { @@ -4861,29 +4877,18 @@ namespace ts { return result; } - function typeParameterRelatedTo(source: TypeParameter, target: TypeParameter, reportErrors: boolean): Ternary { - if (relation === identityRelation) { - if (source.symbol.name !== target.symbol.name) { - return Ternary.False; - } - // covers case when both type parameters does not have constraint (both equal to noConstraintType) - if (source.constraint === target.constraint) { - return Ternary.True; - } - if (source.constraint === noConstraintType || target.constraint === noConstraintType) { - return Ternary.False; - } - return isRelatedTo(source.constraint, target.constraint, reportErrors); - } - else { - while (true) { - let constraint = getConstraintOfTypeParameter(source); - if (constraint === target) return Ternary.True; - if (!(constraint && constraint.flags & TypeFlags.TypeParameter)) break; - source = constraint; - } + function typeParameterIdenticalTo(source: TypeParameter, target: TypeParameter): Ternary { + if (source.symbol.name !== target.symbol.name) { return Ternary.False; } + // covers case when both type parameters does not have constraint (both equal to noConstraintType) + if (source.constraint === target.constraint) { + return Ternary.True; + } + if (source.constraint === noConstraintType || target.constraint === noConstraintType) { + return Ternary.False; + } + return isIdenticalTo(source.constraint, target.constraint); } // Determine if two object types are related by structure. First, check if the result is already available in the global cache. @@ -5732,6 +5737,14 @@ namespace ts { inferFromTypes(sourceTypes[i], targetTypes[i]); } } + else if (source.flags & TypeFlags.Tuple && target.flags & TypeFlags.Tuple && (source).elementTypes.length === (target).elementTypes.length) { + // If source and target are tuples of the same size, infer from element types + let sourceTypes = (source).elementTypes; + let targetTypes = (target).elementTypes; + for (let i = 0; i < sourceTypes.length; i++) { + inferFromTypes(sourceTypes[i], targetTypes[i]); + } + } else if (target.flags & TypeFlags.UnionOrIntersection) { let targetTypes = (target).types; let typeParameterCount = 0; @@ -6207,14 +6220,20 @@ namespace ts { } function getNarrowedType(originalType: Type, narrowedTypeCandidate: Type) { - // Narrow to the target type if it's a subtype of the current type - if (isTypeSubtypeOf(narrowedTypeCandidate, originalType)) { + // If the current type is a union type, remove all constituents that aren't assignable to target. If that produces + // 0 candidates, fall back to the assignability check + if (originalType.flags & TypeFlags.Union) { + let assignableConstituents = filter((originalType).types, t => isTypeAssignableTo(t, narrowedTypeCandidate)); + if (assignableConstituents.length) { + return getUnionType(assignableConstituents); + } + } + + if (isTypeAssignableTo(narrowedTypeCandidate, originalType)) { + // Narrow to the target type if it's assignable to the current type return narrowedTypeCandidate; } - // If the current type is a union type, remove all constituents that aren't subtypes of the target. - if (originalType.flags & TypeFlags.Union) { - return getUnionType(filter((originalType).types, t => isTypeSubtypeOf(t, narrowedTypeCandidate))); - } + return originalType; } @@ -7337,7 +7356,7 @@ namespace ts { } // Wasn't found - error(node, Diagnostics.Property_0_does_not_exist_on_type_1, (node.tagName).text, 'JSX.' + JsxNames.IntrinsicElements); + error(node, Diagnostics.Property_0_does_not_exist_on_type_1, (node.tagName).text, "JSX." + JsxNames.IntrinsicElements); return unknownSymbol; } else { @@ -7377,7 +7396,7 @@ namespace ts { function getJsxElementInstanceType(node: JsxOpeningLikeElement) { // There is no such thing as an instance type for a non-class element. This // line shouldn't be hit. - Debug.assert(!!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement), 'Should not call getJsxElementInstanceType on non-class Element'); + Debug.assert(!!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement), "Should not call getJsxElementInstanceType on non-class Element"); let classSymbol = getJsxElementTagSymbol(node); if (classSymbol === unknownSymbol) { @@ -7557,7 +7576,7 @@ namespace ts { // be marked as 'used' so we don't incorrectly elide its import. And if there // is no 'React' symbol in scope, we should issue an error. if (compilerOptions.jsx === JsxEmit.React) { - let reactSym = resolveName(node.tagName, 'React', SymbolFlags.Value, Diagnostics.Cannot_find_name_0, 'React'); + let reactSym = resolveName(node.tagName, "React", SymbolFlags.Value, Diagnostics.Cannot_find_name_0, "React"); if (reactSym) { getSymbolLinks(reactSym).referenced = true; } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index be6d083e3a..9a984b9a2f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -335,7 +335,7 @@ namespace ts { * @param fileName The path to the config file */ export function readConfigFile(fileName: string): { config?: any; error?: Diagnostic } { - let text = ''; + let text = ""; try { text = sys.readFile(fileName); } @@ -423,7 +423,7 @@ namespace ts { fileNames = map(json["files"], s => combinePaths(basePath, s)); } else { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, 'files', 'Array')); + errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array")); } } else { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ec171d4aee..3305d4b149 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -219,10 +219,10 @@ namespace ts { export function reduceLeft(array: T[], f: (a: U, x: T) => U, initial: U): U; export function reduceLeft(array: T[], f: (a: U, x: T) => U, initial?: U): U { if (array) { - var count = array.length; + const count = array.length; if (count > 0) { - var pos = 0; - var result = arguments.length <= 2 ? array[pos++] : initial; + let pos = 0; + let result = arguments.length <= 2 ? array[pos++] : initial; while (pos < count) { result = f(result, array[pos++]); } @@ -236,9 +236,9 @@ namespace ts { export function reduceRight(array: T[], f: (a: U, x: T) => U, initial: U): U; export function reduceRight(array: T[], f: (a: U, x: T) => U, initial?: U): U { if (array) { - var pos = array.length - 1; + let pos = array.length - 1; if (pos >= 0) { - var result = arguments.length <= 2 ? array[pos--] : initial; + let result = arguments.length <= 2 ? array[pos--] : initial; while (pos >= 0) { result = f(result, array[pos--]); } @@ -523,7 +523,7 @@ namespace ts { if (path.lastIndexOf("file:///", 0) === 0) { return "file:///".length; } - let idx = path.indexOf('://'); + let idx = path.indexOf("://"); if (idx !== -1) { return idx + "://".length; } @@ -805,4 +805,4 @@ namespace ts { Debug.assert(false, message); } } -} +} diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index cb5eb86466..e5bdb9a258 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -380,7 +380,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function base64VLQFormatEncode(inValue: number) { function base64FormatEncode(inValue: number) { if (inValue < 64) { - return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.charAt(inValue); + return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(inValue); } throw TypeError(inValue + ": not a 64 based value"); } @@ -895,7 +895,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // Any template literal or string literal with an extended escape // (e.g. "\u{0067}") will need to be downleveled as a escaped string literal. if (languageVersion < ScriptTarget.ES6 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) { - return getQuotedEscapedLiteralText('"', node.text, '"'); + return getQuotedEscapedLiteralText("\"", node.text, "\""); } // If we don't need to downlevel and we can reach the original source text using @@ -908,15 +908,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // or an escaped quoted form of the original text if it's string-like. switch (node.kind) { case SyntaxKind.StringLiteral: - return getQuotedEscapedLiteralText('"', node.text, '"'); + return getQuotedEscapedLiteralText("\"", node.text, "\""); case SyntaxKind.NoSubstitutionTemplateLiteral: - return getQuotedEscapedLiteralText('`', node.text, '`'); + return getQuotedEscapedLiteralText("`", node.text, "`"); case SyntaxKind.TemplateHead: - return getQuotedEscapedLiteralText('`', node.text, '${'); + return getQuotedEscapedLiteralText("`", node.text, "${"); case SyntaxKind.TemplateMiddle: - return getQuotedEscapedLiteralText('}', node.text, '${'); + return getQuotedEscapedLiteralText("}", node.text, "${"); case SyntaxKind.TemplateTail: - return getQuotedEscapedLiteralText('}', node.text, '`'); + return getQuotedEscapedLiteralText("}", node.text, "`"); case SyntaxKind.NumericLiteral: return node.text; } @@ -947,7 +947,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi text = text.replace(/\r\n?/g, "\n"); text = escapeString(text); - write('"' + text + '"'); + write(`"${text}"`); } function emitDownlevelTaggedTemplateArray(node: TaggedTemplateExpression, literalEmitter: (literal: LiteralExpression) => void) { @@ -1134,9 +1134,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi /// 'Div' for upper-cased or dotted names function emitTagName(name: Identifier|QualifiedName) { if (name.kind === SyntaxKind.Identifier && isIntrinsicJsxName((name).text)) { - write('"'); + write("\""); emit(name); - write('"'); + write("\""); } else { emit(name); @@ -1148,9 +1148,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi /// about keywords, just non-identifier characters function emitAttributeName(name: Identifier) { if (/[A-Za-z_]+[\w*]/.test(name.text)) { - write('"'); + write("\""); emit(name); - write('"'); + write("\""); } else { emit(name); @@ -1248,10 +1248,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // Don't emit empty strings if (children[i].kind === SyntaxKind.JsxText) { let text = getTextToEmit(children[i]); - if(text !== undefined) { - write(', "'); + if (text !== undefined) { + write(", \""); write(text); - write('"'); + write("\""); } } else { @@ -1491,7 +1491,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (declaration.kind === SyntaxKind.ImportClause) { // Identifier references default import write(getGeneratedNameForNode(declaration.parent)); - write(languageVersion === ScriptTarget.ES3 ? '["default"]' : ".default"); + write(languageVersion === ScriptTarget.ES3 ? "[\"default\"]" : ".default"); return; } else if (declaration.kind === SyntaxKind.ImportSpecifier) { @@ -2006,12 +2006,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean { - if (compilerOptions.isolatedModules) { - // do not inline enum values in separate compilation mode - return false; - } - - let constantValue = resolver.getConstantValue(node); + let constantValue = tryGetConstEnumValue(node); if (constantValue !== undefined) { write(constantValue.toString()); if (!compilerOptions.removeComments) { @@ -2022,6 +2017,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } return false; } + + function tryGetConstEnumValue(node: Node): number { + if (compilerOptions.isolatedModules) { + return undefined; + } + + return node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.ElementAccessExpression + ? resolver.getConstantValue(node) + : undefined + } // Returns 'true' if the code was actually indented, false otherwise. // If the code is not indented, an optional valueToWriteWhenNotIndenting will be @@ -2054,10 +2059,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi let indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken); // 1 .toString is a valid property access, emit a space after the literal + // Also emit a space if expression is a integer const enum value - it will appear in generated code as numeric literal let shouldEmitSpace: boolean; - if (!indentedBeforeDot && node.expression.kind === SyntaxKind.NumericLiteral) { - let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression); - shouldEmitSpace = text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0; + if (!indentedBeforeDot) { + if (node.expression.kind === SyntaxKind.NumericLiteral) { + // check if numeric literal was originally written with a dot + let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression); + shouldEmitSpace = text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0; + } + else { + // check if constant enum value is integer + let constantValue = tryGetConstEnumValue(node.expression); + // isFinite handles cases when constantValue is undefined + shouldEmitSpace = isFinite(constantValue) && Math.floor(constantValue) === constantValue; + } } if (shouldEmitSpace) { @@ -4255,11 +4270,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi emitDetachedComments(ctor.body.statements); } emitCaptureThisForNodeIfNecessary(node); + let superCall: ExpressionStatement; if (ctor) { emitDefaultValueAssignments(ctor); emitRestParameter(ctor); if (baseTypeElement) { - var superCall = findInitialSuperCall(ctor); + superCall = findInitialSuperCall(ctor); if (superCall) { writeLine(); emit(superCall); @@ -4936,7 +4952,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi let temp = createAndRecordTempVariable(TempFlags.Auto); write("(typeof ("); emitNodeWithoutSourceMap(temp); - write(" = ") + write(" = "); emitEntityNameAsExpression(typeName, /*useFallback*/ true); write(") === 'function' && "); emitNodeWithoutSourceMap(temp); @@ -4995,7 +5011,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // // For the rules on serializing the type of each parameter declaration, see `serializeTypeOfDeclaration`. if (node) { - var valueDeclaration: FunctionLikeDeclaration; + let valueDeclaration: FunctionLikeDeclaration; if (node.kind === SyntaxKind.ClassDeclaration) { valueDeclaration = getFirstConstructorWithBody(node); } @@ -5004,8 +5020,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } if (valueDeclaration) { - var parameters = valueDeclaration.parameters; - var parameterCount = parameters.length; + const parameters = valueDeclaration.parameters; + const parameterCount = parameters.length; if (parameterCount > 0) { for (var i = 0; i < parameterCount; i++) { if (i > 0) { @@ -5013,7 +5029,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } if (parameters[i].dotDotDotToken) { - var parameterType = parameters[i].type; + let parameterType = parameters[i].type; if (parameterType.kind === SyntaxKind.ArrayType) { parameterType = (parameterType).elementType; } @@ -5825,7 +5841,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi writeLine(); write("}"); writeLine(); - write(`${exportFunctionForFile}(exports);`) + write(`${exportFunctionForFile}(exports);`); decreaseIndent(); writeLine(); write("}"); @@ -6173,7 +6189,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // exports_(reexports); let reexportsVariableName = makeUniqueName("reexports"); writeLine(); - write(`var ${reexportsVariableName} = {};`) + write(`var ${reexportsVariableName} = {};`); writeLine(); for (let e of (importNode).exportClause.elements) { write(`${reexportsVariableName}["`); @@ -6439,7 +6455,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (isLineBreak(c)) { if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) { let part = text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1); - result = (result ? result + '" + \' \' + "' : '') + part; + result = (result ? result + "\" + ' ' + \"" : "") + part; } firstNonWhitespace = -1; } @@ -6452,7 +6468,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } if (firstNonWhitespace !== -1) { let part = text.substr(firstNonWhitespace); - result = (result ? result + '" + \' \' + "' : '') + part; + result = (result ? result + "\" + ' ' + \"" : "") + part; } return result; @@ -6477,9 +6493,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function emitJsxText(node: JsxText) { switch (compilerOptions.jsx) { case JsxEmit.React: - write('"'); + write("\""); write(trimReactWhitespace(node)); - write('"'); + write("\""); break; case JsxEmit.Preserve: @@ -6494,9 +6510,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi switch (compilerOptions.jsx) { case JsxEmit.Preserve: default: - write('{'); + write("{"); emit(node.expression); - write('}'); + write("}"); break; case JsxEmit.React: emit(node.expression); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 127d1b58ee..10ebe86368 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3148,7 +3148,7 @@ namespace ts { } function parseAwaitExpression() { - var node = createNode(SyntaxKind.AwaitExpression); + const node = createNode(SyntaxKind.AwaitExpression); nextToken(); node.expression = parseUnaryExpressionOrHigher(); return finishNode(node); @@ -3340,7 +3340,7 @@ namespace ts { case SyntaxKind.LessThanToken: return parseJsxElementOrSelfClosingElement(); } - Debug.fail('Unknown JSX child kind ' + token); + Debug.fail("Unknown JSX child kind " + token); } function parseJsxChildren(openingTagName: EntityName): NodeArray { @@ -5140,7 +5140,7 @@ namespace ts { // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. if (token === SyntaxKind.FromKeyword || (token === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { - parseExpected(SyntaxKind.FromKeyword) + parseExpected(SyntaxKind.FromKeyword); node.moduleSpecifier = parseModuleSpecifier(); } } @@ -6011,7 +6011,7 @@ namespace ts { return; function visitNode(node: IncrementalNode) { - let text = ''; + let text = ""; if (aggressiveChecks && shouldCheckNode(node)) { text = oldText.substring(node.pos, node.end); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 379177a9b9..7db8f24319 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -660,9 +660,9 @@ namespace ts { ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ || ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion); } - + /* @internal */ - // Creates a scanner over a (possibly unspecified) range of a piece of text. + // Creates a scanner over a (possibly unspecified) range of a piece of text. export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, languageVariant = LanguageVariant.Standard, @@ -1121,7 +1121,7 @@ namespace ts { // Special handling for shebang if (ch === CharacterCodes.hash && pos === 0 && isShebangTrivia(text, pos)) { - pos = scanShebangTrivia(text ,pos); + pos = scanShebangTrivia(text, pos); if (skipTrivia) { continue; } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 228b9516de..1730e45ee9 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -30,8 +30,8 @@ namespace ts { declare var global: any; declare var __filename: string; declare var Buffer: { - new (str: string, encoding ?: string): any; - } + new (str: string, encoding?: string): any; + }; declare class Enumerator { public atEnd(): boolean; @@ -188,13 +188,13 @@ namespace ts { }; } function getNodeSystem(): System { - var _fs = require("fs"); - var _path = require("path"); - var _os = require('os'); + const _fs = require("fs"); + const _path = require("path"); + const _os = require("os"); - var platform: string = _os.platform(); + const platform: string = _os.platform(); // win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive - var useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin"; + const useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin"; function readFile(fileName: string, encoding?: string): string { if (!_fs.existsSync(fileName)) { @@ -228,7 +228,7 @@ namespace ts { function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void { // If a BOM is required, emit one if (writeByteOrderMark) { - data = '\uFEFF' + data; + data = "\uFEFF" + data; } _fs.writeFileSync(fileName, data, "utf8"); @@ -271,10 +271,10 @@ namespace ts { newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write(s: string): void { - var buffer = new Buffer(s, 'utf8'); - var offset: number = 0; - var toWrite: number = buffer.length; - var written = 0; + const buffer = new Buffer(s, "utf8"); + let offset: number = 0; + let toWrite: number = buffer.length; + let written = 0; // 1 is a standard descriptor for stdout while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { offset += written; @@ -297,7 +297,7 @@ namespace ts { } callback(fileName); - }; + } }, resolvePath: function (path: string): string { return _path.resolve(path); diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 880180b133..22bd6d79b0 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -245,7 +245,7 @@ namespace ts { reportDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); } - function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError ?: (message: string) => void) { + function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) { // Return existing SourceFile object if one is available if (cachedProgram) { let sourceFile = cachedProgram.getSourceFile(fileName); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 312a366675..02416b95b8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1866,7 +1866,7 @@ namespace ts { function writeTrimmedCurrentLine(pos: number, nextLineStart: number) { let end = Math.min(comment.end, nextLineStart - 1); - let currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, ''); + let currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, ""); if (currentLineText) { // trimmed forward and ending spaces text writer.write(currentLineText); diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index b1d4330237..87e22e08cf 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -1,6 +1,6 @@ -/// -/// -/// +/// +/// +/// const enum CompilerTestType { Conformance, @@ -9,7 +9,7 @@ const enum CompilerTestType { } class CompilerBaselineRunner extends RunnerBase { - private basePath = 'tests/cases'; + private basePath = "tests/cases"; private testSuiteName: string; private errors: boolean; private emit: boolean; @@ -25,21 +25,21 @@ class CompilerBaselineRunner extends RunnerBase { this.decl = true; this.output = true; if (testType === CompilerTestType.Conformance) { - this.testSuiteName = 'conformance'; + this.testSuiteName = "conformance"; } else if (testType === CompilerTestType.Regressions) { - this.testSuiteName = 'compiler'; + this.testSuiteName = "compiler"; } else if (testType === CompilerTestType.Test262) { - this.testSuiteName = 'test262'; + this.testSuiteName = "test262"; } else { - this.testSuiteName = 'compiler'; // default to this for historical reasons + this.testSuiteName = "compiler"; // default to this for historical reasons } - this.basePath += '/' + this.testSuiteName; + this.basePath += "/" + this.testSuiteName; } public checkTestCodeOutput(fileName: string) { - describe('compiler tests for ' + fileName, () => { + describe("compiler tests for " + fileName, () => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Everything declared here should be cleared out in the "after" callback. let justName: string; @@ -64,14 +64,14 @@ class CompilerBaselineRunner extends RunnerBase { let createNewInstance = false; before(() => { - justName = fileName.replace(/^.*[\\\/]/, ''); // strips the fileName from the path. + justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path. content = Harness.IO.readFile(fileName); testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName); units = testCaseContent.testUnitData; tcSettings = testCaseContent.settings; createNewInstance = false; lastUnit = units[units.length - 1]; - rootDir = lastUnit.originalFilePath.indexOf('conformance') === -1 ? 'tests/cases/compiler/' : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf('/')) + '/'; + rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/"; harnessCompiler = Harness.Compiler.getCompiler(); // We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test) // If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references, @@ -106,7 +106,7 @@ class CompilerBaselineRunner extends RunnerBase { eventually to remove this limitation. */ for (let i = 0; i < tcSettings.length; ++i) { // noImplicitAny is passed to getCompiler, but target is just passed in the settings blob to setCompilerSettings - if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === 'target')) { + if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === "target")) { harnessCompiler = Harness.Compiler.getCompiler(); harnessCompiler.setCompilerSettings(tcSettings); createNewInstance = true; @@ -148,9 +148,9 @@ class CompilerBaselineRunner extends RunnerBase { } // check errors - it('Correct errors for ' + fileName, () => { + it("Correct errors for " + fileName, () => { if (this.errors) { - Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.tsx?$/, '.errors.txt'), (): string => { + Harness.Baseline.runBaseline("Correct errors for " + fileName, justName.replace(/\.tsx?$/, ".errors.txt"), (): string => { if (result.errors.length === 0) return null; return getErrorBaseline(toBeCompiled, otherFiles, result); }); @@ -158,12 +158,12 @@ class CompilerBaselineRunner extends RunnerBase { }); // Source maps? - it('Correct sourcemap content for ' + fileName, () => { + it("Correct sourcemap content for " + fileName, () => { if (options.sourceMap || options.inlineSourceMap) { - Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => { + Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => { let record = result.getSourceMapRecord(); if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) { - // Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required. + // Because of the noEmitOnError option no files are created. We need to return null because baselining isn"t required. return null; } return record; @@ -171,35 +171,35 @@ class CompilerBaselineRunner extends RunnerBase { } }); - it('Correct JS output for ' + fileName, () => { - if (!ts.fileExtensionIs(lastUnit.name, '.d.ts') && this.emit) { + it("Correct JS output for " + fileName, () => { + if (!ts.fileExtensionIs(lastUnit.name, ".d.ts") && this.emit) { if (result.files.length === 0 && result.errors.length === 0) { - throw new Error('Expected at least one js file to be emitted or at least one error to be created.'); + throw new Error("Expected at least one js file to be emitted or at least one error to be created."); } // check js output - Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.tsx?/, '.js'), () => { - let tsCode = ''; + Harness.Baseline.runBaseline("Correct JS output for " + fileName, justName.replace(/\.tsx?/, ".js"), () => { + let tsCode = ""; let tsSources = otherFiles.concat(toBeCompiled); if (tsSources.length > 1) { - tsCode += '//// [' + fileName + '] ////\r\n\r\n'; + tsCode += "//// [" + fileName + "] ////\r\n\r\n"; } for (let i = 0; i < tsSources.length; i++) { - tsCode += '//// [' + Harness.Path.getFileName(tsSources[i].unitName) + ']\r\n'; - tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? '\r\n' : ''); + tsCode += "//// [" + Harness.Path.getFileName(tsSources[i].unitName) + "]\r\n"; + tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : ""); } - let jsCode = ''; + let jsCode = ""; for (let i = 0; i < result.files.length; i++) { - jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n'; + jsCode += "//// [" + Harness.Path.getFileName(result.files[i].fileName) + "]\r\n"; jsCode += getByteOrderMarkText(result.files[i]); jsCode += result.files[i].code; } if (result.declFilesCode.length > 0) { - jsCode += '\r\n\r\n'; + jsCode += "\r\n\r\n"; for (let i = 0; i < result.declFilesCode.length; i++) { - jsCode += '//// [' + Harness.Path.getFileName(result.declFilesCode[i].fileName) + ']\r\n'; + jsCode += "//// [" + Harness.Path.getFileName(result.declFilesCode[i].fileName) + "]\r\n"; jsCode += getByteOrderMarkText(result.declFilesCode[i]); jsCode += result.declFilesCode[i].code; } @@ -210,13 +210,13 @@ class CompilerBaselineRunner extends RunnerBase { }, options); if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) { - jsCode += '\r\n\r\n//// [DtsFileErrors]\r\n'; - jsCode += '\r\n\r\n'; + jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n"; + jsCode += "\r\n\r\n"; jsCode += getErrorBaseline(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles, declFileCompilationResult.declResult); } if (jsCode.length > 0) { - return tsCode + '\r\n\r\n' + jsCode; + return tsCode + "\r\n\r\n" + jsCode; } else { return null; } @@ -224,28 +224,28 @@ class CompilerBaselineRunner extends RunnerBase { } }); - it('Correct Sourcemap output for ' + fileName, () => { + it("Correct Sourcemap output for " + fileName, () => { if (options.inlineSourceMap) { if (result.sourceMaps.length > 0) { - throw new Error('No sourcemap files should be generated if inlineSourceMaps was set.'); + throw new Error("No sourcemap files should be generated if inlineSourceMaps was set."); } return null; } else if (options.sourceMap) { if (result.sourceMaps.length !== result.files.length) { - throw new Error('Number of sourcemap files should be same as js files.'); + throw new Error("Number of sourcemap files should be same as js files."); } - Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.tsx?/, '.js.map'), () => { + Harness.Baseline.runBaseline("Correct Sourcemap output for " + fileName, justName.replace(/\.tsx?/, ".js.map"), () => { if (options.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) { // We need to return null here or the runBaseLine will actually create a empty file. // Baselining isn't required here because there is no output. return null; } - let sourceMapCode = ''; + let sourceMapCode = ""; for (let i = 0; i < result.sourceMaps.length; i++) { - sourceMapCode += '//// [' + Harness.Path.getFileName(result.sourceMaps[i].fileName) + ']\r\n'; + sourceMapCode += "//// [" + Harness.Path.getFileName(result.sourceMaps[i].fileName) + "]\r\n"; sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]); sourceMapCode += result.sourceMaps[i].code; } @@ -255,7 +255,7 @@ class CompilerBaselineRunner extends RunnerBase { } }); - it('Correct type/symbol baselines for ' + fileName, () => { + it("Correct type/symbol baselines for " + fileName, () => { if (fileName.indexOf("APISample") >= 0) { return; } @@ -317,15 +317,15 @@ class CompilerBaselineRunner extends RunnerBase { let fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine); let pullBaseLine = generateBaseLine(pullResults, isSymbolBaseLine); - let fullExtension = isSymbolBaseLine ? '.symbols' : '.types'; - let pullExtension = isSymbolBaseLine ? '.symbols.pull' : '.types.pull'; + let fullExtension = isSymbolBaseLine ? ".symbols" : ".types"; + let pullExtension = isSymbolBaseLine ? ".symbols.pull" : ".types.pull"; if (fullBaseLine !== pullBaseLine) { - Harness.Baseline.runBaseline('Correct full information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine); - Harness.Baseline.runBaseline('Correct pull information for ' + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine); + Harness.Baseline.runBaseline("Correct full information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine); + Harness.Baseline.runBaseline("Correct pull information for " + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine); } else { - Harness.Baseline.runBaseline('Correct information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine); + Harness.Baseline.runBaseline("Correct information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine); } } @@ -334,7 +334,7 @@ class CompilerBaselineRunner extends RunnerBase { let typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {}; allFiles.forEach(file => { - let codeLines = file.content.split('\n'); + let codeLines = file.content.split("\n"); typeWriterResults[file.unitName].forEach(result => { if (isSymbolBaseline && !result.symbol) { return; @@ -354,30 +354,30 @@ class CompilerBaselineRunner extends RunnerBase { typeMap[file.unitName][result.line] = typeInfo; }); - typeLines.push('=== ' + file.unitName + ' ===\r\n'); + typeLines.push("=== " + file.unitName + " ===\r\n"); for (let i = 0; i < codeLines.length; i++) { let currentCodeLine = codeLines[i]; - typeLines.push(currentCodeLine + '\r\n'); + typeLines.push(currentCodeLine + "\r\n"); if (typeMap[file.unitName]) { let typeInfo = typeMap[file.unitName][i]; if (typeInfo) { typeInfo.forEach(ty => { - typeLines.push('>' + ty + '\r\n'); + typeLines.push(">" + ty + "\r\n"); }); - if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === '')) { + if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === "")) { } else { - typeLines.push('\r\n'); + typeLines.push("\r\n"); } } } else { - typeLines.push('No type information for this code.'); + typeLines.push("No type information for this code."); } } }); - return typeLines.join(''); + return typeLines.join(""); } } }); @@ -385,7 +385,7 @@ class CompilerBaselineRunner extends RunnerBase { } public initializeTests() { - describe(this.testSuiteName + ' tests', () => { + describe(this.testSuiteName + " tests", () => { describe("Setup compiler for compiler baselines", () => { let harnessCompiler = Harness.Compiler.getCompiler(); this.parseOptions(); @@ -416,23 +416,23 @@ class CompilerBaselineRunner extends RunnerBase { this.decl = false; this.output = false; - let opts = this.options.split(','); + let opts = this.options.split(","); for (let i = 0; i < opts.length; i++) { switch (opts[i]) { - case 'error': + case "error": this.errors = true; break; - case 'emit': + case "emit": this.emit = true; break; - case 'decl': + case "decl": this.decl = true; break; - case 'output': + case "output": this.output = true; break; default: - throw new Error('unsupported flag'); + throw new Error("unsupported flag"); } } } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f9470ab2d5..2ebf086cb7 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -13,11 +13,11 @@ // limitations under the License. // -/// -/// -/// -/// -/// +/// +/// +/// +/// +/// module FourSlash { ts.disableIncrementalParsing = false; @@ -100,12 +100,12 @@ module FourSlash { } let entityMap: ts.Map = { - '&': '&', - '"': '"', - "'": ''', - '/': '/', - '<': '<', - '>': '>' + "&": "&", + "\"": """, + "'": "'", + "/": "/", + "<": "<", + ">": ">" }; export function escapeXmlAttributeValue(s: string) { @@ -116,18 +116,18 @@ module FourSlash { // To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames // Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data let metadataOptionNames = { - baselineFile: 'BaselineFile', - declaration: 'declaration', - emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project - fileName: 'Filename', - mapRoot: 'mapRoot', - module: 'module', - out: 'out', - outDir: 'outDir', - sourceMap: 'sourceMap', - sourceRoot: 'sourceRoot', - allowNonTsExtensions: 'allowNonTsExtensions', - resolveReference: 'ResolveReference', // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file + baselineFile: "BaselineFile", + declaration: "declaration", + emitThisFile: "emitThisFile", // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project + fileName: "Filename", + mapRoot: "mapRoot", + module: "module", + out: "out", + outDir: "outDir", + sourceMap: "sourceMap", + sourceRoot: "sourceRoot", + allowNonTsExtensions: "allowNonTsExtensions", + resolveReference: "ResolveReference", // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file }; // List of allowed metadata names @@ -326,7 +326,7 @@ module FourSlash { // Add triple reference files into language-service host ts.forEach(referencedFiles, referenceFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName so we will properly append the same base directory to refFile path - let referenceFilePath = this.basePath + '/' + referenceFile.fileName; + let referenceFilePath = this.basePath + "/" + referenceFile.fileName; this.addMatchedInputFile(referenceFilePath); }); @@ -334,7 +334,7 @@ module FourSlash { ts.forEach(importedFiles, importedFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName and import statement doesn't require ".ts" // so convert them before making appropriate comparison - let importedFilePath = this.basePath + '/' + importedFile.fileName + ".ts"; + let importedFilePath = this.basePath + "/" + importedFile.fileName + ".ts"; this.addMatchedInputFile(importedFilePath); }); @@ -369,9 +369,9 @@ module FourSlash { }; this.testData.files.forEach(file => { - let fileName = file.fileName.replace(Harness.IO.directoryName(file.fileName), '').substr(1); + let fileName = file.fileName.replace(Harness.IO.directoryName(file.fileName), "").substr(1); let fileNameWithoutExtension = fileName.substr(0, fileName.lastIndexOf(".")); - this.scenarioActions.push(''); + this.scenarioActions.push(""); }); // Open the first file by default @@ -384,7 +384,7 @@ module FourSlash { } // Entry points from fourslash.ts - public goToMarker(name = '') { + public goToMarker(name = "") { let marker = this.getMarkerByName(name); if (this.activeFile.fileName !== marker.fileName) { this.openFile(marker.fileName); @@ -392,7 +392,7 @@ module FourSlash { let content = this.getFileContent(marker.fileName); if (marker.position === -1 || marker.position > content.length) { - throw new Error('Marker "' + name + '" has been invalidated by unrecoverable edits to the file.'); + throw new Error(`Marker "${name}" has been invalidated by unrecoverable edits to the file.`); } this.lastKnownMarker = name; this.goToPosition(marker.position); @@ -410,9 +410,9 @@ module FourSlash { this.currentCaretPosition += count; this.currentCaretPosition = Math.min(this.currentCaretPosition, this.getFileContent(this.activeFile.fileName).length); if (count > 0) { - this.scenarioActions.push(''); + this.scenarioActions.push(``); } else { - this.scenarioActions.push(''); + this.scenarioActions.push(``); } } @@ -423,8 +423,8 @@ module FourSlash { let fileToOpen: FourSlashFile = this.findFile(indexOrName); fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName); this.activeFile = fileToOpen; - let fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), '').substr(1); - this.scenarioActions.push(''); + let fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), "").substr(1); + this.scenarioActions.push(``); // Let the host know that this file is now open this.languageServiceAdapterHost.openFile(fileToOpen.fileName); @@ -439,7 +439,7 @@ module FourSlash { let exists = this.anyErrorInRange(predicate, startMarker, endMarker); - this.taoInvalidReason = 'verifyErrorExistsBetweenMarkers NYI'; + this.taoInvalidReason = "verifyErrorExistsBetweenMarkers NYI"; if (exists !== negative) { this.printErrorLog(negative, this.getAllDiagnostics()); @@ -492,7 +492,7 @@ module FourSlash { }; } - this.taoInvalidReason = 'verifyErrorExistsAfterMarker NYI'; + this.taoInvalidReason = "verifyErrorExistsAfterMarker NYI"; let exists = this.anyErrorInRange(predicate, marker); let diagnostics = this.getAllDiagnostics(); @@ -541,7 +541,7 @@ module FourSlash { let errors = this.getDiagnostics(this.activeFile.fileName); let actual = errors.length; - this.scenarioActions.push(''); + this.scenarioActions.push(``); if (actual !== expected) { this.printErrorLog(false, errors); @@ -557,11 +557,11 @@ module FourSlash { throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName); } - this.taoInvalidReason = 'verifyEval impossible'; + this.taoInvalidReason = "verifyEval impossible"; - let evaluation = new Function(emit.outputFiles[0].text + ';\r\nreturn (' + expr + ');')(); + let evaluation = new Function(`${emit.outputFiles[0].text};\r\nreturn (${expr});`)(); if (evaluation !== value) { - this.raiseError('Expected evaluation of expression "' + expr + '" to equal "' + value + '", but got "' + evaluation + '"'); + this.raiseError(`Expected evaluation of expression "${expr}" to equal "${value}", but got "${evaluation}"`); } } @@ -570,19 +570,19 @@ module FourSlash { if (emit.outputFiles.length !== 1) { throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName); } - this.taoInvalidReason = 'verifyGetEmitOutputForCurrentFile impossible'; + this.taoInvalidReason = "verifyGetEmitOutputForCurrentFile impossible"; let actual = emit.outputFiles[0].text; if (actual !== expected) { - this.raiseError("Expected emit output to be '" + expected + "', but got '" + actual + "'"); + this.raiseError(`Expected emit output to be "${expected}", but got "${actual}"`); } } public verifyMemberListContains(symbol: string, text?: string, documentation?: string, kind?: string) { - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); if (text || documentation || kind) { - this.taoInvalidReason = 'verifyMemberListContains only supports the "symbol" parameter'; + this.taoInvalidReason = "verifyMemberListContains only supports the \"symbol\" parameter"; } let members = this.getMemberListAtCaret(); @@ -600,11 +600,11 @@ module FourSlash { this.verifyMemberListIsEmpty(false); return; } else { - this.scenarioActions.push(''); + this.scenarioActions.push(""); } } else { - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); } let members = this.getMemberListAtCaret(); @@ -622,31 +622,31 @@ module FourSlash { } public verifyMemberListDoesNotContain(symbol: string) { - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); let members = this.getMemberListAtCaret(); if (members && members.entries.filter(e => e.name === symbol).length !== 0) { - this.raiseError('Member list did contain ' + symbol); + this.raiseError(`Member list did contain ${symbol}`); } } public verifyCompletionListItemsCountIsGreaterThan(count: number) { - this.taoInvalidReason = 'verifyCompletionListItemsCountIsGreaterThan NYI'; + this.taoInvalidReason = "verifyCompletionListItemsCountIsGreaterThan NYI"; let completions = this.getCompletionListAtCaret(); let itemsCount = completions.entries.length; if (itemsCount <= count) { - this.raiseError('Expected completion list items count to be greater than ' + count + ', but is actually ' + itemsCount); + this.raiseError(`Expected completion list items count to be greater than ${count}, but is actually ${itemsCount}`); } } public verifyMemberListIsEmpty(negative: boolean) { if (negative) { - this.scenarioActions.push(''); + this.scenarioActions.push(""); } else { - this.scenarioActions.push(''); + this.scenarioActions.push(""); } let members = this.getMemberListAtCaret(); @@ -666,7 +666,7 @@ module FourSlash { } public verifyCompletionListIsEmpty(negative: boolean) { - this.scenarioActions.push(''); + this.scenarioActions.push(""); let completions = this.getCompletionListAtCaret(); if ((!completions || completions.entries.length === 0) && negative) { @@ -730,12 +730,12 @@ module FourSlash { return documentation === expectedDocumentation ? true : false; } // Because expectedText and expectedDocumentation are undefined, we assume that - // users don't care to compare them so we will treat that entry as if the entry has matching text and documentation + // users don"t care to compare them so we will treat that entry as if the entry has matching text and documentation // and keep it in the list of filtered entry. return true; } - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); let completions = this.getCompletionListAtCaret(); if (completions) { @@ -763,7 +763,7 @@ module FourSlash { } public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string) { - this.taoInvalidReason = 'verifyCompletionEntryDetails NYI'; + this.taoInvalidReason = "verifyCompletionEntryDetails NYI"; let details = this.getCompletionEntryDetails(entryName); @@ -779,30 +779,30 @@ module FourSlash { } public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { - this.taoInvalidReason = 'verifyReferencesAtPositionListContains NYI'; + this.taoInvalidReason = "verifyReferencesAtPositionListContains NYI"; let references = this.getReferencesAtCaret(); if (!references || references.length === 0) { - this.raiseError('verifyReferencesAtPositionListContains failed - found 0 references, expected at least one.'); + this.raiseError("verifyReferencesAtPositionListContains failed - found 0 references, expected at least one."); } for (let i = 0; i < references.length; i++) { let reference = references[i]; if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) { if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) { - this.raiseError('verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ' + reference.isWriteAccess + ', expected: ' + isWriteAccess + '.'); + this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`); } return; } } let missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; - this.raiseError('verifyReferencesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(references) + ')'); + this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem)} in the returned list: (${JSON.stringify(references)})`); } public verifyReferencesCountIs(count: number, localFilesOnly: boolean = true) { - this.taoInvalidReason = 'verifyReferences NYI'; + this.taoInvalidReason = "verifyReferences NYI"; let references = this.getReferencesAtCaret(); let referencesCount = 0; @@ -865,8 +865,8 @@ module FourSlash { public verifyQuickInfoString(negative: boolean, expectedText?: string, expectedDocumentation?: string) { [expectedText, expectedDocumentation].forEach(str => { if (str) { - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); } }); @@ -896,8 +896,8 @@ module FourSlash { public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; }, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[]) { - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); function getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) { let result = ""; @@ -964,23 +964,23 @@ module FourSlash { } public verifyQuickInfoExists(negative: boolean) { - this.taoInvalidReason = 'verifyQuickInfoExists NYI'; + this.taoInvalidReason = "verifyQuickInfoExists NYI"; let actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (negative) { if (actualQuickInfo) { - this.raiseError('verifyQuickInfoExists failed. Expected quick info NOT to exist'); + this.raiseError("verifyQuickInfoExists failed. Expected quick info NOT to exist"); } } else { if (!actualQuickInfo) { - this.raiseError('verifyQuickInfoExists failed. Expected quick info to exist'); + this.raiseError("verifyQuickInfoExists failed. Expected quick info to exist"); } } } public verifyCurrentSignatureHelpIs(expected: string) { - this.taoInvalidReason = 'verifyCurrentSignatureHelpIs NYI'; + this.taoInvalidReason = "verifyCurrentSignatureHelpIs NYI"; let help = this.getActiveSignatureHelpItem(); assert.equal( @@ -990,7 +990,7 @@ module FourSlash { } public verifyCurrentParameterIsletiable(isVariable: boolean) { - this.taoInvalidReason = 'verifyCurrentParameterIsletiable NYI'; + this.taoInvalidReason = "verifyCurrentParameterIsletiable NYI"; let signature = this.getActiveSignatureHelpItem(); assert.isNotNull(signature); @@ -998,7 +998,7 @@ module FourSlash { } public verifyCurrentParameterHelpName(name: string) { - this.taoInvalidReason = 'verifyCurrentParameterHelpName NYI'; + this.taoInvalidReason = "verifyCurrentParameterHelpName NYI"; let activeParameter = this.getActiveParameter(); let activeParameterName = activeParameter.name; @@ -1006,7 +1006,7 @@ module FourSlash { } public verifyCurrentParameterSpanIs(parameter: string) { - this.taoInvalidReason = 'verifyCurrentParameterSpanIs NYI'; + this.taoInvalidReason = "verifyCurrentParameterSpanIs NYI"; let activeSignature = this.getActiveSignatureHelpItem(); let activeParameter = this.getActiveParameter(); @@ -1014,7 +1014,7 @@ module FourSlash { } public verifyCurrentParameterHelpDocComment(docComment: string) { - this.taoInvalidReason = 'verifyCurrentParameterHelpDocComment NYI'; + this.taoInvalidReason = "verifyCurrentParameterHelpDocComment NYI"; let activeParameter = this.getActiveParameter(); let activeParameterDocComment = activeParameter.documentation; @@ -1022,27 +1022,27 @@ module FourSlash { } public verifyCurrentSignatureHelpParameterCount(expectedCount: number) { - this.taoInvalidReason = 'verifyCurrentSignatureHelpParameterCount NYI'; + this.taoInvalidReason = "verifyCurrentSignatureHelpParameterCount NYI"; assert.equal(this.getActiveSignatureHelpItem().parameters.length, expectedCount); } public verifyCurrentSignatureHelpTypeParameterCount(expectedCount: number) { - this.taoInvalidReason = 'verifyCurrentSignatureHelpTypeParameterCount NYI'; + this.taoInvalidReason = "verifyCurrentSignatureHelpTypeParameterCount NYI"; // assert.equal(this.getActiveSignatureHelpItem().typeParameters.length, expectedCount); } public verifyCurrentSignatureHelpDocComment(docComment: string) { - this.taoInvalidReason = 'verifyCurrentSignatureHelpDocComment NYI'; + this.taoInvalidReason = "verifyCurrentSignatureHelpDocComment NYI"; let actualDocComment = this.getActiveSignatureHelpItem().documentation; assert.equal(ts.displayPartsToString(actualDocComment), docComment, assertionMessage("current signature help doc comment")); } public verifySignatureHelpCount(expected: number) { - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); let actual = help && help.items ? help.items.length : 0; @@ -1050,14 +1050,14 @@ module FourSlash { } public verifySignatureHelpArgumentCount(expected: number) { - this.taoInvalidReason = 'verifySignatureHelpArgumentCount NYI'; + this.taoInvalidReason = "verifySignatureHelpArgumentCount NYI"; let signatureHelpItems = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); let actual = signatureHelpItems.argumentCount; assert.equal(actual, expected); } public verifySignatureHelpPresent(shouldBePresent = true) { - this.taoInvalidReason = 'verifySignatureHelpPresent NYI'; + this.taoInvalidReason = "verifySignatureHelpPresent NYI"; let actual = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); if (shouldBePresent) { @@ -1066,7 +1066,7 @@ module FourSlash { } } else { if (actual) { - this.raiseError("Expected no signature help, but got '" + JSON.stringify(actual) + "'"); + this.raiseError(`Expected no signature help, but got "${JSON.stringify(actual)}"`); } } } @@ -1200,12 +1200,12 @@ module FourSlash { } public getBreakpointStatementLocation(pos: number) { - this.taoInvalidReason = 'getBreakpointStatementLocation NYI'; + this.taoInvalidReason = "getBreakpointStatementLocation NYI"; return this.languageService.getBreakpointStatementAtPosition(this.activeFile.fileName, pos); } public baselineCurrentFileBreakpointLocations() { - this.taoInvalidReason = 'baselineCurrentFileBreakpointLocations impossible'; + this.taoInvalidReason = "baselineCurrentFileBreakpointLocations impossible"; Harness.Baseline.runBaseline( "Breakpoint Locations for " + this.activeFile.fileName, @@ -1217,7 +1217,7 @@ module FourSlash { } public baselineGetEmitOutput() { - this.taoInvalidReason = 'baselineGetEmitOutput impossible'; + this.taoInvalidReason = "baselineGetEmitOutput impossible"; // Find file to be emitted let emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on @@ -1288,7 +1288,7 @@ module FourSlash { let syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); let semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); let errorList = syntacticErrors.concat(semanticErrors); - Harness.IO.log('Error list (' + errorList.length + ' errors)'); + Harness.IO.log(`Error list (${errorList.length} errors)`); if (errorList.length) { errorList.forEach(err => { @@ -1304,10 +1304,10 @@ module FourSlash { for (let i = 0; i < this.testData.files.length; i++) { let file = this.testData.files[i]; let active = (this.activeFile === file); - Harness.IO.log('=== Script (' + file.fileName + ') ' + (active ? '(active, cursor at |)' : '') + ' ==='); + Harness.IO.log(`=== Script (${file.fileName}) ${(active ? "(active, cursor at |)" : "")} ===`); let content = this.getFileContent(file.fileName); if (active) { - content = content.substr(0, this.currentCaretPosition) + (makeCaretVisible ? '|' : "") + content.substr(this.currentCaretPosition); + content = content.substr(0, this.currentCaretPosition) + (makeCaretVisible ? "|" : "") + content.substr(this.currentCaretPosition); } if (makeWhitespaceVisible) { content = TestState.makeWhitespaceVisible(content); @@ -1343,7 +1343,7 @@ module FourSlash { } public deleteChar(count = 1) { - this.scenarioActions.push(''); + this.scenarioActions.push(``); let offset = this.currentCaretPosition; let ch = ""; @@ -1377,7 +1377,7 @@ module FourSlash { } public replace(start: number, length: number, text: string) { - this.taoInvalidReason = 'replace NYI'; + this.taoInvalidReason = "replace NYI"; this.languageServiceAdapterHost.editScript(this.activeFile.fileName, start, start + length, text); this.updateMarkersForEdit(this.activeFile.fileName, start, start + length, text); @@ -1385,7 +1385,7 @@ module FourSlash { } public deleteCharBehindMarker(count = 1) { - this.scenarioActions.push(''); + this.scenarioActions.push(``); let offset = this.currentCaretPosition; let ch = ""; @@ -1419,10 +1419,10 @@ module FourSlash { // Enters lines of text at the current caret position public type(text: string) { - if (text === '') { - this.taoInvalidReason = 'Test used empty-insert workaround.'; + if (text === "") { + this.taoInvalidReason = "Test used empty-insert workaround."; } else { - this.scenarioActions.push(''); + this.scenarioActions.push(``); } return this.typeHighFidelity(text); @@ -1433,7 +1433,7 @@ module FourSlash { // as much as possible private typeHighFidelity(text: string) { let offset = this.currentCaretPosition; - let prevChar = ' '; + let prevChar = " "; let checkCadence = (text.length >> 2) + 1; for (let i = 0; i < text.length; i++) { @@ -1445,10 +1445,10 @@ module FourSlash { this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch); offset++; - if (ch === '(' || ch === ',') { + if (ch === "(" || ch === ",") { /* Signature help*/ this.languageService.getSignatureHelpItems(this.activeFile.fileName, offset); - } else if (prevChar === ' ' && /A-Za-z_/.test(ch)) { + } else if (prevChar === " " && /A-Za-z_/.test(ch)) { /* Completions */ this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset); } @@ -1478,7 +1478,7 @@ module FourSlash { // Enters text as if the user had pasted it public paste(text: string) { - this.scenarioActions.push(''); + this.scenarioActions.push(``); let start = this.currentCaretPosition; let offset = this.currentCaretPosition; @@ -1531,7 +1531,7 @@ module FourSlash { // that happens, move it back one character if (this.currentCaretPosition > 0) { let ch = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition - 1, this.currentCaretPosition); - if (ch === '\r') { + if (ch === "\r") { this.currentCaretPosition--; } }; @@ -1556,8 +1556,8 @@ module FourSlash { if (isFormattingEdit) { let newContent = this.getFileContent(fileName); - if (newContent.replace(/\s/g, '') !== oldContent.replace(/\s/g, '')) { - this.raiseError('Formatting operation destroyed non-whitespace content'); + if (newContent.replace(/\s/g, "") !== oldContent.replace(/\s/g, "")) { + this.raiseError("Formatting operation destroyed non-whitespace content"); } } return runningOffset; @@ -1574,7 +1574,7 @@ module FourSlash { } public formatDocument() { - this.scenarioActions.push(''); + this.scenarioActions.push(""); let edits = this.languageService.getFormattingEditsForDocument(this.activeFile.fileName, this.formatCodeOptions); this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, true); @@ -1582,7 +1582,7 @@ module FourSlash { } public formatSelection(start: number, end: number) { - this.taoInvalidReason = 'formatSelection NYI'; + this.taoInvalidReason = "formatSelection NYI"; let edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, end, this.formatCodeOptions); this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, true); @@ -1617,18 +1617,18 @@ module FourSlash { public goToDefinition(definitionIndex: number) { if (definitionIndex === 0) { - this.scenarioActions.push(''); + this.scenarioActions.push(""); } else { - this.taoInvalidReason = 'GoToDefinition not supported for non-zero definition indices'; + this.taoInvalidReason = "GoToDefinition not supported for non-zero definition indices"; } let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { - this.raiseError('goToDefinition failed - expected to at least one definition location but got 0'); + this.raiseError("goToDefinition failed - expected to at least one definition location but got 0"); } if (definitionIndex >= definitions.length) { - this.raiseError('goToDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')'); + this.raiseError(`goToDefinition failed - definitionIndex value (${definitionIndex}) exceeds definition list size (${definitions.length})`); } let definition = definitions[definitionIndex]; @@ -1638,19 +1638,19 @@ module FourSlash { public goToTypeDefinition(definitionIndex: number) { if (definitionIndex === 0) { - this.scenarioActions.push(''); + this.scenarioActions.push(""); } else { - this.taoInvalidReason = 'GoToTypeDefinition not supported for non-zero definition indices'; + this.taoInvalidReason = "GoToTypeDefinition not supported for non-zero definition indices"; } let definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { - this.raiseError('goToTypeDefinition failed - expected to at least one definition location but got 0'); + this.raiseError("goToTypeDefinition failed - expected to at least one definition location but got 0"); } if (definitionIndex >= definitions.length) { - this.raiseError('goToTypeDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')'); + this.raiseError(`goToTypeDefinition failed - definitionIndex value (${definitionIndex}) exceeds definition list size (${definitions.length})`); } let definition = definitions[definitionIndex]; @@ -1659,17 +1659,17 @@ module FourSlash { } public verifyDefinitionLocationExists(negative: boolean) { - this.taoInvalidReason = 'verifyDefinitionLocationExists NYI'; + this.taoInvalidReason = "verifyDefinitionLocationExists NYI"; let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); let foundDefinitions = definitions && definitions.length; if (foundDefinitions && negative) { - this.raiseError('goToDefinition - expected to 0 definition locations but got ' + definitions.length); + this.raiseError(`goToDefinition - expected to 0 definition locations but got ${definitions.length}`); } else if (!foundDefinitions && !negative) { - this.raiseError('goToDefinition - expected to at least one definition location but got 0'); + this.raiseError("goToDefinition - expected to at least one definition location but got 0"); } } @@ -1692,7 +1692,7 @@ module FourSlash { } public verifyDefinitionsName(negative: boolean, expectedName: string, expectedContainerName: string) { - this.taoInvalidReason = 'verifyDefinititionsInfo NYI'; + this.taoInvalidReason = "verifyDefinititionsInfo NYI"; let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); let actualDefinitionName = definitions && definitions.length ? definitions[0].name : ""; @@ -1716,15 +1716,15 @@ module FourSlash { return this.testData.ranges.slice(0); } - public verifyCaretAtMarker(markerName = '') { - this.taoInvalidReason = 'verifyCaretAtMarker NYI'; + public verifyCaretAtMarker(markerName = "") { + this.taoInvalidReason = "verifyCaretAtMarker NYI"; let pos = this.getMarkerByName(markerName); if (pos.fileName !== this.activeFile.fileName) { - throw new Error('verifyCaretAtMarker failed - expected to be in file "' + pos.fileName + '", but was in file "' + this.activeFile.fileName + '"'); + throw new Error(`verifyCaretAtMarker failed - expected to be in file "${pos.fileName}", but was in file "${this.activeFile.fileName}"`); } if (pos.position !== this.currentCaretPosition) { - throw new Error('verifyCaretAtMarker failed - expected to be at marker "/*' + markerName + '*/, but was at position ' + this.currentCaretPosition + '(' + this.getLineColStringAtPosition(this.currentCaretPosition) + ')'); + throw new Error(`verifyCaretAtMarker failed - expected to be at marker "/*${markerName}*/, but was at position ${this.currentCaretPosition}(${this.getLineColStringAtPosition(this.currentCaretPosition)})`); } } @@ -1733,84 +1733,84 @@ module FourSlash { } public verifyIndentationAtCurrentPosition(numberOfSpaces: number) { - this.taoInvalidReason = 'verifyIndentationAtCurrentPosition NYI'; + this.taoInvalidReason = "verifyIndentationAtCurrentPosition NYI"; let actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition); let lineCol = this.getLineColStringAtPosition(this.currentCaretPosition); if (actual !== numberOfSpaces) { - this.raiseError('verifyIndentationAtCurrentPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual); + this.raiseError(`verifyIndentationAtCurrentPosition failed at ${lineCol} - expected: ${numberOfSpaces}, actual: ${actual}`); } } public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number) { - this.taoInvalidReason = 'verifyIndentationAtPosition NYI'; + this.taoInvalidReason = "verifyIndentationAtPosition NYI"; let actual = this.getIndentation(fileName, position); let lineCol = this.getLineColStringAtPosition(position); if (actual !== numberOfSpaces) { - this.raiseError('verifyIndentationAtPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual); + this.raiseError(`verifyIndentationAtPosition failed at ${lineCol} - expected: ${numberOfSpaces}, actual: ${actual}`); } } public verifyCurrentLineContent(text: string) { - this.taoInvalidReason = 'verifyCurrentLineContent NYI'; + this.taoInvalidReason = "verifyCurrentLineContent NYI"; let actual = this.getCurrentLineContent(); if (actual !== text) { - throw new Error('verifyCurrentLineContent\n' + - '\tExpected: "' + text + '"\n' + - '\t Actual: "' + actual + '"'); + throw new Error("verifyCurrentLineContent\n" + + "\tExpected: \"" + text + "\"\n" + + "\t Actual: \"" + actual + "\""); } } public verifyCurrentFileContent(text: string) { - this.taoInvalidReason = 'verifyCurrentFileContent NYI'; + this.taoInvalidReason = "verifyCurrentFileContent NYI"; let actual = this.getFileContent(this.activeFile.fileName); let replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n"); if (replaceNewlines(actual) !== replaceNewlines(text)) { - throw new Error('verifyCurrentFileContent\n' + - '\tExpected: "' + text + '"\n' + - '\t Actual: "' + actual + '"'); + throw new Error("verifyCurrentFileContent\n" + + "\tExpected: \"" + text + "\"\n" + + "\t Actual: \"" + actual + "\""); } } public verifyTextAtCaretIs(text: string) { - this.taoInvalidReason = 'verifyCurrentFileContent NYI'; + this.taoInvalidReason = "verifyCurrentFileContent NYI"; let actual = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition, this.currentCaretPosition + text.length); if (actual !== text) { - throw new Error('verifyTextAtCaretIs\n' + - '\tExpected: "' + text + '"\n' + - '\t Actual: "' + actual + '"'); + throw new Error("verifyTextAtCaretIs\n" + + "\tExpected: \"" + text + "\"\n" + + "\t Actual: \"" + actual + "\""); } } public verifyCurrentNameOrDottedNameSpanText(text: string) { - this.taoInvalidReason = 'verifyCurrentNameOrDottedNameSpanText NYI'; + this.taoInvalidReason = "verifyCurrentNameOrDottedNameSpanText NYI"; let span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition); if (!span) { - this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' + - '\tExpected: "' + text + '"\n' + - '\t Actual: undefined'); + this.raiseError("verifyCurrentNameOrDottedNameSpanText\n" + + "\tExpected: \"" + text + "\"\n" + + "\t Actual: undefined"); } let actual = this.getFileContent(this.activeFile.fileName).substring(span.start, ts.textSpanEnd(span)); if (actual !== text) { - this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' + - '\tExpected: "' + text + '"\n' + - '\t Actual: "' + actual + '"'); + this.raiseError("verifyCurrentNameOrDottedNameSpanText\n" + + "\tExpected: \"" + text + "\"\n" + + "\t Actual: \"" + actual + "\""); } } private getNameOrDottedNameSpan(pos: number) { - this.taoInvalidReason = 'getNameOrDottedNameSpan NYI'; + this.taoInvalidReason = "getNameOrDottedNameSpan NYI"; return this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, pos, pos); } public baselineCurrentFileNameOrDottedNameSpans() { - this.taoInvalidReason = 'baselineCurrentFileNameOrDottedNameSpans impossible'; + this.taoInvalidReason = "baselineCurrentFileNameOrDottedNameSpans impossible"; Harness.Baseline.runBaseline( "Name OrDottedNameSpans for " + this.activeFile.fileName, @@ -1828,8 +1828,8 @@ module FourSlash { private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) { if (actual.length !== expected.length) { - this.raiseError('verifyClassifications failed - expected total classifications to be ' + expected.length + - ', but was ' + actual.length + + this.raiseError("verifyClassifications failed - expected total classifications to be " + expected.length + + ", but was " + actual.length + jsonMismatchString()); } @@ -1839,8 +1839,8 @@ module FourSlash { let expectedType: string = (ts.ClassificationTypeNames)[expectedClassification.classificationType]; if (expectedType !== actualClassification.classificationType) { - this.raiseError('verifyClassifications failed - expected classifications type to be ' + - expectedType + ', but was ' + + this.raiseError("verifyClassifications failed - expected classifications type to be " + + expectedType + ", but was " + actualClassification.classificationType + jsonMismatchString()); } @@ -1861,8 +1861,8 @@ module FourSlash { let actualText = this.activeFile.content.substr(actualSpan.start, actualSpan.length); if (expectedClassification.text !== actualText) { - this.raiseError('verifyClassifications failed - expected classified text to be ' + - expectedClassification.text + ', but was ' + + this.raiseError("verifyClassifications failed - expected classified text to be " + + expectedClassification.text + ", but was " + actualText + jsonMismatchString()); } @@ -1905,19 +1905,19 @@ module FourSlash { } public verifyOutliningSpans(spans: TextSpan[]) { - this.taoInvalidReason = 'verifyOutliningSpans NYI'; + this.taoInvalidReason = "verifyOutliningSpans NYI"; let actual = this.languageService.getOutliningSpans(this.activeFile.fileName); if (actual.length !== spans.length) { - this.raiseError('verifyOutliningSpans failed - expected total spans to be ' + spans.length + ', but was ' + actual.length); + this.raiseError(`verifyOutliningSpans failed - expected total spans to be ${spans.length}, but was ${actual.length}`); } for (let i = 0; i < spans.length; i++) { let expectedSpan = spans[i]; let actualSpan = actual[i]; if (expectedSpan.start !== actualSpan.textSpan.start || expectedSpan.end !== ts.textSpanEnd(actualSpan.textSpan)) { - this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualSpan.textSpan.start + ',' + ts.textSpanEnd(actualSpan.textSpan) + ')'); + this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.start},${expectedSpan.end}), actual: (${actualSpan.textSpan.start},${ts.textSpanEnd(actualSpan.textSpan)})`); } } } @@ -1927,7 +1927,7 @@ module FourSlash { descriptors.map(d => { return { text: d, priority: 0 }; })); if (actual.length !== spans.length) { - this.raiseError('verifyTodoComments failed - expected total spans to be ' + spans.length + ', but was ' + actual.length); + this.raiseError(`verifyTodoComments failed - expected total spans to be ${spans.length}, but was ${actual.length}`); } for (let i = 0; i < spans.length; i++) { @@ -1936,18 +1936,18 @@ module FourSlash { let actualCommentSpan = ts.createTextSpan(actualComment.position, actualComment.message.length); if (expectedSpan.start !== actualCommentSpan.start || expectedSpan.end !== ts.textSpanEnd(actualCommentSpan)) { - this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualCommentSpan.start + ',' + ts.textSpanEnd(actualCommentSpan) + ')'); + this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.start},${expectedSpan.end}), actual: (${actualCommentSpan.start},${ts.textSpanEnd(actualCommentSpan)})`); } } } public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) { - this.taoInvalidReason = 'verifyMatchingBracePosition NYI'; + this.taoInvalidReason = "verifyMatchingBracePosition NYI"; let actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 2) { - this.raiseError('verifyMatchingBracePosition failed - expected result to contain 2 spans, but it had ' + actual.length); + this.raiseError(`verifyMatchingBracePosition failed - expected result to contain 2 spans, but it had ${actual.length}`); } let actualMatchPosition = -1; @@ -1956,21 +1956,21 @@ module FourSlash { } else if (bracePosition === actual[1].start) { actualMatchPosition = actual[0].start; } else { - this.raiseError('verifyMatchingBracePosition failed - could not find the brace position: ' + bracePosition + ' in the returned list: (' + actual[0].start + ',' + ts.textSpanEnd(actual[0]) + ') and (' + actual[1].start + ',' + ts.textSpanEnd(actual[1]) + ')'); + this.raiseError(`verifyMatchingBracePosition failed - could not find the brace position: ${bracePosition} in the returned list: (${actual[0].start},${ts.textSpanEnd(actual[0])}) and (${actual[1].start},${ts.textSpanEnd(actual[1])})`); } if (actualMatchPosition !== expectedMatchPosition) { - this.raiseError('verifyMatchingBracePosition failed - expected: ' + actualMatchPosition + ', actual: ' + expectedMatchPosition); + this.raiseError(`verifyMatchingBracePosition failed - expected: ${actualMatchPosition}, actual: ${expectedMatchPosition}`); } } public verifyNoMatchingBracePosition(bracePosition: number) { - this.taoInvalidReason = 'verifyNoMatchingBracePosition NYI'; + this.taoInvalidReason = "verifyNoMatchingBracePosition NYI"; let actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 0) { - this.raiseError('verifyNoMatchingBracePosition failed - expected: 0 spans, actual: ' + actual.length); + this.raiseError("verifyNoMatchingBracePosition failed - expected: 0 spans, actual: " + actual.length); } } @@ -1979,7 +1979,7 @@ module FourSlash { Report an error if expected value and actual value do not match. */ public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string) { - this.taoInvalidReason = 'verifyNavigationItemsCount NYI'; + this.taoInvalidReason = "verifyNavigationItemsCount NYI"; let items = this.languageService.getNavigateToItems(searchValue); let actual = 0; @@ -1994,7 +1994,7 @@ module FourSlash { } if (expected !== actual) { - this.raiseError('verifyNavigationItemsCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.'); + this.raiseError(`verifyNavigationItemsCount failed - found: ${actual} navigation items, expected: ${expected}.`); } } @@ -2009,12 +2009,12 @@ module FourSlash { matchKind: string, fileName?: string, parentName?: string) { - this.taoInvalidReason = 'verifyNavigationItemsListContains NYI'; + this.taoInvalidReason = "verifyNavigationItemsListContains NYI"; let items = this.languageService.getNavigateToItems(searchValue); if (!items || items.length === 0) { - this.raiseError('verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one.'); + this.raiseError("verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one."); } for (let i = 0; i < items.length; i++) { @@ -2030,18 +2030,18 @@ module FourSlash { // if there was an explicit match kind specified, then it should be validated. if (matchKind !== undefined) { let missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName }; - this.raiseError('verifyNavigationItemsListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items) + ')'); + this.raiseError(`verifyNavigationItemsListContains failed - could not find the item: ${JSON.stringify(missingItem)} in the returned list: (${JSON.stringify(items)})`); } } public verifyGetScriptLexicalStructureListCount(expected: number) { - this.taoInvalidReason = 'verifyNavigationItemsListContains impossible'; + this.taoInvalidReason = "verifyNavigationItemsListContains impossible"; let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); let actual = this.getNavigationBarItemsCount(items); if (expected !== actual) { - this.raiseError('verifyGetScriptLexicalStructureListCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.'); + this.raiseError(`verifyGetScriptLexicalStructureListCount failed - found: ${actual} navigation items, expected: ${expected}.`); } } @@ -2058,12 +2058,12 @@ module FourSlash { } public verifyGetScriptLexicalStructureListContains(name: string, kind: string) { - this.taoInvalidReason = 'verifyGetScriptLexicalStructureListContains impossible'; + this.taoInvalidReason = "verifyGetScriptLexicalStructureListContains impossible"; let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); if (!items || items.length === 0) { - this.raiseError('verifyGetScriptLexicalStructureListContains failed - found 0 navigation items, expected at least one.'); + this.raiseError("verifyGetScriptLexicalStructureListContains failed - found 0 navigation items, expected at least one."); } if (this.navigationBarItemsContains(items, name, kind)) { @@ -2071,7 +2071,7 @@ module FourSlash { } let missingItem = { name: name, kind: kind }; - this.raiseError('verifyGetScriptLexicalStructureListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items, null, " ") + ')'); + this.raiseError(`verifyGetScriptLexicalStructureListContains failed - could not find the item: ${JSON.stringify(missingItem)} in the returned list: (${JSON.stringify(items, null, " ")})`); } private navigationBarItemsContains(items: ts.NavigationBarItem[], name: string, kind: string) { @@ -2095,11 +2095,11 @@ module FourSlash { let items = this.languageService.getNavigateToItems(searchValue); let length = items && items.length; - Harness.IO.log('NavigationItems list (' + length + ' items)'); + Harness.IO.log(`NavigationItems list (${length} items)`); for (let i = 0; i < length; i++) { let item = items[i]; - Harness.IO.log('name: ' + item.name + ', kind: ' + item.kind + ', parentName: ' + item.containerName + ', fileName: ' + item.fileName); + Harness.IO.log(`name: ${item.name}, kind: ${item.kind}, parentName: ${item.containerName}, fileName: ${item.fileName}`); } } @@ -2107,11 +2107,11 @@ module FourSlash { let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); let length = items && items.length; - Harness.IO.log('NavigationItems list (' + length + ' items)'); + Harness.IO.log(`NavigationItems list (${length} items)`); for (let i = 0; i < length; i++) { let item = items[i]; - Harness.IO.log('name: ' + item.text + ', kind: ' + item.kind); + Harness.IO.log(`name: ${item.text}, kind: ${item.kind}`); } } @@ -2120,7 +2120,7 @@ module FourSlash { } public verifyOccurrencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { - this.taoInvalidReason = 'verifyOccurrencesAtPositionListContains NYI'; + this.taoInvalidReason = "verifyOccurrencesAtPositionListContains NYI"; let occurrences = this.getOccurancesAtCurrentPosition(); @@ -2131,23 +2131,23 @@ module FourSlash { for (let occurrence of occurrences) { if (occurrence && occurrence.fileName === fileName && occurrence.textSpan.start === start && ts.textSpanEnd(occurrence.textSpan) === end) { if (typeof isWriteAccess !== "undefined" && occurrence.isWriteAccess !== isWriteAccess) { - this.raiseError('verifyOccurrencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ' + occurrence.isWriteAccess + ', expected: ' + isWriteAccess + '.'); + this.raiseError(`verifyOccurrencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${occurrence.isWriteAccess}, expected: ${isWriteAccess}.`); } return; } } let missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; - this.raiseError('verifyOccurrencesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(occurrences) + ')'); + this.raiseError(`verifyOccurrencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem)} in the returned list: (${JSON.stringify(occurrences)})`); } public verifyOccurrencesAtPositionListCount(expectedCount: number) { - this.taoInvalidReason = 'verifyOccurrencesAtPositionListCount NYI'; + this.taoInvalidReason = "verifyOccurrencesAtPositionListCount NYI"; let occurrences = this.getOccurancesAtCurrentPosition(); let actualCount = occurrences ? occurrences.length : 0; if (expectedCount !== actualCount) { - this.raiseError('verifyOccurrencesAtPositionListCount failed - actual: ' + actualCount + ', expected:' + expectedCount); + this.raiseError(`verifyOccurrencesAtPositionListCount failed - actual: ${actualCount}, expected:${expectedCount}`); } } @@ -2227,11 +2227,11 @@ module FourSlash { } private assertItemInCompletionList(items: ts.CompletionEntry[], name: string, text?: string, documentation?: string, kind?: string) { - this.scenarioActions.push(''); - this.scenarioActions.push(''); + this.scenarioActions.push(""); + this.scenarioActions.push(``); if (text || documentation || kind) { - this.taoInvalidReason = 'assertItemInCompletionList only supports the "name" parameter'; + this.taoInvalidReason = "assertItemInCompletionList only supports the \"name\" parameter"; } for (let i = 0; i < items.length; i++) { @@ -2258,23 +2258,23 @@ module FourSlash { let itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind })).join(",\n"); - this.raiseError('Expected "' + JSON.stringify({ name, text, documentation, kind }) + '" to be in list [' + itemsString + ']'); + this.raiseError(`Expected "${JSON.stringify({ name, text, documentation, kind })}" to be in list [${itemsString}]`); } private findFile(indexOrName: any) { let result: FourSlashFile = null; - if (typeof indexOrName === 'number') { + if (typeof indexOrName === "number") { let index = indexOrName; if (index >= this.testData.files.length) { - throw new Error('File index (' + index + ') in openFile was out of range. There are only ' + this.testData.files.length + ' files in this test.'); + throw new Error(`File index (${index}) in openFile was out of range. There are only ${this.testData.files.length} files in this test.`); } else { result = this.testData.files[index]; } - } else if (typeof indexOrName === 'string') { + } else if (typeof indexOrName === "string") { let name = indexOrName; // names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName - name = name.indexOf('/') === -1 ? (this.basePath + '/' + name) : name; + name = name.indexOf("/") === -1 ? (this.basePath + "/" + name) : name; let availableNames: string[] = []; let foundIt = false; @@ -2291,10 +2291,10 @@ module FourSlash { } if (!foundIt) { - throw new Error('No test file named "' + name + '" exists. Available file names are:' + availableNames.join(', ')); + throw new Error(`No test file named "${name}" exists. Available file names are: ${availableNames.join(", ")}`); } } else { - throw new Error('Unknown argument type'); + throw new Error("Unknown argument type"); } return result; @@ -2302,7 +2302,7 @@ module FourSlash { private getLineColStringAtPosition(position: number) { let pos = this.languageServiceAdapterHost.positionToLineAndCharacter(this.activeFile.fileName, position); - return 'line ' + (pos.line + 1) + ', col ' + pos.character; + return `line ${(pos.line + 1)}, col ${pos.character}`; } public getMarkerByName(markerName: string) { @@ -2310,21 +2310,21 @@ module FourSlash { if (markerPos === undefined) { let markerNames: string[] = []; for (let m in this.testData.markerPositions) markerNames.push(m); - throw new Error('Unknown marker "' + markerName + '" Available markers: ' + markerNames.map(m => '"' + m + '"').join(', ')); + throw new Error(`Unknown marker "${markerName}" Available markers: ${markerNames.map(m => "\"" + m + "\"").join(", ")}`); } else { return markerPos; } } private static makeWhitespaceVisible(text: string) { - return text.replace(/ /g, '\u00B7').replace(/\r/g, '\u00B6').replace(/\n/g, '\u2193\n').replace(/\t/g, '\u2192\ '); + return text.replace(/ /g, "\u00B7").replace(/\r/g, "\u00B6").replace(/\n/g, "\u2193\n").replace(/\t/g, "\u2192\ "); } public getTestXmlData(): TestXmlData { return { actions: this.scenarioActions, invalidReason: this.taoInvalidReason, - originalName: '' + originalName: "" }; } @@ -2368,7 +2368,7 @@ module FourSlash { currentTestState = new TestState(basePath, testType, testData); - let result = ''; + let result = ""; let host = Harness.Compiler.createCompilerHost( [ { unitName: Harness.Compiler.fourslashFileName, content: undefined }, @@ -2384,12 +2384,12 @@ module FourSlash { let diagnostics = ts.getPreEmitDiagnostics(program, sourceFile); if (diagnostics.length > 0) { - throw new Error('Error compiling ' + fileName + ': ' + - diagnostics.map(e => ts.flattenDiagnosticMessageText(e.messageText, ts.sys.newLine)).join('\r\n')); + throw new Error(`Error compiling ${fileName}: ` + + diagnostics.map(e => ts.flattenDiagnosticMessageText(e.messageText, ts.sys.newLine)).join("\r\n")); } program.emit(sourceFile); - result = result || ''; // Might have an empty fourslash file + result = result || ""; // Might have an empty fourslash file result = fourslashJsOutput + "\r\n" + result; @@ -2410,12 +2410,12 @@ module FourSlash { function chompLeadingSpace(content: string) { let lines = content.split("\n"); for (let i = 0; i < lines.length; i++) { - if ((lines[i].length !== 0) && (lines[i].charAt(0) !== ' ')) { + if ((lines[i].length !== 0) && (lines[i].charAt(0) !== " ")) { return content; } } - return lines.map(s => s.substr(1)).join('\n'); + return lines.map(s => s.substr(1)).join("\n"); } function parseTestData(basePath: string, contents: string, fileName: string): FourSlashData { @@ -2431,7 +2431,7 @@ module FourSlash { // Split up the input file by line // Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so // we have to string-based splitting instead and try to figure out the delimiting chars - let lines = contents.split('\n'); + let lines = contents.split("\n"); let markerPositions: MarkerMap = {}; let markers: Marker[] = []; @@ -2446,23 +2446,23 @@ module FourSlash { let line = lines[i]; let lineLength = line.length; - if (lineLength > 0 && line.charAt(lineLength - 1) === '\r') { + if (lineLength > 0 && line.charAt(lineLength - 1) === "\r") { line = line.substr(0, lineLength - 1); } - if (line.substr(0, 4) === '////') { + if (line.substr(0, 4) === "////") { // Subfile content line // Append to the current subfile content, inserting a newline needed if (currentFileContent === null) { - currentFileContent = ''; + currentFileContent = ""; } else { // End-of-line - currentFileContent = currentFileContent + '\n'; + currentFileContent = currentFileContent + "\n"; } currentFileContent = currentFileContent + line.substr(4); - } else if (line.substr(0, 2) === '//') { + } else if (line.substr(0, 2) === "//") { // Comment line, check for global/file @options and record them let match = optionRegex.exec(line.substr(2)); if (match) { @@ -2470,7 +2470,7 @@ module FourSlash { let fileMetadataNamesIndex = fileMetadataNames.indexOf(match[1]); if (globalMetadataNamesIndex === -1) { if (fileMetadataNamesIndex === -1) { - throw new Error('Unrecognized metadata name "' + match[1] + '". Available global metadata names are: ' + globalMetadataNames.join(', ') + '; file metadata names are: ' + fileMetadataNames.join(', ')); + throw new Error(`Unrecognized metadata name "${match[1]}". Available global metadata names are: ${globalMetadataNames.join(", ")}; file metadata names are: ${fileMetadataNames.join(", ")}`); } else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(metadataOptionNames.fileName)) { // Found an @FileName directive, if this is not the first then create a new subfile if (currentFileContent) { @@ -2486,7 +2486,7 @@ module FourSlash { currentFileName = fileName; } - currentFileName = basePath + '/' + match[2]; + currentFileName = basePath + "/" + match[2]; currentFileOptions[match[1]] = match[2]; } else { // Add other fileMetadata flag @@ -2501,7 +2501,7 @@ module FourSlash { } } // TODO: should be '==='? - } else if (line == '' || lineLength === 0) { + } else if (line == "" || lineLength === 0) { // Previously blank lines between fourslash content caused it to be considered as 2 files, // Remove this behavior since it just causes errors now } else { @@ -2542,7 +2542,7 @@ module FourSlash { } function containTSConfigJson(files: FourSlashFile[]): boolean { - return ts.forEach(files, f => f.fileOptions['Filename'] === 'tsconfig.json'); + return ts.forEach(files, f => f.fileOptions["Filename"] === "tsconfig.json"); } function getNonFileNameOptionInFileList(files: FourSlashFile[]): string { @@ -2621,7 +2621,7 @@ module FourSlash { content = chompLeadingSpace(content); // Any slash-star comment with a character not in this string is not a marker. - let validMarkerChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$1234567890_'; + let validMarkerChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$1234567890_"; /// The file content (minus metacharacters) so far let output: string = ""; @@ -2756,7 +2756,7 @@ module FourSlash { openMarker = null; state = State.none; } else if (validMarkerChars.indexOf(currentChar) < 0) { - if (currentChar === '*' && i < content.length - 1 && content.charAt(i + 1) === '/') { + if (currentChar === "*" && i < content.length - 1 && content.charAt(i + 1) === "/") { // The marker is about to be closed, ignore the 'invalid' char } else { // We've hit a non-valid marker character, so we were actually in a block comment @@ -2771,10 +2771,10 @@ module FourSlash { break; } - if (currentChar === '\n' && previousChar === '\r') { + if (currentChar === "\n" && previousChar === "\r") { // Ignore trailing \n after a \r continue; - } else if (currentChar === '\n' || currentChar === '\r') { + } else if (currentChar === "\n" || currentChar === "\r") { line++; column = 1; continue; diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index 05a11c4f52..3914232dbe 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -1,6 +1,6 @@ -/// -/// -/// +/// +/// +/// const enum FourSlashTestType { Native, @@ -16,16 +16,16 @@ class FourSlashRunner extends RunnerBase { super(); switch (testType) { case FourSlashTestType.Native: - this.basePath = 'tests/cases/fourslash'; - this.testSuiteName = 'fourslash'; + this.basePath = "tests/cases/fourslash"; + this.testSuiteName = "fourslash"; break; case FourSlashTestType.Shims: - this.basePath = 'tests/cases/fourslash/shims'; - this.testSuiteName = 'fourslash-shims'; + this.basePath = "tests/cases/fourslash/shims"; + this.testSuiteName = "fourslash-shims"; break; case FourSlashTestType.Server: - this.basePath = 'tests/cases/fourslash/server'; - this.testSuiteName = 'fourslash-server'; + this.basePath = "tests/cases/fourslash/server"; + this.testSuiteName = "fourslash-server"; break; } } @@ -35,25 +35,25 @@ class FourSlashRunner extends RunnerBase { this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); } - describe(this.testSuiteName + ' tests', () => { + describe(this.testSuiteName + " tests", () => { this.tests.forEach((fn: string) => { describe(fn, () => { fn = ts.normalizeSlashes(fn); - let justName = fn.replace(/^.*[\\\/]/, ''); + let justName = fn.replace(/^.*[\\\/]/, ""); // Convert to relative path - let testIndex = fn.indexOf('tests/'); + let testIndex = fn.indexOf("tests/"); if (testIndex >= 0) fn = fn.substr(testIndex); if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { - it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => { + it(this.testSuiteName + " test " + justName + " runs correctly", () => { FourSlash.runFourSlashTest(this.basePath, this.testType, fn); }); } }); }); - describe('Generate Tao XML', () => { + describe("Generate Tao XML", () => { let invalidReasons: any = {}; FourSlash.xmlData.forEach(xml => { if (xml.invalidReason !== null) { @@ -69,37 +69,37 @@ class FourSlashRunner extends RunnerBase { invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1); let lines: string[] = []; - lines.push(''); - lines.push(''); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); + lines.push("-->"); + lines.push(""); + lines.push(" "); + lines.push(" "); + lines.push(" "); + lines.push(" "); FourSlash.xmlData.forEach(xml => { if (xml.invalidReason !== null) { - lines.push(''); + lines.push(""); } else { - lines.push(' '); + lines.push(" "); xml.actions.forEach(action => { - lines.push(' ' + action); + lines.push(" " + action); }); - lines.push(' '); + lines.push(" "); } }); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(''); - Harness.IO.writeFile('built/local/fourslash.xml', lines.join('\r\n')); + lines.push(" "); + lines.push(" "); + lines.push(" "); + lines.push(" "); + lines.push(" "); + lines.push(" "); + lines.push(" "); + lines.push(" "); + lines.push(""); + Harness.IO.writeFile("built/local/fourslash.xml", lines.join("\r\n")); }); }); } @@ -108,6 +108,6 @@ class FourSlashRunner extends RunnerBase { class GeneratedFourslashRunner extends FourSlashRunner { constructor(testType: FourSlashTestType) { super(testType); - this.basePath += '/generated/'; + this.basePath += "/generated/"; } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 47b388c494..e37a861008 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -14,24 +14,27 @@ // limitations under the License. // -/// -/// -/// -/// -/// -/// -/// -/// -/// +/// +/// +/// +/// +/// +/// +/// +/// +/// -var Buffer: BufferConstructor = require('buffer').Buffer; +// Block scoped definitions work poorly for global variables, temporarily enable var +/* tslint:disable:no-var-keyword */ +var Buffer: BufferConstructor = require("buffer").Buffer; // this will work in the browser via browserify -var _chai: typeof chai = require('chai'); +var _chai: typeof chai = require("chai"); var assert: typeof _chai.assert = _chai.assert; var expect: typeof _chai.expect = _chai.expect; declare var __dirname: string; // Node-specific var global = Function("return this").call(null); +/* tslint:enable:no-var-keyword */ module Utils { // Setup some globals based on the current environment @@ -63,7 +66,7 @@ module Utils { eval(fileContents); break; case ExecutionEnvironment.Node: - let vm = require('vm'); + let vm = require("vm"); if (nodeContext) { vm.runInNewContext(fileContents, nodeContext, fileName); } else { @@ -71,7 +74,7 @@ module Utils { } break; default: - throw new Error('Unknown context'); + throw new Error("Unknown context"); } } @@ -80,9 +83,9 @@ module Utils { // Split up the input file by line // Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so // we have to use string-based splitting instead and try to figure out the delimiting chars - let lines = content.split('\r\n'); + let lines = content.split("\r\n"); if (lines.length === 1) { - lines = content.split('\n'); + lines = content.split("\n"); if (lines.length === 1) { lines = content.split("\r"); @@ -93,7 +96,7 @@ module Utils { /** Reads a file under /tests */ export function readTestFile(path: string) { - if (path.indexOf('tests') < 0) { + if (path.indexOf("tests") < 0) { path = "tests/" + path; } @@ -388,7 +391,7 @@ module Utils { module Harness.Path { export function getFileName(fullPath: string) { - return fullPath.replace(/^.*[\\\/]/, ''); + return fullPath.replace(/^.*[\\\/]/, ""); } export function filePath(fullPath: string) { @@ -412,6 +415,7 @@ module Harness { log(text: string): void; getMemoryUsage?(): number; } + export var IO: IO; module IOImpl { declare class Enumerator { @@ -484,8 +488,8 @@ module Harness { declare let require: any; let fs: any, pathModule: any; if (require) { - fs = require('fs'); - pathModule = require('path'); + fs = require("fs"); + pathModule = require("path"); } else { fs = pathModule = {}; } @@ -559,8 +563,8 @@ module Harness { let serverRoot = "http://localhost:8888/"; // Unused? - let newLine = '\r\n'; - let currentDirectory = () => ''; + let newLine = "\r\n"; + let currentDirectory = () => ""; let supportsCodePage = () => false; module Http { @@ -606,9 +610,9 @@ module Harness { export function writeToServerSync(url: string, action: string, contents?: string): XHRResponse { let xhr = new XMLHttpRequest(); try { - let actionMsg = '?action=' + action; - xhr.open('POST', url + actionMsg, false); - xhr.setRequestHeader('Access-Control-Allow-Origin', '*'); + let actionMsg = "?action=" + action; + xhr.open("POST", url + actionMsg, false); + xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); xhr.send(contents); } catch (e) { @@ -624,7 +628,7 @@ module Harness { } export function deleteFile(path: string) { - Http.writeToServerSync(serverRoot + path, 'DELETE', null); + Http.writeToServerSync(serverRoot + path, "DELETE", null); } export function directoryExists(path: string): boolean { @@ -637,15 +641,15 @@ module Harness { if (dirPath.match(/localhost:\d+$/) || dirPath.match(/localhost:\d+\/$/)) { dirPath = null; // path + fileName - } else if (dirPath.indexOf('.') === -1) { - dirPath = dirPath.substring(0, dirPath.lastIndexOf('/')); + } else if (dirPath.indexOf(".") === -1) { + dirPath = dirPath.substring(0, dirPath.lastIndexOf("/")); // path } else { // strip any trailing slash if (dirPath.match(/.*\/$/)) { dirPath = dirPath.substring(0, dirPath.length - 2); } - dirPath = dirPath.substring(0, dirPath.lastIndexOf('/')); + dirPath = dirPath.substring(0, dirPath.lastIndexOf("/")); } return dirPath; @@ -660,7 +664,7 @@ module Harness { export function _listFilesImpl(path: string, spec?: RegExp, options?: any) { let response = Http.getFileFromServerSync(serverRoot + path); if (response.status === 200) { - let results = response.responseText.split(','); + let results = response.responseText.split(","); if (spec) { return results.filter(file => spec.test(file)); } else { @@ -668,7 +672,7 @@ module Harness { } } else { - return ['']; + return [""]; } }; export let listFiles = Utils.memoize(_listFilesImpl); @@ -685,12 +689,11 @@ module Harness { } export function writeFile(path: string, contents: string) { - Http.writeToServerSync(serverRoot + path, 'WRITE', contents); + Http.writeToServerSync(serverRoot + path, "WRITE", contents); } } } - export var IO: IO; switch (Utils.getExecutionEnvironment()) { case Utils.ExecutionEnvironment.CScript: IO = IOImpl.CScript; @@ -722,7 +725,7 @@ module Harness { tcServicesFileName = "built/local/typescriptServices.js"; break; default: - throw new Error('Unknown context'); + throw new Error("Unknown context"); } export let tcServicesFile = IO.readFile(tcServicesFileName); @@ -745,12 +748,12 @@ module Harness { public Write(str: string) { // out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later - this.currentLine = [(this.currentLine || ''), str].join(''); + this.currentLine = [(this.currentLine || ""), str].join(""); } public WriteLine(str: string) { // out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later - this.lines.push([(this.currentLine || ''), str].join('')); + this.lines.push([(this.currentLine || ""), str].join("")); this.currentLine = undefined; } @@ -799,7 +802,7 @@ module Harness { if (this.fileCollection.hasOwnProperty(p)) { let current = this.fileCollection[p]; if (current.lines.length > 0) { - if (p.indexOf('.d.ts') !== -1) { current.lines.unshift(['////[', Path.getFileName(p), ']'].join('')); } + if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); } result.push({ fileName: p, file: this.fileCollection[p] }); } } @@ -828,12 +831,12 @@ module Harness { const carriageReturnLineFeed = "\r\n"; const lineFeed = "\n"; - export let defaultLibFileName = 'lib.d.ts'; - export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); - export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); + export let defaultLibFileName = "lib.d.ts"; + export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest); + export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest); // Cache these between executions so we don't have to re-parse them for every test - export let fourslashFileName = 'fourslash.ts'; + export let fourslashFileName = "fourslash.ts"; export let fourslashSourceFile: ts.SourceFile; export function getCanonicalFileName(fileName: string): string { @@ -883,7 +886,7 @@ module Harness { return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined; } else if (fn === fourslashFileName) { - let tsFn = 'tests/cases/fourslash/' + fourslashFileName; + let tsFn = "tests/cases/fourslash/" + fourslashFileName; fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget); return fourslashSourceFile; } @@ -974,7 +977,7 @@ module Harness { settingsCallback(null); } - let newLine = '\r\n'; + let newLine = "\r\n"; options.skipDefaultLibCheck = true; // Files from built\local that are requested by test "@includeBuiltFiles" to be in the context. @@ -1011,19 +1014,19 @@ module Harness { // "fileName", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noimplicitany", "noresolve" case "module": case "modulegentarget": - if (typeof setting.value === 'string') { - if (setting.value.toLowerCase() === 'amd') { + if (typeof setting.value === "string") { + if (setting.value.toLowerCase() === "amd") { options.module = ts.ModuleKind.AMD; - } else if (setting.value.toLowerCase() === 'umd') { + } else if (setting.value.toLowerCase() === "umd") { options.module = ts.ModuleKind.UMD; - } else if (setting.value.toLowerCase() === 'commonjs') { + } else if (setting.value.toLowerCase() === "commonjs") { options.module = ts.ModuleKind.CommonJS; - } else if (setting.value.toLowerCase() === 'system') { + } else if (setting.value.toLowerCase() === "system") { options.module = ts.ModuleKind.System; - } else if (setting.value.toLowerCase() === 'unspecified') { + } else if (setting.value.toLowerCase() === "unspecified") { options.module = ts.ModuleKind.None; } else { - throw new Error('Unknown module type ' + setting.value); + throw new Error("Unknown module type " + setting.value); } } else { options.module = setting.value; @@ -1031,152 +1034,152 @@ module Harness { break; case "target": - case 'codegentarget': - if (typeof setting.value === 'string') { - if (setting.value.toLowerCase() === 'es3') { + case "codegentarget": + if (typeof setting.value === "string") { + if (setting.value.toLowerCase() === "es3") { options.target = ts.ScriptTarget.ES3; - } else if (setting.value.toLowerCase() === 'es5') { + } else if (setting.value.toLowerCase() === "es5") { options.target = ts.ScriptTarget.ES5; - } else if (setting.value.toLowerCase() === 'es6') { + } else if (setting.value.toLowerCase() === "es6") { options.target = ts.ScriptTarget.ES6; } else { - throw new Error('Unknown compile target ' + setting.value); + throw new Error("Unknown compile target " + setting.value); } } else { options.target = setting.value; } break; - case 'experimentaldecorators': - options.experimentalDecorators = setting.value === 'true'; + case "experimentaldecorators": + options.experimentalDecorators = setting.value === "true"; break; - case 'emitdecoratormetadata': - options.emitDecoratorMetadata = setting.value === 'true'; + case "emitdecoratormetadata": + options.emitDecoratorMetadata = setting.value === "true"; break; - case 'experimentalasyncfunctions': - options.experimentalAsyncFunctions = setting.value === 'true'; + case "experimentalasyncfunctions": + options.experimentalAsyncFunctions = setting.value === "true"; break; - case 'noemithelpers': - options.noEmitHelpers = setting.value === 'true'; + case "noemithelpers": + options.noEmitHelpers = setting.value === "true"; break; - case 'noemitonerror': - options.noEmitOnError = setting.value === 'true'; + case "noemitonerror": + options.noEmitOnError = setting.value === "true"; break; - case 'noresolve': - options.noResolve = setting.value === 'true'; + case "noresolve": + options.noResolve = setting.value === "true"; break; - case 'noimplicitany': - options.noImplicitAny = setting.value === 'true'; + case "noimplicitany": + options.noImplicitAny = setting.value === "true"; break; - case 'nolib': - options.noLib = setting.value === 'true'; + case "nolib": + options.noLib = setting.value === "true"; break; - case 'out': - case 'outfileoption': + case "out": + case "outfileoption": options.out = setting.value; break; - case 'outdiroption': - case 'outdir': + case "outdiroption": + case "outdir": options.outDir = setting.value; break; - case 'skipdefaultlibcheck': + case "skipdefaultlibcheck": options.skipDefaultLibCheck = setting.value === "true"; break; - case 'sourceroot': + case "sourceroot": options.sourceRoot = setting.value; break; - case 'maproot': + case "maproot": options.mapRoot = setting.value; break; - case 'sourcemap': - options.sourceMap = setting.value === 'true'; + case "sourcemap": + options.sourceMap = setting.value === "true"; break; - case 'declaration': - options.declaration = setting.value === 'true'; + case "declaration": + options.declaration = setting.value === "true"; break; - case 'newline': - if (setting.value.toLowerCase() === 'crlf') { + case "newline": + if (setting.value.toLowerCase() === "crlf") { options.newLine = ts.NewLineKind.CarriageReturnLineFeed; } - else if (setting.value.toLowerCase() === 'lf') { + else if (setting.value.toLowerCase() === "lf") { options.newLine = ts.NewLineKind.LineFeed; } else { - throw new Error('Unknown option for newLine: ' + setting.value); + throw new Error("Unknown option for newLine: " + setting.value); } break; - case 'comments': - options.removeComments = setting.value === 'false'; + case "comments": + options.removeComments = setting.value === "false"; break; - case 'stripinternal': - options.stripInternal = setting.value === 'true'; + case "stripinternal": + options.stripInternal = setting.value === "true"; - case 'usecasesensitivefilenames': - useCaseSensitiveFileNames = setting.value === 'true'; + case "usecasesensitivefilenames": + useCaseSensitiveFileNames = setting.value === "true"; break; - case 'filename': + case "filename": // Not supported yet break; - case 'emitbom': - options.emitBOM = setting.value === 'true'; + case "emitbom": + options.emitBOM = setting.value === "true"; break; - case 'errortruncation': - options.noErrorTruncation = setting.value === 'false'; + case "errortruncation": + options.noErrorTruncation = setting.value === "false"; break; - case 'preserveconstenums': - options.preserveConstEnums = setting.value === 'true'; + case "preserveconstenums": + options.preserveConstEnums = setting.value === "true"; break; - case 'isolatedmodules': - options.isolatedModules = setting.value === 'true'; + case "isolatedmodules": + options.isolatedModules = setting.value === "true"; break; - case 'suppressimplicitanyindexerrors': - options.suppressImplicitAnyIndexErrors = setting.value === 'true'; + case "suppressimplicitanyindexerrors": + options.suppressImplicitAnyIndexErrors = setting.value === "true"; break; - case 'includebuiltfile': + case "includebuiltfile": let builtFileName = libFolder + setting.value; includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) }); break; - case 'inlinesourcemap': - options.inlineSourceMap = setting.value === 'true'; + case "inlinesourcemap": + options.inlineSourceMap = setting.value === "true"; break; - case 'inlinesources': - options.inlineSources = setting.value === 'true'; + case "inlinesources": + options.inlineSources = setting.value === "true"; break; - case 'jsx': - options.jsx = setting.value.toLowerCase() === 'react' ? ts.JsxEmit.React : - setting.value.toLowerCase() === 'preserve' ? ts.JsxEmit.Preserve : + case "jsx": + options.jsx = setting.value.toLowerCase() === "react" ? ts.JsxEmit.React : + setting.value.toLowerCase() === "preserve" ? ts.JsxEmit.Preserve : ts.JsxEmit.None; break; default: - throw new Error('Unsupported compiler setting ' + setting.flag); + throw new Error("Unsupported compiler setting " + setting.flag); } } } @@ -1189,7 +1192,7 @@ module Harness { // Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file currentDirectory?: string) { if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) { - throw new Error('There were no errors and declFiles generated did not match number of js files generated'); + throw new Error("There were no errors and declFiles generated did not match number of js files generated"); } let declInputFiles: { unitName: string; content: string }[] = []; @@ -1250,8 +1253,8 @@ module Harness { } function normalizeLineEndings(text: string, lineEnding: string): string { - let normalized = text.replace(/\r\n?/g, '\n'); - if (lineEnding !== '\n') { + let normalized = text.replace(/\r\n?/g, "\n"); + if (lineEnding !== "\n") { normalized = normalized.replace(/\n/g, lineEnding); } return normalized; @@ -1282,10 +1285,10 @@ module Harness { let message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine); let errLines = RunnerBase.removeFullPaths(message) - .split('\n') - .map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s) + .split("\n") + .map(s => s.length > 0 && s.charAt(s.length - 1) === "\r" ? s.substr(0, s.length - 1) : s) .filter(s => s.length > 0) - .map(s => '!!! ' + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s); + .map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s); errLines.forEach(e => outputLines.push(e)); totalErrorsReported++; @@ -1305,7 +1308,7 @@ module Harness { // Header - outputLines.push('==== ' + inputFile.unitName + ' (' + fileErrors.length + ' errors) ===='); + outputLines.push("==== " + inputFile.unitName + " (" + fileErrors.length + " errors) ===="); // Make sure we emit something for every error let markedErrorCount = 0; @@ -1314,13 +1317,13 @@ module Harness { // we have to string-based splitting instead and try to figure out the delimiting chars let lineStarts = ts.computeLineStarts(inputFile.content); - let lines = inputFile.content.split('\n'); + let lines = inputFile.content.split("\n"); if (lines.length === 1) { lines = lines[0].split("\r"); } lines.forEach((line, lineIndex) => { - if (line.length > 0 && line.charAt(line.length - 1) === '\r') { + if (line.length > 0 && line.charAt(line.length - 1) === "\r") { line = line.substr(0, line.length - 1); } @@ -1333,7 +1336,7 @@ module Harness { nextLineStart = lineStarts[lineIndex + 1]; } // Emit this line from the original file - outputLines.push(' ' + line); + outputLines.push(" " + line); fileErrors.forEach(err => { // Does any error start or continue on to this line? Emit squiggles let end = ts.textSpanEnd(err); @@ -1345,7 +1348,7 @@ module Harness { // Calculate the start of the squiggle let squiggleStart = Math.max(0, relativeOffset); // TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another - outputLines.push(' ' + line.substr(0, squiggleStart).replace(/[^\s]/g, ' ') + new Array(Math.min(length, line.length - squiggleStart) + 1).join('~')); + outputLines.push(" " + line.substr(0, squiggleStart).replace(/[^\s]/g, " ") + new Array(Math.min(length, line.length - squiggleStart) + 1).join("~")); // If the error ended here, or we're at the end of the file, emit its message if ((lineIndex === lines.length - 1) || nextLineStart > end) { @@ -1360,7 +1363,7 @@ module Harness { }); // Verify we didn't miss any errors in this file - assert.equal(markedErrorCount, fileErrors.length, 'count of errors in ' + inputFile.unitName); + assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName); }); let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => { @@ -1373,10 +1376,10 @@ module Harness { }); // Verify we didn't miss any errors in total - assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, 'total number of errors'); + assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); return minimalDiagnosticsToString(diagnostics) + - ts.sys.newLine + ts.sys.newLine + outputLines.join('\r\n'); + ts.sys.newLine + ts.sys.newLine + outputLines.join("\r\n"); } export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string { @@ -1384,15 +1387,15 @@ module Harness { outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName))); // Emit them - let result = ''; + let result = ""; for (let outputFile of outputFiles) { // Some extra spacing if this isn't the first file if (result.length) { - result += '\r\n\r\n'; + result += "\r\n\r\n"; } // FileName header + content - result += '/*====== ' + outputFile.fileName + ' ======*/\r\n'; + result += "/*====== " + outputFile.fileName + " ======*/\r\n"; result += outputFile.code; } @@ -1400,7 +1403,7 @@ module Harness { return result; function cleanName(fn: string) { - let lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/'); + let lastSlash = ts.normalizeSlashes(fn).lastIndexOf("/"); return fn.substr(lastSlash + 1).toLowerCase(); } } @@ -1418,7 +1421,7 @@ module Harness { // This does not need to exist strictly speaking, but many tests will need to be updated if it's removed export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) { // NEWTODO: Re-implement 'compileString' - throw new Error('compileString NYI'); + throw new Error("compileString NYI"); } export interface GeneratedFile { @@ -1432,26 +1435,26 @@ module Harness { } export function isTS(fileName: string) { - return stringEndsWith(fileName, '.ts'); + return stringEndsWith(fileName, ".ts"); } export function isTSX(fileName: string) { - return stringEndsWith(fileName, '.tsx'); + return stringEndsWith(fileName, ".tsx"); } export function isDTS(fileName: string) { - return stringEndsWith(fileName, '.d.ts'); + return stringEndsWith(fileName, ".d.ts"); } export function isJS(fileName: string) { - return stringEndsWith(fileName, '.js'); + return stringEndsWith(fileName, ".js"); } export function isJSX(fileName: string) { - return stringEndsWith(fileName, '.jsx'); + return stringEndsWith(fileName, ".jsx"); } export function isJSMap(fileName: string) { - return stringEndsWith(fileName, '.js.map') || stringEndsWith(fileName, '.jsx.map'); + return stringEndsWith(fileName, ".js.map") || stringEndsWith(fileName, ".jsx.map"); } /** Contains the code and errors of a compilation and some helper methods to check its status. */ @@ -1478,7 +1481,7 @@ module Harness { this.sourceMaps.push(emittedFile); } else { - throw new Error('Unrecognized file extension for file ' + emittedFile.fileName); + throw new Error("Unrecognized file extension for file " + emittedFile.fileName); } }); @@ -1587,10 +1590,10 @@ module Harness { // Subfile content line // Append to the current subfile content, inserting a newline needed if (currentFileContent === null) { - currentFileContent = ''; + currentFileContent = ""; } else { // End-of-line - currentFileContent = currentFileContent + '\n'; + currentFileContent = currentFileContent + "\n"; } currentFileContent = currentFileContent + line; } @@ -1601,7 +1604,7 @@ module Harness { // EOF, push whatever remains let newTestFile2 = { - content: currentFileContent || '', + content: currentFileContent || "", name: currentFileName, fileOptions: currentFileOptions, originalFilePath: fileName, @@ -1623,27 +1626,27 @@ module Harness { export function localPath(fileName: string, baselineFolder?: string, subfolder?: string) { if (baselineFolder === undefined) { - return baselinePath(fileName, 'local', 'tests/baselines', subfolder); + return baselinePath(fileName, "local", "tests/baselines", subfolder); } else { - return baselinePath(fileName, 'local', baselineFolder, subfolder); + return baselinePath(fileName, "local", baselineFolder, subfolder); } } function referencePath(fileName: string, baselineFolder?: string, subfolder?: string) { if (baselineFolder === undefined) { - return baselinePath(fileName, 'reference', 'tests/baselines', subfolder); + return baselinePath(fileName, "reference", "tests/baselines", subfolder); } else { - return baselinePath(fileName, 'reference', baselineFolder, subfolder); + return baselinePath(fileName, "reference", baselineFolder, subfolder); } } function baselinePath(fileName: string, type: string, baselineFolder: string, subfolder?: string) { if (subfolder !== undefined) { - return Harness.userSpecifiedRoot + baselineFolder + '/' + subfolder + '/' + type + '/' + fileName; + return Harness.userSpecifiedRoot + baselineFolder + "/" + subfolder + "/" + type + "/" + fileName; } else { - return Harness.userSpecifiedRoot + baselineFolder + '/' + type + '/' + fileName; + return Harness.userSpecifiedRoot + baselineFolder + "/" + type + "/" + fileName; } } @@ -1677,7 +1680,7 @@ module Harness { let actual = generateContent(); if (actual === undefined) { - throw new Error('The generated content was "undefined". Return "null" if no baselining is required."'); + throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\""); } // Store the content in the 'local' folder so we @@ -1700,10 +1703,10 @@ module Harness { let refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder); if (actual === null) { - actual = ''; + actual = ""; } - let expected = ''; + let expected = ""; if (IO.fileExists(refFileName)) { expected = IO.readFile(refFileName); } @@ -1712,10 +1715,10 @@ module Harness { } function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) { - let encoded_actual = (new Buffer(actual)).toString('utf8'); + let encoded_actual = (new Buffer(actual)).toString("utf8"); if (expected != encoded_actual) { // Overwrite & issue error - let errMsg = 'The baseline file ' + relativeFileName + ' has changed'; + let errMsg = "The baseline file " + relativeFileName + " has changed"; throw new Error(errMsg); } } @@ -1744,7 +1747,7 @@ module Harness { } export function isLibraryFile(filePath: string): boolean { - return (Path.getFileName(filePath) === 'lib.d.ts') || (Path.getFileName(filePath) === 'lib.core.d.ts'); + return (Path.getFileName(filePath) === "lib.d.ts") || (Path.getFileName(filePath) === "lib.core.d.ts"); } export function isBuiltFile(filePath: string): boolean { diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 3c543e5056..0a35e3b4ed 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -1,7 +1,7 @@ -/// -/// -/// -/// +/// +/// +/// +/// module Harness.LanguageService { export class ScriptInfo { @@ -242,7 +242,7 @@ module Harness.LanguageService { throw new Error("NYI"); } getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult { - let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n'); + let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split("\n"); let entries: ts.ClassificationInfo[] = []; let i = 0; let position = 0; diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index c7b57a7d51..db82a47d36 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -73,7 +73,7 @@ interface PlaybackControl { module Playback { let recordLog: IOLog = undefined; let replayLog: IOLog = undefined; - let recordLogFileNameBase = ''; + let recordLogFileNameBase = ""; interface Memoized { (s: string): T; @@ -99,7 +99,7 @@ module Playback { return { timestamp: (new Date()).toString(), arguments: [], - currentDirectory: '', + currentDirectory: "", filesRead: [], filesWritten: [], filesDeleted: [], @@ -110,7 +110,7 @@ module Playback { dirExists: [], dirsCreated: [], pathsResolved: [], - executingPath: '' + executingPath: "" }; } @@ -170,7 +170,7 @@ module Playback { if (defaultValue !== undefined) { return defaultValue; } else { - throw new Error('No matching result in log array for: ' + JSON.stringify(expectedFields)); + throw new Error("No matching result in log array for: " + JSON.stringify(expectedFields)); } } return results[0].result; @@ -195,7 +195,7 @@ module Playback { } // If we got here, we didn't find a match if (defaultValue === undefined) { - throw new Error('No matching result in log array for path: ' + expectedPath); + throw new Error("No matching result in log array for path: " + expectedPath); } else { return defaultValue; } @@ -203,7 +203,7 @@ module Playback { let pathEquivCache: any = {}; function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) { - let key = left + '-~~-' + right; + let key = left + "-~~-" + right; function areSame(a: string, b: string) { return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase(); } @@ -233,14 +233,14 @@ module Playback { wrapper.endRecord = () => { if (recordLog !== undefined) { let i = 0; - let fn = () => recordLogFileNameBase + i + '.json'; + let fn = () => recordLogFileNameBase + i + ".json"; while (underlying.fileExists(fn())) i++; underlying.writeFile(fn(), JSON.stringify(recordLog)); recordLog = undefined; } }; - Object.defineProperty(wrapper, 'args', { + Object.defineProperty(wrapper, "args", { get() { if (replayLog !== undefined) { return replayLog.arguments; @@ -276,7 +276,7 @@ module Playback { wrapper.getCurrentDirectory = () => { if (replayLog !== undefined) { - return replayLog.currentDirectory || ''; + return replayLog.currentDirectory || ""; } else if (recordLog !== undefined) { return recordLog.currentDirectory = underlying.getCurrentDirectory(); } else { @@ -286,7 +286,7 @@ module Playback { wrapper.resolvePath = recordReplay(wrapper.resolvePath, underlying)( (path) => callAndRecord(underlying.resolvePath(path), recordLog.pathsResolved, { path: path }), - memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + '/' + path : ts.normalizeSlashes(path)))); + memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + "/" + path : ts.normalizeSlashes(path)))); wrapper.readFile = recordReplay(wrapper.readFile, underlying)( (path) => { @@ -299,7 +299,7 @@ module Playback { wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)( (path, contents) => callAndRecord(underlying.writeFile(path, contents), recordLog.filesWritten, { path: path, contents: contents, bom: false }), - (path, contents) => noOpReplay('writeFile')); + (path, contents) => noOpReplay("writeFile")); wrapper.exit = (exitCode) => { if (recordLog !== undefined) { diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 5ea118aacb..c91f789940 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -74,7 +74,7 @@ class ProjectRunner extends RunnerBase { catch (e) { assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message); } - let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, ""); + let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, "").replace(/\.json/, ""); function moduleNameToString(moduleKind: ts.ModuleKind) { return moduleKind === ts.ModuleKind.AMD @@ -331,9 +331,9 @@ class ProjectRunner extends RunnerBase { return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors); } - let name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName; + let name = "Compiling project for " + testCase.scenario + ": testcase " + testCaseFileName; - describe('Projects tests', () => { + describe("Projects tests", () => { describe(name, () => { function verifyCompilerResults(moduleKind: ts.ModuleKind) { let compilerResult: BatchCompileProjectTestCaseResult; @@ -367,27 +367,27 @@ class ProjectRunner extends RunnerBase { compilerResult = batchCompilerProjectTestCase(moduleKind); }); - it('Resolution information of (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => { + it("Resolution information of (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { + Harness.Baseline.runBaseline("Resolution information of (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".json", () => { return JSON.stringify(getCompilerResolutionInfo(), undefined, " "); }); }); - it('Errors for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + it("Errors for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { if (compilerResult.errors.length) { - Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => { + Harness.Baseline.runBaseline("Errors for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".errors.txt", () => { return getErrorsBaseline(compilerResult); }); } }); - it('Baseline of emitted result (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + it("Baseline of emitted result (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { if (testCase.baselineCheck) { ts.forEach(compilerResult.outputFiles, outputFile => { - Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { + Harness.Baseline.runBaseline("Baseline of emitted result (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { try { return ts.sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind)); } @@ -400,9 +400,9 @@ class ProjectRunner extends RunnerBase { }); - it('SourceMapRecord for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + it("SourceMapRecord for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { if (compilerResult.sourceMapData) { - Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => { + Harness.Baseline.runBaseline("SourceMapRecord for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".sourcemap.txt", () => { return Harness.SourceMapRecoder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program, ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName))); }); @@ -411,11 +411,11 @@ class ProjectRunner extends RunnerBase { // Verify that all the generated .d.ts files compile - it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { if (!compilerResult.errors.length && testCase.declaration) { let dTsCompileResult = compileCompileDTsFiles(compilerResult); if (dTsCompileResult.errors.length) { - Harness.Baseline.runBaseline('Errors in generated Dts files for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.dts.errors.txt', () => { + Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => { return getErrorsBaseline(dTsCompileResult); }); } diff --git a/src/harness/runner.ts b/src/harness/runner.ts index e4ed604e98..06aaf3d32b 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -13,12 +13,12 @@ // limitations under the License. // -/// -/// -/// -/// -/// -/// +/// +/// +/// +/// +/// +/// let runners: RunnerBase[] = []; let iterations: number = 1; @@ -32,13 +32,13 @@ function runTests(runners: RunnerBase[]) { } // users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options -let mytestconfig = 'mytest.config'; -let testconfig = 'test.config'; +let mytestconfig = "mytest.config"; +let testconfig = "test.config"; let testConfigFile = Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) : - (Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : ''); + (Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : ""); -if (testConfigFile !== '') { +if (testConfigFile !== "") { let testConfig = JSON.parse(testConfigFile); if (testConfig.light) { Harness.lightMode = true; @@ -51,33 +51,33 @@ if (testConfigFile !== '') { } switch (option) { - case 'compiler': + case "compiler": runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance)); runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions)); runners.push(new ProjectRunner()); break; - case 'conformance': + case "conformance": runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance)); break; - case 'project': + case "project": runners.push(new ProjectRunner()); break; - case 'fourslash': + case "fourslash": runners.push(new FourSlashRunner(FourSlashTestType.Native)); break; - case 'fourslash-shims': + case "fourslash-shims": runners.push(new FourSlashRunner(FourSlashTestType.Shims)); break; - case 'fourslash-server': + case "fourslash-server": runners.push(new FourSlashRunner(FourSlashTestType.Server)); break; - case 'fourslash-generated': + case "fourslash-generated": runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native)); break; - case 'rwc': + case "rwc": runners.push(new RWCRunner()); break; - case 'test262': + case "test262": runners.push(new Test262BaselineRunner()); break; } @@ -102,6 +102,6 @@ if (runners.length === 0) { // runners.push(new GeneratedFourslashRunner()); } -ts.sys.newLine = '\r\n'; +ts.sys.newLine = "\r\n"; runTests(runners); diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 406ca7caea..afe757ea82 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -33,7 +33,7 @@ abstract class RunnerBase { // when running in the browser the 'full path' is the host name, shows up in error baselines let localHost = /http:\/localhost:\d+/g; - fixedPath = fixedPath.replace(localHost, ''); + fixedPath = fixedPath.replace(localHost, ""); return fixedPath; } } \ No newline at end of file diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 54aeff18ef..d8b52ec2e3 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -1,7 +1,7 @@ -/// -/// -/// -/// +/// +/// +/// +/// module RWC { function runWithIOLog(ioLog: IOLog, fn: () => void) { @@ -26,8 +26,8 @@ module RWC { let compilerResult: Harness.Compiler.CompilerResult; let compilerOptions: ts.CompilerOptions; let baselineOpts: Harness.Baseline.BaselineOptions = { - Subfolder: 'rwc', - Baselinefolder: 'internal/baselines' + Subfolder: "rwc", + Baselinefolder: "internal/baselines" }; let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2]; let currentDirectory: string; @@ -49,7 +49,7 @@ module RWC { useCustomLibraryFile = undefined; }); - it('can compile', () => { + it("can compile", () => { let harnessCompiler = Harness.Compiler.getCompiler(); let opts: ts.ParsedCommandLine; @@ -74,10 +74,11 @@ module RWC { }); // Add files to compilation + let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath; for (let fileRead of ioLog.filesRead) { // Check if the file is already added into the set of input files. - var resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path)); - let inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath); + const resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path)); + let inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath)); if (!Harness.isLibraryFile(fileRead.path)) { if (inInputList) { @@ -130,14 +131,14 @@ module RWC { }); - it('has the expected emitted code', () => { - Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => { + it("has the expected emitted code", () => { + Harness.Baseline.runBaseline("has the expected emitted code", baseName + ".output.js", () => { return Harness.Compiler.collateOutputs(compilerResult.files); }, false, baselineOpts); }); - it('has the expected declaration file content', () => { - Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => { + it("has the expected declaration file content", () => { + Harness.Baseline.runBaseline("has the expected declaration file content", baseName + ".d.ts", () => { if (!compilerResult.declFilesCode.length) { return null; } @@ -146,8 +147,8 @@ module RWC { }, false, baselineOpts); }); - it('has the expected source maps', () => { - Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => { + it("has the expected source maps", () => { + Harness.Baseline.runBaseline("has the expected source maps", baseName + ".map", () => { if (!compilerResult.sourceMaps.length) { return null; } @@ -156,16 +157,16 @@ module RWC { }, false, baselineOpts); }); - /*it('has correct source map record', () => { + /*it("has correct source map record", () => { if (compilerOptions.sourceMap) { - Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => { + Harness.Baseline.runBaseline("has correct source map record", baseName + ".sourcemap.txt", () => { return compilerResult.getSourceMapRecord(); }, false, baselineOpts); } });*/ - it('has the expected errors', () => { - Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => { + it("has the expected errors", () => { + Harness.Baseline.runBaseline("has the expected errors", baseName + ".errors.txt", () => { if (compilerResult.errors.length === 0) { return null; } @@ -176,9 +177,9 @@ module RWC { // Ideally, a generated declaration file will have no errors. But we allow generated // declaration file errors as part of the baseline. - it('has the expected errors in generated declaration files', () => { + it("has the expected errors in generated declaration files", () => { if (compilerOptions.declaration && !compilerResult.errors.length) { - Harness.Baseline.runBaseline('has the expected errors in generated declaration files', baseName + '.dts.errors.txt', () => { + Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => { let declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult, /*settingscallback*/ undefined, compilerOptions, currentDirectory); if (declFileCompilationResult.declResult.errors.length === 0) { diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts index 767dd37949..55ca9ea965 100644 --- a/src/harness/sourceMapRecorder.ts +++ b/src/harness/sourceMapRecorder.ts @@ -13,7 +13,7 @@ // limitations under the License. // -/// +/// module Harness.SourceMapRecoder { @@ -50,11 +50,11 @@ module Harness.SourceMapRecoder { return true; } - if (sourceMapMappings.charAt(decodingIndex) == ',') { + if (sourceMapMappings.charAt(decodingIndex) == ",") { return true; } - if (sourceMapMappings.charAt(decodingIndex) == ';') { + if (sourceMapMappings.charAt(decodingIndex) == ";") { return true; } @@ -117,7 +117,7 @@ module Harness.SourceMapRecoder { } while (decodingIndex < sourceMapMappings.length) { - if (sourceMapMappings.charAt(decodingIndex) == ';') { + if (sourceMapMappings.charAt(decodingIndex) == ";") { // New line decodeOfEncodedMapping.emittedLine++; decodeOfEncodedMapping.emittedColumn = 1; @@ -125,7 +125,7 @@ module Harness.SourceMapRecoder { continue; } - if (sourceMapMappings.charAt(decodingIndex) == ',') { + if (sourceMapMappings.charAt(decodingIndex) == ",") { // Next entry is on same line - no action needed decodingIndex++; continue; @@ -459,6 +459,6 @@ module Harness.SourceMapRecoder { SourceMapSpanWriter.close(); // If the last spans werent emitted, emit them } sourceMapRecoder.Close(); - return sourceMapRecoder.lines.join('\r\n'); + return sourceMapRecoder.lines.join("\r\n"); } } diff --git a/src/harness/test262Runner.ts b/src/harness/test262Runner.ts index e34e58844a..d9bbd55e7a 100644 --- a/src/harness/test262Runner.ts +++ b/src/harness/test262Runner.ts @@ -1,9 +1,9 @@ -/// -/// +/// +/// class Test262BaselineRunner extends RunnerBase { - private static basePath = 'internal/cases/test262'; - private static helpersFilePath = 'tests/cases/test262-harness/helpers.d.ts'; + private static basePath = "internal/cases/test262"; + private static helpersFilePath = "tests/cases/test262-harness/helpers.d.ts"; private static helperFile = { unitName: Test262BaselineRunner.helpersFilePath, content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath) @@ -15,8 +15,8 @@ class Test262BaselineRunner extends RunnerBase { module: ts.ModuleKind.CommonJS }; private static baselineOptions: Harness.Baseline.BaselineOptions = { - Subfolder: 'test262', - Baselinefolder: 'internal/baselines' + Subfolder: "test262", + Baselinefolder: "internal/baselines" }; private static getTestFilePath(filename: string): string { @@ -24,7 +24,7 @@ class Test262BaselineRunner extends RunnerBase { } private runTest(filePath: string) { - describe('test262 test for ' + filePath, () => { + describe("test262 test for " + filePath, () => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Everything declared here should be cleared out in the "after" callback. let testState: { @@ -36,7 +36,7 @@ class Test262BaselineRunner extends RunnerBase { before(() => { let content = Harness.IO.readFile(filePath); - let testFilename = ts.removeFileExtension(filePath).replace(/\//g, '_') + ".test"; + let testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test"; let testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename); let inputFiles = testCaseContent.testUnitData.map(unit => { @@ -61,15 +61,15 @@ class Test262BaselineRunner extends RunnerBase { testState = undefined; }); - it('has the expected emitted code', () => { - Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => { + it("has the expected emitted code", () => { + Harness.Baseline.runBaseline("has the expected emitted code", testState.filename + ".output.js", () => { let files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath); return Harness.Compiler.collateOutputs(files); }, false, Test262BaselineRunner.baselineOptions); }); - it('has the expected errors', () => { - Harness.Baseline.runBaseline('has the expected errors', testState.filename + '.errors.txt', () => { + it("has the expected errors", () => { + Harness.Baseline.runBaseline("has the expected errors", testState.filename + ".errors.txt", () => { let errors = testState.compilerResult.errors; if (errors.length === 0) { return null; @@ -79,13 +79,13 @@ class Test262BaselineRunner extends RunnerBase { }, false, Test262BaselineRunner.baselineOptions); }); - it('satisfies inletiants', () => { + it("satisfies inletiants", () => { let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename)); Utils.assertInvariants(sourceFile, /*parent:*/ undefined); }); - it('has the expected AST', () => { - Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt', () => { + it("has the expected AST", () => { + Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => { let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename)); return Utils.sourceFileToJSON(sourceFile); }, false, Test262BaselineRunner.baselineOptions); diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index db748f7f49..3b291b6e39 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -418,6 +418,7 @@ namespace ts.formatting { case SyntaxKind.DefaultClause: case SyntaxKind.CaseClause: case SyntaxKind.ParenthesizedExpression: + case SyntaxKind.PropertyAccessExpression: case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: case SyntaxKind.VariableStatement: diff --git a/tests/baselines/reference/apparentTypeSupertype.errors.txt b/tests/baselines/reference/apparentTypeSupertype.errors.txt index 7d653f34bf..5fe5c92a5b 100644 --- a/tests/baselines/reference/apparentTypeSupertype.errors.txt +++ b/tests/baselines/reference/apparentTypeSupertype.errors.txt @@ -1,6 +1,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(9,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. Types of property 'x' are incompatible. Type 'U' is not assignable to type 'string'. + Type 'String' is not assignable to type 'string'. ==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts (1 errors) ==== @@ -17,5 +18,6 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty !!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'x' are incompatible. !!! error TS2415: Type 'U' is not assignable to type 'string'. +!!! error TS2415: Type 'String' is not assignable to type 'string'. x: U; } \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt b/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt index 0a9b50ff0b..c5987a93dd 100644 --- a/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt @@ -12,12 +12,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(33,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. + Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(36,9): error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A'. Index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(37,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. + Type 'Base' is not assignable to type 'Derived2'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts (6 errors) ==== @@ -72,6 +74,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived'. var b2: { [x: number]: Derived2; } a = b2; // error @@ -84,6 +87,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. var b3: { [x: number]: T; } a = b3; // ok diff --git a/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt b/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt index b15f2f7905..f91d0dd0c1 100644 --- a/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt @@ -12,12 +12,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(33,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. + Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(36,9): error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A'. Index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(37,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. + Type 'Base' is not assignable to type 'Derived2'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts (6 errors) ==== @@ -72,6 +74,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived'. var b2: { [x: number]: Derived2; } a = b2; // error @@ -84,6 +87,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. var b3: { [x: number]: T; } a = b3; // ok diff --git a/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt b/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt index f002c70e90..51762bb941 100644 --- a/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt @@ -18,12 +18,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(47,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. + Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(50,9): error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A'. Index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(51,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. + Type 'Base' is not assignable to type 'Derived2'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts (8 errors) ==== @@ -100,6 +102,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived'. var b4: { [x: string]: Derived2; }; a3 = b4; // error @@ -112,5 +115,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. } } \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt b/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt index c322364280..0b0d70d01b 100644 --- a/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt @@ -18,12 +18,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(47,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. + Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(50,9): error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A'. Index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(51,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. + Type 'Base' is not assignable to type 'Derived2'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts (8 errors) ==== @@ -100,6 +102,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived'. var b4: { [x: string]: Derived2; }; a3 = b4; // error @@ -112,5 +115,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. } } \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt b/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt index a31b2ef302..4b4c03678d 100644 --- a/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt @@ -5,6 +5,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer3.ts(21,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: string; }'. Index signatures are incompatible. Type 'T' is not assignable to type 'string'. + Type 'Derived' is not assignable to type 'string'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer3.ts (3 errors) ==== @@ -39,5 +40,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: string; }'. !!! error TS2322: Index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'string'. +!!! error TS2322: Type 'Derived' is not assignable to type 'string'. } } \ No newline at end of file diff --git a/tests/baselines/reference/assignmentNonObjectTypeConstraints.js b/tests/baselines/reference/assignmentNonObjectTypeConstraints.js new file mode 100644 index 0000000000..c9d3cec38f --- /dev/null +++ b/tests/baselines/reference/assignmentNonObjectTypeConstraints.js @@ -0,0 +1,42 @@ +//// [assignmentNonObjectTypeConstraints.ts] +const enum E { A, B, C } + +function foo(x: T) { + var y: number = x; // Ok +} + +foo(5); +foo(E.A); + +class A { a } +class B { b } + +function bar(x: T) { + var y: A | B = x; // Ok +} + +bar(new A); +bar(new B); + + +//// [assignmentNonObjectTypeConstraints.js] +function foo(x) { + var y = x; // Ok +} +foo(5); +foo(0 /* A */); +var A = (function () { + function A() { + } + return A; +})(); +var B = (function () { + function B() { + } + return B; +})(); +function bar(x) { + var y = x; // Ok +} +bar(new A); +bar(new B); diff --git a/tests/baselines/reference/assignmentNonObjectTypeConstraints.symbols b/tests/baselines/reference/assignmentNonObjectTypeConstraints.symbols new file mode 100644 index 0000000000..d8bff5df5f --- /dev/null +++ b/tests/baselines/reference/assignmentNonObjectTypeConstraints.symbols @@ -0,0 +1,58 @@ +=== tests/cases/compiler/assignmentNonObjectTypeConstraints.ts === +const enum E { A, B, C } +>E : Symbol(E, Decl(assignmentNonObjectTypeConstraints.ts, 0, 0)) +>A : Symbol(E.A, Decl(assignmentNonObjectTypeConstraints.ts, 0, 14)) +>B : Symbol(E.B, Decl(assignmentNonObjectTypeConstraints.ts, 0, 17)) +>C : Symbol(E.C, Decl(assignmentNonObjectTypeConstraints.ts, 0, 20)) + +function foo(x: T) { +>foo : Symbol(foo, Decl(assignmentNonObjectTypeConstraints.ts, 0, 24)) +>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 2, 13)) +>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 2, 31)) +>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 2, 13)) + + var y: number = x; // Ok +>y : Symbol(y, Decl(assignmentNonObjectTypeConstraints.ts, 3, 7)) +>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 2, 31)) +} + +foo(5); +>foo : Symbol(foo, Decl(assignmentNonObjectTypeConstraints.ts, 0, 24)) + +foo(E.A); +>foo : Symbol(foo, Decl(assignmentNonObjectTypeConstraints.ts, 0, 24)) +>E.A : Symbol(E.A, Decl(assignmentNonObjectTypeConstraints.ts, 0, 14)) +>E : Symbol(E, Decl(assignmentNonObjectTypeConstraints.ts, 0, 0)) +>A : Symbol(E.A, Decl(assignmentNonObjectTypeConstraints.ts, 0, 14)) + +class A { a } +>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9)) +>a : Symbol(a, Decl(assignmentNonObjectTypeConstraints.ts, 9, 9)) + +class B { b } +>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13)) +>b : Symbol(b, Decl(assignmentNonObjectTypeConstraints.ts, 10, 9)) + +function bar(x: T) { +>bar : Symbol(bar, Decl(assignmentNonObjectTypeConstraints.ts, 10, 13)) +>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 12, 13)) +>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9)) +>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13)) +>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 12, 30)) +>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 12, 13)) + + var y: A | B = x; // Ok +>y : Symbol(y, Decl(assignmentNonObjectTypeConstraints.ts, 13, 7)) +>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9)) +>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13)) +>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 12, 30)) +} + +bar(new A); +>bar : Symbol(bar, Decl(assignmentNonObjectTypeConstraints.ts, 10, 13)) +>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9)) + +bar(new B); +>bar : Symbol(bar, Decl(assignmentNonObjectTypeConstraints.ts, 10, 13)) +>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13)) + diff --git a/tests/baselines/reference/assignmentNonObjectTypeConstraints.types b/tests/baselines/reference/assignmentNonObjectTypeConstraints.types new file mode 100644 index 0000000000..94391e2ea5 --- /dev/null +++ b/tests/baselines/reference/assignmentNonObjectTypeConstraints.types @@ -0,0 +1,65 @@ +=== tests/cases/compiler/assignmentNonObjectTypeConstraints.ts === +const enum E { A, B, C } +>E : E +>A : E +>B : E +>C : E + +function foo(x: T) { +>foo : (x: T) => void +>T : T +>x : T +>T : T + + var y: number = x; // Ok +>y : number +>x : T +} + +foo(5); +>foo(5) : void +>foo : (x: T) => void +>5 : number + +foo(E.A); +>foo(E.A) : void +>foo : (x: T) => void +>E.A : E +>E : typeof E +>A : E + +class A { a } +>A : A +>a : any + +class B { b } +>B : B +>b : any + +function bar(x: T) { +>bar : (x: T) => void +>T : T +>A : A +>B : B +>x : T +>T : T + + var y: A | B = x; // Ok +>y : A | B +>A : A +>B : B +>x : T +} + +bar(new A); +>bar(new A) : void +>bar : (x: T) => void +>new A : A +>A : typeof A + +bar(new B); +>bar(new B) : void +>bar : (x: T) => void +>new B : B +>B : typeof B + diff --git a/tests/baselines/reference/constEnumToStringNoComments.js b/tests/baselines/reference/constEnumToStringNoComments.js new file mode 100644 index 0000000000..a23be26033 --- /dev/null +++ b/tests/baselines/reference/constEnumToStringNoComments.js @@ -0,0 +1,37 @@ +//// [constEnumToStringNoComments.ts] +const enum Foo { + X = 100, + Y = 0.5, + Z = 2., + A = -1, + B = -1.5, + C = -1. +} + +let x0 = Foo.X.toString(); +let x1 = Foo["X"].toString(); +let y0 = Foo.Y.toString(); +let y1 = Foo["Y"].toString(); +let z0 = Foo.Z.toString(); +let z1 = Foo["Z"].toString(); +let a0 = Foo.A.toString(); +let a1 = Foo["A"].toString(); +let b0 = Foo.B.toString(); +let b1 = Foo["B"].toString(); +let c0 = Foo.C.toString(); +let c1 = Foo["C"].toString(); + + +//// [constEnumToStringNoComments.js] +var x0 = 100 .toString(); +var x1 = 100 .toString(); +var y0 = 0.5.toString(); +var y1 = 0.5.toString(); +var z0 = 2 .toString(); +var z1 = 2 .toString(); +var a0 = -1 .toString(); +var a1 = -1 .toString(); +var b0 = -1.5.toString(); +var b1 = -1.5.toString(); +var c0 = -1 .toString(); +var c1 = -1 .toString(); diff --git a/tests/baselines/reference/constEnumToStringNoComments.symbols b/tests/baselines/reference/constEnumToStringNoComments.symbols new file mode 100644 index 0000000000..0206e6a5d9 --- /dev/null +++ b/tests/baselines/reference/constEnumToStringNoComments.symbols @@ -0,0 +1,113 @@ +=== tests/cases/compiler/constEnumToStringNoComments.ts === +const enum Foo { +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) + + X = 100, +>X : Symbol(Foo.X, Decl(constEnumToStringNoComments.ts, 0, 16)) + + Y = 0.5, +>Y : Symbol(Foo.Y, Decl(constEnumToStringNoComments.ts, 1, 12)) + + Z = 2., +>Z : Symbol(Foo.Z, Decl(constEnumToStringNoComments.ts, 2, 12)) + + A = -1, +>A : Symbol(Foo.A, Decl(constEnumToStringNoComments.ts, 3, 11)) + + B = -1.5, +>B : Symbol(Foo.B, Decl(constEnumToStringNoComments.ts, 4, 11)) + + C = -1. +>C : Symbol(Foo.C, Decl(constEnumToStringNoComments.ts, 5, 13)) +} + +let x0 = Foo.X.toString(); +>x0 : Symbol(x0, Decl(constEnumToStringNoComments.ts, 9, 3)) +>Foo.X.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.X : Symbol(Foo.X, Decl(constEnumToStringNoComments.ts, 0, 16)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>X : Symbol(Foo.X, Decl(constEnumToStringNoComments.ts, 0, 16)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let x1 = Foo["X"].toString(); +>x1 : Symbol(x1, Decl(constEnumToStringNoComments.ts, 10, 3)) +>Foo["X"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>"X" : Symbol(Foo.X, Decl(constEnumToStringNoComments.ts, 0, 16)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let y0 = Foo.Y.toString(); +>y0 : Symbol(y0, Decl(constEnumToStringNoComments.ts, 11, 3)) +>Foo.Y.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.Y : Symbol(Foo.Y, Decl(constEnumToStringNoComments.ts, 1, 12)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>Y : Symbol(Foo.Y, Decl(constEnumToStringNoComments.ts, 1, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let y1 = Foo["Y"].toString(); +>y1 : Symbol(y1, Decl(constEnumToStringNoComments.ts, 12, 3)) +>Foo["Y"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>"Y" : Symbol(Foo.Y, Decl(constEnumToStringNoComments.ts, 1, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let z0 = Foo.Z.toString(); +>z0 : Symbol(z0, Decl(constEnumToStringNoComments.ts, 13, 3)) +>Foo.Z.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.Z : Symbol(Foo.Z, Decl(constEnumToStringNoComments.ts, 2, 12)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>Z : Symbol(Foo.Z, Decl(constEnumToStringNoComments.ts, 2, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let z1 = Foo["Z"].toString(); +>z1 : Symbol(z1, Decl(constEnumToStringNoComments.ts, 14, 3)) +>Foo["Z"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>"Z" : Symbol(Foo.Z, Decl(constEnumToStringNoComments.ts, 2, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let a0 = Foo.A.toString(); +>a0 : Symbol(a0, Decl(constEnumToStringNoComments.ts, 15, 3)) +>Foo.A.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.A : Symbol(Foo.A, Decl(constEnumToStringNoComments.ts, 3, 11)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>A : Symbol(Foo.A, Decl(constEnumToStringNoComments.ts, 3, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let a1 = Foo["A"].toString(); +>a1 : Symbol(a1, Decl(constEnumToStringNoComments.ts, 16, 3)) +>Foo["A"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>"A" : Symbol(Foo.A, Decl(constEnumToStringNoComments.ts, 3, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let b0 = Foo.B.toString(); +>b0 : Symbol(b0, Decl(constEnumToStringNoComments.ts, 17, 3)) +>Foo.B.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.B : Symbol(Foo.B, Decl(constEnumToStringNoComments.ts, 4, 11)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>B : Symbol(Foo.B, Decl(constEnumToStringNoComments.ts, 4, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let b1 = Foo["B"].toString(); +>b1 : Symbol(b1, Decl(constEnumToStringNoComments.ts, 18, 3)) +>Foo["B"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>"B" : Symbol(Foo.B, Decl(constEnumToStringNoComments.ts, 4, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let c0 = Foo.C.toString(); +>c0 : Symbol(c0, Decl(constEnumToStringNoComments.ts, 19, 3)) +>Foo.C.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.C : Symbol(Foo.C, Decl(constEnumToStringNoComments.ts, 5, 13)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>C : Symbol(Foo.C, Decl(constEnumToStringNoComments.ts, 5, 13)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let c1 = Foo["C"].toString(); +>c1 : Symbol(c1, Decl(constEnumToStringNoComments.ts, 20, 3)) +>Foo["C"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringNoComments.ts, 0, 0)) +>"C" : Symbol(Foo.C, Decl(constEnumToStringNoComments.ts, 5, 13)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + diff --git a/tests/baselines/reference/constEnumToStringNoComments.types b/tests/baselines/reference/constEnumToStringNoComments.types new file mode 100644 index 0000000000..21c4dc6c70 --- /dev/null +++ b/tests/baselines/reference/constEnumToStringNoComments.types @@ -0,0 +1,140 @@ +=== tests/cases/compiler/constEnumToStringNoComments.ts === +const enum Foo { +>Foo : Foo + + X = 100, +>X : Foo +>100 : number + + Y = 0.5, +>Y : Foo +>0.5 : number + + Z = 2., +>Z : Foo +>2. : number + + A = -1, +>A : Foo +>-1 : number +>1 : number + + B = -1.5, +>B : Foo +>-1.5 : number +>1.5 : number + + C = -1. +>C : Foo +>-1. : number +>1. : number +} + +let x0 = Foo.X.toString(); +>x0 : string +>Foo.X.toString() : string +>Foo.X.toString : (radix?: number) => string +>Foo.X : Foo +>Foo : typeof Foo +>X : Foo +>toString : (radix?: number) => string + +let x1 = Foo["X"].toString(); +>x1 : string +>Foo["X"].toString() : string +>Foo["X"].toString : (radix?: number) => string +>Foo["X"] : Foo +>Foo : typeof Foo +>"X" : string +>toString : (radix?: number) => string + +let y0 = Foo.Y.toString(); +>y0 : string +>Foo.Y.toString() : string +>Foo.Y.toString : (radix?: number) => string +>Foo.Y : Foo +>Foo : typeof Foo +>Y : Foo +>toString : (radix?: number) => string + +let y1 = Foo["Y"].toString(); +>y1 : string +>Foo["Y"].toString() : string +>Foo["Y"].toString : (radix?: number) => string +>Foo["Y"] : Foo +>Foo : typeof Foo +>"Y" : string +>toString : (radix?: number) => string + +let z0 = Foo.Z.toString(); +>z0 : string +>Foo.Z.toString() : string +>Foo.Z.toString : (radix?: number) => string +>Foo.Z : Foo +>Foo : typeof Foo +>Z : Foo +>toString : (radix?: number) => string + +let z1 = Foo["Z"].toString(); +>z1 : string +>Foo["Z"].toString() : string +>Foo["Z"].toString : (radix?: number) => string +>Foo["Z"] : Foo +>Foo : typeof Foo +>"Z" : string +>toString : (radix?: number) => string + +let a0 = Foo.A.toString(); +>a0 : string +>Foo.A.toString() : string +>Foo.A.toString : (radix?: number) => string +>Foo.A : Foo +>Foo : typeof Foo +>A : Foo +>toString : (radix?: number) => string + +let a1 = Foo["A"].toString(); +>a1 : string +>Foo["A"].toString() : string +>Foo["A"].toString : (radix?: number) => string +>Foo["A"] : Foo +>Foo : typeof Foo +>"A" : string +>toString : (radix?: number) => string + +let b0 = Foo.B.toString(); +>b0 : string +>Foo.B.toString() : string +>Foo.B.toString : (radix?: number) => string +>Foo.B : Foo +>Foo : typeof Foo +>B : Foo +>toString : (radix?: number) => string + +let b1 = Foo["B"].toString(); +>b1 : string +>Foo["B"].toString() : string +>Foo["B"].toString : (radix?: number) => string +>Foo["B"] : Foo +>Foo : typeof Foo +>"B" : string +>toString : (radix?: number) => string + +let c0 = Foo.C.toString(); +>c0 : string +>Foo.C.toString() : string +>Foo.C.toString : (radix?: number) => string +>Foo.C : Foo +>Foo : typeof Foo +>C : Foo +>toString : (radix?: number) => string + +let c1 = Foo["C"].toString(); +>c1 : string +>Foo["C"].toString() : string +>Foo["C"].toString : (radix?: number) => string +>Foo["C"] : Foo +>Foo : typeof Foo +>"C" : string +>toString : (radix?: number) => string + diff --git a/tests/baselines/reference/constEnumToStringWithComments.js b/tests/baselines/reference/constEnumToStringWithComments.js new file mode 100644 index 0000000000..e70833c9b8 --- /dev/null +++ b/tests/baselines/reference/constEnumToStringWithComments.js @@ -0,0 +1,37 @@ +//// [constEnumToStringWithComments.ts] +const enum Foo { + X = 100, + Y = 0.5, + Z = 2., + A = -1, + B = -1.5, + C = -1. +} + +let x0 = Foo.X.toString(); +let x1 = Foo["X"].toString(); +let y0 = Foo.Y.toString(); +let y1 = Foo["Y"].toString(); +let z0 = Foo.Z.toString(); +let z1 = Foo["Z"].toString(); +let a0 = Foo.A.toString(); +let a1 = Foo["A"].toString(); +let b0 = Foo.B.toString(); +let b1 = Foo["B"].toString(); +let c0 = Foo.C.toString(); +let c1 = Foo["C"].toString(); + + +//// [constEnumToStringWithComments.js] +var x0 = 100 /* X */ .toString(); +var x1 = 100 /* "X" */ .toString(); +var y0 = 0.5 /* Y */.toString(); +var y1 = 0.5 /* "Y" */.toString(); +var z0 = 2 /* Z */ .toString(); +var z1 = 2 /* "Z" */ .toString(); +var a0 = -1 /* A */ .toString(); +var a1 = -1 /* "A" */ .toString(); +var b0 = -1.5 /* B */.toString(); +var b1 = -1.5 /* "B" */.toString(); +var c0 = -1 /* C */ .toString(); +var c1 = -1 /* "C" */ .toString(); diff --git a/tests/baselines/reference/constEnumToStringWithComments.symbols b/tests/baselines/reference/constEnumToStringWithComments.symbols new file mode 100644 index 0000000000..fafb7ab461 --- /dev/null +++ b/tests/baselines/reference/constEnumToStringWithComments.symbols @@ -0,0 +1,113 @@ +=== tests/cases/compiler/constEnumToStringWithComments.ts === +const enum Foo { +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) + + X = 100, +>X : Symbol(Foo.X, Decl(constEnumToStringWithComments.ts, 0, 16)) + + Y = 0.5, +>Y : Symbol(Foo.Y, Decl(constEnumToStringWithComments.ts, 1, 12)) + + Z = 2., +>Z : Symbol(Foo.Z, Decl(constEnumToStringWithComments.ts, 2, 12)) + + A = -1, +>A : Symbol(Foo.A, Decl(constEnumToStringWithComments.ts, 3, 11)) + + B = -1.5, +>B : Symbol(Foo.B, Decl(constEnumToStringWithComments.ts, 4, 11)) + + C = -1. +>C : Symbol(Foo.C, Decl(constEnumToStringWithComments.ts, 5, 13)) +} + +let x0 = Foo.X.toString(); +>x0 : Symbol(x0, Decl(constEnumToStringWithComments.ts, 9, 3)) +>Foo.X.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.X : Symbol(Foo.X, Decl(constEnumToStringWithComments.ts, 0, 16)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>X : Symbol(Foo.X, Decl(constEnumToStringWithComments.ts, 0, 16)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let x1 = Foo["X"].toString(); +>x1 : Symbol(x1, Decl(constEnumToStringWithComments.ts, 10, 3)) +>Foo["X"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>"X" : Symbol(Foo.X, Decl(constEnumToStringWithComments.ts, 0, 16)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let y0 = Foo.Y.toString(); +>y0 : Symbol(y0, Decl(constEnumToStringWithComments.ts, 11, 3)) +>Foo.Y.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.Y : Symbol(Foo.Y, Decl(constEnumToStringWithComments.ts, 1, 12)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>Y : Symbol(Foo.Y, Decl(constEnumToStringWithComments.ts, 1, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let y1 = Foo["Y"].toString(); +>y1 : Symbol(y1, Decl(constEnumToStringWithComments.ts, 12, 3)) +>Foo["Y"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>"Y" : Symbol(Foo.Y, Decl(constEnumToStringWithComments.ts, 1, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let z0 = Foo.Z.toString(); +>z0 : Symbol(z0, Decl(constEnumToStringWithComments.ts, 13, 3)) +>Foo.Z.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.Z : Symbol(Foo.Z, Decl(constEnumToStringWithComments.ts, 2, 12)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>Z : Symbol(Foo.Z, Decl(constEnumToStringWithComments.ts, 2, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let z1 = Foo["Z"].toString(); +>z1 : Symbol(z1, Decl(constEnumToStringWithComments.ts, 14, 3)) +>Foo["Z"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>"Z" : Symbol(Foo.Z, Decl(constEnumToStringWithComments.ts, 2, 12)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let a0 = Foo.A.toString(); +>a0 : Symbol(a0, Decl(constEnumToStringWithComments.ts, 15, 3)) +>Foo.A.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.A : Symbol(Foo.A, Decl(constEnumToStringWithComments.ts, 3, 11)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>A : Symbol(Foo.A, Decl(constEnumToStringWithComments.ts, 3, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let a1 = Foo["A"].toString(); +>a1 : Symbol(a1, Decl(constEnumToStringWithComments.ts, 16, 3)) +>Foo["A"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>"A" : Symbol(Foo.A, Decl(constEnumToStringWithComments.ts, 3, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let b0 = Foo.B.toString(); +>b0 : Symbol(b0, Decl(constEnumToStringWithComments.ts, 17, 3)) +>Foo.B.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.B : Symbol(Foo.B, Decl(constEnumToStringWithComments.ts, 4, 11)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>B : Symbol(Foo.B, Decl(constEnumToStringWithComments.ts, 4, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let b1 = Foo["B"].toString(); +>b1 : Symbol(b1, Decl(constEnumToStringWithComments.ts, 18, 3)) +>Foo["B"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>"B" : Symbol(Foo.B, Decl(constEnumToStringWithComments.ts, 4, 11)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let c0 = Foo.C.toString(); +>c0 : Symbol(c0, Decl(constEnumToStringWithComments.ts, 19, 3)) +>Foo.C.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo.C : Symbol(Foo.C, Decl(constEnumToStringWithComments.ts, 5, 13)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>C : Symbol(Foo.C, Decl(constEnumToStringWithComments.ts, 5, 13)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + +let c1 = Foo["C"].toString(); +>c1 : Symbol(c1, Decl(constEnumToStringWithComments.ts, 20, 3)) +>Foo["C"].toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) +>Foo : Symbol(Foo, Decl(constEnumToStringWithComments.ts, 0, 0)) +>"C" : Symbol(Foo.C, Decl(constEnumToStringWithComments.ts, 5, 13)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) + diff --git a/tests/baselines/reference/constEnumToStringWithComments.types b/tests/baselines/reference/constEnumToStringWithComments.types new file mode 100644 index 0000000000..72d7d367f5 --- /dev/null +++ b/tests/baselines/reference/constEnumToStringWithComments.types @@ -0,0 +1,140 @@ +=== tests/cases/compiler/constEnumToStringWithComments.ts === +const enum Foo { +>Foo : Foo + + X = 100, +>X : Foo +>100 : number + + Y = 0.5, +>Y : Foo +>0.5 : number + + Z = 2., +>Z : Foo +>2. : number + + A = -1, +>A : Foo +>-1 : number +>1 : number + + B = -1.5, +>B : Foo +>-1.5 : number +>1.5 : number + + C = -1. +>C : Foo +>-1. : number +>1. : number +} + +let x0 = Foo.X.toString(); +>x0 : string +>Foo.X.toString() : string +>Foo.X.toString : (radix?: number) => string +>Foo.X : Foo +>Foo : typeof Foo +>X : Foo +>toString : (radix?: number) => string + +let x1 = Foo["X"].toString(); +>x1 : string +>Foo["X"].toString() : string +>Foo["X"].toString : (radix?: number) => string +>Foo["X"] : Foo +>Foo : typeof Foo +>"X" : string +>toString : (radix?: number) => string + +let y0 = Foo.Y.toString(); +>y0 : string +>Foo.Y.toString() : string +>Foo.Y.toString : (radix?: number) => string +>Foo.Y : Foo +>Foo : typeof Foo +>Y : Foo +>toString : (radix?: number) => string + +let y1 = Foo["Y"].toString(); +>y1 : string +>Foo["Y"].toString() : string +>Foo["Y"].toString : (radix?: number) => string +>Foo["Y"] : Foo +>Foo : typeof Foo +>"Y" : string +>toString : (radix?: number) => string + +let z0 = Foo.Z.toString(); +>z0 : string +>Foo.Z.toString() : string +>Foo.Z.toString : (radix?: number) => string +>Foo.Z : Foo +>Foo : typeof Foo +>Z : Foo +>toString : (radix?: number) => string + +let z1 = Foo["Z"].toString(); +>z1 : string +>Foo["Z"].toString() : string +>Foo["Z"].toString : (radix?: number) => string +>Foo["Z"] : Foo +>Foo : typeof Foo +>"Z" : string +>toString : (radix?: number) => string + +let a0 = Foo.A.toString(); +>a0 : string +>Foo.A.toString() : string +>Foo.A.toString : (radix?: number) => string +>Foo.A : Foo +>Foo : typeof Foo +>A : Foo +>toString : (radix?: number) => string + +let a1 = Foo["A"].toString(); +>a1 : string +>Foo["A"].toString() : string +>Foo["A"].toString : (radix?: number) => string +>Foo["A"] : Foo +>Foo : typeof Foo +>"A" : string +>toString : (radix?: number) => string + +let b0 = Foo.B.toString(); +>b0 : string +>Foo.B.toString() : string +>Foo.B.toString : (radix?: number) => string +>Foo.B : Foo +>Foo : typeof Foo +>B : Foo +>toString : (radix?: number) => string + +let b1 = Foo["B"].toString(); +>b1 : string +>Foo["B"].toString() : string +>Foo["B"].toString : (radix?: number) => string +>Foo["B"] : Foo +>Foo : typeof Foo +>"B" : string +>toString : (radix?: number) => string + +let c0 = Foo.C.toString(); +>c0 : string +>Foo.C.toString() : string +>Foo.C.toString : (radix?: number) => string +>Foo.C : Foo +>Foo : typeof Foo +>C : Foo +>toString : (radix?: number) => string + +let c1 = Foo["C"].toString(); +>c1 : string +>Foo["C"].toString() : string +>Foo["C"].toString : (radix?: number) => string +>Foo["C"] : Foo +>Foo : typeof Foo +>"C" : string +>toString : (radix?: number) => string + diff --git a/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt b/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt index 03ce995293..871368da9f 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt +++ b/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt @@ -14,7 +14,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstrain tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts(34,16): error TS2345: Argument of type 'F2' is not assignable to parameter of type '(x: string) => string'. tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts(36,38): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts(37,10): error TS2345: Argument of type 'T' is not assignable to parameter of type '(x: string) => string'. - Type 'void' is not assignable to type 'string'. + Type '() => void' is not assignable to type '(x: string) => string'. tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts(38,10): error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'. @@ -85,7 +85,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstrain foo2(x); ~ !!! error TS2345: Argument of type 'T' is not assignable to parameter of type '(x: string) => string'. -!!! error TS2345: Type 'void' is not assignable to type 'string'. +!!! error TS2345: Type '() => void' is not assignable to type '(x: string) => string'. foo2(y); ~ !!! error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'. diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt b/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt index f9f230b577..c264058ad9 100644 --- a/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt +++ b/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt @@ -5,7 +5,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(25,23): error TS2345: Argument of type '(a: T) => T' is not assignable to parameter of type '(x: Date) => Date'. Types of parameters 'a' and 'x' are incompatible. Type 'T' is not assignable to type 'Date'. - Property 'toDateString' is missing in type 'RegExp'. + Type 'RegExp' is not assignable to type 'Date'. + Property 'toDateString' is missing in type 'RegExp'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(37,36): error TS2345: Argument of type '(x: E) => F' is not assignable to parameter of type '(x: E) => E'. Type 'F' is not assignable to type 'E'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(50,21): error TS2345: Argument of type 'Date' is not assignable to parameter of type 'T'. @@ -13,6 +14,7 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(60,23): error TS2345: Argument of type '(a: T) => T' is not assignable to parameter of type '(x: Date) => Date'. Types of parameters 'a' and 'x' are incompatible. Type 'T' is not assignable to type 'Date'. + Type 'RegExp' is not assignable to type 'Date'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(67,51): error TS2304: Cannot find name 'U'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(67,57): error TS2304: Cannot find name 'U'. @@ -54,7 +56,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen !!! error TS2345: Argument of type '(a: T) => T' is not assignable to parameter of type '(x: Date) => Date'. !!! error TS2345: Types of parameters 'a' and 'x' are incompatible. !!! error TS2345: Type 'T' is not assignable to type 'Date'. -!!! error TS2345: Property 'toDateString' is missing in type 'RegExp'. +!!! error TS2345: Type 'RegExp' is not assignable to type 'Date'. +!!! error TS2345: Property 'toDateString' is missing in type 'RegExp'. var r7b = foo2((a) => a, (b) => b); // valid, T is inferred to be Date } @@ -101,6 +104,7 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen !!! error TS2345: Argument of type '(a: T) => T' is not assignable to parameter of type '(x: Date) => Date'. !!! error TS2345: Types of parameters 'a' and 'x' are incompatible. !!! error TS2345: Type 'T' is not assignable to type 'Date'. +!!! error TS2345: Type 'RegExp' is not assignable to type 'Date'. var r7b = foo2((a) => a, (b) => b); } diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.errors.txt b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.errors.txt index 2a7bfd696c..b0c0bee94f 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndIndexersErrors.ts(15,17): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndIndexersErrors.ts(18,9): error TS2413: Numeric index type 'T' is not assignable to string index type 'Object'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndIndexersErrors.ts(23,9): error TS2322: Type 'T' is not assignable to type 'U'. -==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndIndexersErrors.ts (3 errors) ==== +==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndIndexersErrors.ts (2 errors) ==== // Type inference infers from indexers in target type, error cases function foo(x: T) { @@ -24,8 +23,6 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObj var b: { [x: string]: Object; [x: number]: T; - ~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'T' is not assignable to string index type 'Object'. }; var r2 = foo(b); var d = r2[1]; diff --git a/tests/baselines/reference/genericTypeAssertions6.errors.txt b/tests/baselines/reference/genericTypeAssertions6.errors.txt index 93677b9ab8..29ca99ecb1 100644 --- a/tests/baselines/reference/genericTypeAssertions6.errors.txt +++ b/tests/baselines/reference/genericTypeAssertions6.errors.txt @@ -1,6 +1,7 @@ tests/cases/compiler/genericTypeAssertions6.ts(8,13): error TS2352: Neither type 'U' nor type 'T' is assignable to the other. tests/cases/compiler/genericTypeAssertions6.ts(9,13): error TS2352: Neither type 'T' nor type 'U' is assignable to the other. tests/cases/compiler/genericTypeAssertions6.ts(19,17): error TS2352: Neither type 'U' nor type 'T' is assignable to the other. + Type 'Date' is not assignable to type 'T'. ==== tests/cases/compiler/genericTypeAssertions6.ts (3 errors) ==== @@ -29,6 +30,7 @@ tests/cases/compiler/genericTypeAssertions6.ts(19,17): error TS2352: Neither typ var e = new Date(); ~~~~~~~~~~~~~~~~ !!! error TS2352: Neither type 'U' nor type 'T' is assignable to the other. +!!! error TS2352: Type 'Date' is not assignable to type 'T'. } } diff --git a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt index ae93d059f9..0fe15afcf3 100644 --- a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt +++ b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt @@ -3,8 +3,9 @@ tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(4,7): error TS2420 Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. Types of parameters 'a' and 'a' are incompatible. Type 'T' is not assignable to type '{ a: number; }'. - Types of property 'a' are incompatible. - Type 'string' is not assignable to type 'number'. + Type '{ a: string; }' is not assignable to type '{ a: number; }'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322: Type 'X<{ a: string; }>' is not assignable to type 'I'. Types of property 'f' are incompatible. Type '(a: { a: string; }) => void' is not assignable to type '(a: { a: number; }) => void'. @@ -25,8 +26,9 @@ tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322 !!! error TS2420: Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. !!! error TS2420: Types of parameters 'a' and 'a' are incompatible. !!! error TS2420: Type 'T' is not assignable to type '{ a: number; }'. -!!! error TS2420: Types of property 'a' are incompatible. -!!! error TS2420: Type 'string' is not assignable to type 'number'. +!!! error TS2420: Type '{ a: string; }' is not assignable to type '{ a: number; }'. +!!! error TS2420: Types of property 'a' are incompatible. +!!! error TS2420: Type 'string' is not assignable to type 'number'. f(a: T): void { } } var x = new X<{ a: string }>(); diff --git a/tests/baselines/reference/instanceOfAssignability.js b/tests/baselines/reference/instanceOfAssignability.js new file mode 100644 index 0000000000..4a1e8b9e9d --- /dev/null +++ b/tests/baselines/reference/instanceOfAssignability.js @@ -0,0 +1,187 @@ +//// [instanceOfAssignability.ts] +interface Base { + foo: string|number; + optional?: number; +} + +// Derived1 is assignable to, but not a subtype of, Base +class Derived1 implements Base { + foo: string; +} +// Derived2 is a subtype of Base that is not assignable to Derived1 +class Derived2 implements Base { + foo: number; + optional: number; +} + +class Animal { + move; +} +class Mammal extends Animal { milk; } +class Giraffe extends Mammal { neck; } + +function fn1(x: Array|Array|boolean) { + if(x instanceof Array) { + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; + } +} + +function fn2(x: Base) { + if(x instanceof Derived1) { + // 1.5: y: Base + // Want: y: Derived1 + let y = x; + } +} + +function fn3(x: Base|Derived1) { + if(x instanceof Derived2) { + // 1.5: y: Derived2 + // Want: Derived2 + let y = x; + } +} + +function fn4(x: Base|Derived2) { + if(x instanceof Derived1) { + // 1.5: y: {} + // Want: Derived1 + let y = x; + } +} + +function fn5(x: Derived1) { + if(x instanceof Derived2) { + // 1.5: y: Derived1 + // Want: ??? + let y = x; + } +} + +function fn6(x: Animal|Mammal) { + if(x instanceof Giraffe) { + // 1.5: y: Derived1 + // Want: ??? + let y = x; + } +} + +function fn7(x: Array|Array) { + if(x instanceof Array) { + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; + } +} + +interface Alpha { a } +interface Beta { b } +interface Gamma { c } +class ABC { a; b; c; } +function fn8(x: Alpha|Beta|Gamma) { + if(x instanceof ABC) { + let y = x; + } +} + + + + +//// [instanceOfAssignability.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +// Derived1 is assignable to, but not a subtype of, Base +var Derived1 = (function () { + function Derived1() { + } + return Derived1; +})(); +// Derived2 is a subtype of Base that is not assignable to Derived1 +var Derived2 = (function () { + function Derived2() { + } + return Derived2; +})(); +var Animal = (function () { + function Animal() { + } + return Animal; +})(); +var Mammal = (function (_super) { + __extends(Mammal, _super); + function Mammal() { + _super.apply(this, arguments); + } + return Mammal; +})(Animal); +var Giraffe = (function (_super) { + __extends(Giraffe, _super); + function Giraffe() { + _super.apply(this, arguments); + } + return Giraffe; +})(Mammal); +function fn1(x) { + if (x instanceof Array) { + // 1.5: y: Array|Array + // Want: y: Array|Array + var y = x; + } +} +function fn2(x) { + if (x instanceof Derived1) { + // 1.5: y: Base + // Want: y: Derived1 + var y = x; + } +} +function fn3(x) { + if (x instanceof Derived2) { + // 1.5: y: Derived2 + // Want: Derived2 + var y = x; + } +} +function fn4(x) { + if (x instanceof Derived1) { + // 1.5: y: {} + // Want: Derived1 + var y = x; + } +} +function fn5(x) { + if (x instanceof Derived2) { + // 1.5: y: Derived1 + // Want: ??? + var y = x; + } +} +function fn6(x) { + if (x instanceof Giraffe) { + // 1.5: y: Derived1 + // Want: ??? + var y = x; + } +} +function fn7(x) { + if (x instanceof Array) { + // 1.5: y: Array|Array + // Want: y: Array|Array + var y = x; + } +} +var ABC = (function () { + function ABC() { + } + return ABC; +})(); +function fn8(x) { + if (x instanceof ABC) { + var y = x; + } +} diff --git a/tests/baselines/reference/instanceOfAssignability.symbols b/tests/baselines/reference/instanceOfAssignability.symbols new file mode 100644 index 0000000000..b01f29a5fa --- /dev/null +++ b/tests/baselines/reference/instanceOfAssignability.symbols @@ -0,0 +1,208 @@ +=== tests/cases/compiler/instanceOfAssignability.ts === +interface Base { +>Base : Symbol(Base, Decl(instanceOfAssignability.ts, 0, 0)) + + foo: string|number; +>foo : Symbol(foo, Decl(instanceOfAssignability.ts, 0, 16)) + + optional?: number; +>optional : Symbol(optional, Decl(instanceOfAssignability.ts, 1, 20)) +} + +// Derived1 is assignable to, but not a subtype of, Base +class Derived1 implements Base { +>Derived1 : Symbol(Derived1, Decl(instanceOfAssignability.ts, 3, 1)) +>Base : Symbol(Base, Decl(instanceOfAssignability.ts, 0, 0)) + + foo: string; +>foo : Symbol(foo, Decl(instanceOfAssignability.ts, 6, 32)) +} +// Derived2 is a subtype of Base that is not assignable to Derived1 +class Derived2 implements Base { +>Derived2 : Symbol(Derived2, Decl(instanceOfAssignability.ts, 8, 1)) +>Base : Symbol(Base, Decl(instanceOfAssignability.ts, 0, 0)) + + foo: number; +>foo : Symbol(foo, Decl(instanceOfAssignability.ts, 10, 32)) + + optional: number; +>optional : Symbol(optional, Decl(instanceOfAssignability.ts, 11, 13)) +} + +class Animal { +>Animal : Symbol(Animal, Decl(instanceOfAssignability.ts, 13, 1)) + + move; +>move : Symbol(move, Decl(instanceOfAssignability.ts, 15, 14)) +} +class Mammal extends Animal { milk; } +>Mammal : Symbol(Mammal, Decl(instanceOfAssignability.ts, 17, 1)) +>Animal : Symbol(Animal, Decl(instanceOfAssignability.ts, 13, 1)) +>milk : Symbol(milk, Decl(instanceOfAssignability.ts, 18, 29)) + +class Giraffe extends Mammal { neck; } +>Giraffe : Symbol(Giraffe, Decl(instanceOfAssignability.ts, 18, 37)) +>Mammal : Symbol(Mammal, Decl(instanceOfAssignability.ts, 17, 1)) +>neck : Symbol(neck, Decl(instanceOfAssignability.ts, 19, 30)) + +function fn1(x: Array|Array|boolean) { +>fn1 : Symbol(fn1, Decl(instanceOfAssignability.ts, 19, 38)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 21, 13)) +>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) +>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) + + if(x instanceof Array) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 21, 13)) +>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) + + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 25, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 21, 13)) + } +} + +function fn2(x: Base) { +>fn2 : Symbol(fn2, Decl(instanceOfAssignability.ts, 27, 1)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 29, 13)) +>Base : Symbol(Base, Decl(instanceOfAssignability.ts, 0, 0)) + + if(x instanceof Derived1) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 29, 13)) +>Derived1 : Symbol(Derived1, Decl(instanceOfAssignability.ts, 3, 1)) + + // 1.5: y: Base + // Want: y: Derived1 + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 33, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 29, 13)) + } +} + +function fn3(x: Base|Derived1) { +>fn3 : Symbol(fn3, Decl(instanceOfAssignability.ts, 35, 1)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 37, 13)) +>Base : Symbol(Base, Decl(instanceOfAssignability.ts, 0, 0)) +>Derived1 : Symbol(Derived1, Decl(instanceOfAssignability.ts, 3, 1)) + + if(x instanceof Derived2) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 37, 13)) +>Derived2 : Symbol(Derived2, Decl(instanceOfAssignability.ts, 8, 1)) + + // 1.5: y: Derived2 + // Want: Derived2 + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 41, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 37, 13)) + } +} + +function fn4(x: Base|Derived2) { +>fn4 : Symbol(fn4, Decl(instanceOfAssignability.ts, 43, 1)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 45, 13)) +>Base : Symbol(Base, Decl(instanceOfAssignability.ts, 0, 0)) +>Derived2 : Symbol(Derived2, Decl(instanceOfAssignability.ts, 8, 1)) + + if(x instanceof Derived1) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 45, 13)) +>Derived1 : Symbol(Derived1, Decl(instanceOfAssignability.ts, 3, 1)) + + // 1.5: y: {} + // Want: Derived1 + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 49, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 45, 13)) + } +} + +function fn5(x: Derived1) { +>fn5 : Symbol(fn5, Decl(instanceOfAssignability.ts, 51, 1)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 53, 13)) +>Derived1 : Symbol(Derived1, Decl(instanceOfAssignability.ts, 3, 1)) + + if(x instanceof Derived2) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 53, 13)) +>Derived2 : Symbol(Derived2, Decl(instanceOfAssignability.ts, 8, 1)) + + // 1.5: y: Derived1 + // Want: ??? + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 57, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 53, 13)) + } +} + +function fn6(x: Animal|Mammal) { +>fn6 : Symbol(fn6, Decl(instanceOfAssignability.ts, 59, 1)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 61, 13)) +>Animal : Symbol(Animal, Decl(instanceOfAssignability.ts, 13, 1)) +>Mammal : Symbol(Mammal, Decl(instanceOfAssignability.ts, 17, 1)) + + if(x instanceof Giraffe) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 61, 13)) +>Giraffe : Symbol(Giraffe, Decl(instanceOfAssignability.ts, 18, 37)) + + // 1.5: y: Derived1 + // Want: ??? + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 65, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 61, 13)) + } +} + +function fn7(x: Array|Array) { +>fn7 : Symbol(fn7, Decl(instanceOfAssignability.ts, 67, 1)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 69, 13)) +>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) +>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) + + if(x instanceof Array) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 69, 13)) +>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11)) + + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 73, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 69, 13)) + } +} + +interface Alpha { a } +>Alpha : Symbol(Alpha, Decl(instanceOfAssignability.ts, 75, 1)) +>a : Symbol(a, Decl(instanceOfAssignability.ts, 77, 17)) + +interface Beta { b } +>Beta : Symbol(Beta, Decl(instanceOfAssignability.ts, 77, 21)) +>b : Symbol(b, Decl(instanceOfAssignability.ts, 78, 16)) + +interface Gamma { c } +>Gamma : Symbol(Gamma, Decl(instanceOfAssignability.ts, 78, 20)) +>c : Symbol(c, Decl(instanceOfAssignability.ts, 79, 17)) + +class ABC { a; b; c; } +>ABC : Symbol(ABC, Decl(instanceOfAssignability.ts, 79, 21)) +>a : Symbol(a, Decl(instanceOfAssignability.ts, 80, 11)) +>b : Symbol(b, Decl(instanceOfAssignability.ts, 80, 14)) +>c : Symbol(c, Decl(instanceOfAssignability.ts, 80, 17)) + +function fn8(x: Alpha|Beta|Gamma) { +>fn8 : Symbol(fn8, Decl(instanceOfAssignability.ts, 80, 22)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 81, 13)) +>Alpha : Symbol(Alpha, Decl(instanceOfAssignability.ts, 75, 1)) +>Beta : Symbol(Beta, Decl(instanceOfAssignability.ts, 77, 21)) +>Gamma : Symbol(Gamma, Decl(instanceOfAssignability.ts, 78, 20)) + + if(x instanceof ABC) { +>x : Symbol(x, Decl(instanceOfAssignability.ts, 81, 13)) +>ABC : Symbol(ABC, Decl(instanceOfAssignability.ts, 79, 21)) + + let y = x; +>y : Symbol(y, Decl(instanceOfAssignability.ts, 83, 5)) +>x : Symbol(x, Decl(instanceOfAssignability.ts, 81, 13)) + } +} + + + diff --git a/tests/baselines/reference/instanceOfAssignability.types b/tests/baselines/reference/instanceOfAssignability.types new file mode 100644 index 0000000000..12b2d32606 --- /dev/null +++ b/tests/baselines/reference/instanceOfAssignability.types @@ -0,0 +1,216 @@ +=== tests/cases/compiler/instanceOfAssignability.ts === +interface Base { +>Base : Base + + foo: string|number; +>foo : string | number + + optional?: number; +>optional : number +} + +// Derived1 is assignable to, but not a subtype of, Base +class Derived1 implements Base { +>Derived1 : Derived1 +>Base : Base + + foo: string; +>foo : string +} +// Derived2 is a subtype of Base that is not assignable to Derived1 +class Derived2 implements Base { +>Derived2 : Derived2 +>Base : Base + + foo: number; +>foo : number + + optional: number; +>optional : number +} + +class Animal { +>Animal : Animal + + move; +>move : any +} +class Mammal extends Animal { milk; } +>Mammal : Mammal +>Animal : Animal +>milk : any + +class Giraffe extends Mammal { neck; } +>Giraffe : Giraffe +>Mammal : Mammal +>neck : any + +function fn1(x: Array|Array|boolean) { +>fn1 : (x: number[] | string[] | boolean) => void +>x : number[] | string[] | boolean +>Array : T[] +>Array : T[] + + if(x instanceof Array) { +>x instanceof Array : boolean +>x : number[] | string[] | boolean +>Array : ArrayConstructor + + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; +>y : number[] | string[] +>x : number[] | string[] + } +} + +function fn2(x: Base) { +>fn2 : (x: Base) => void +>x : Base +>Base : Base + + if(x instanceof Derived1) { +>x instanceof Derived1 : boolean +>x : Base +>Derived1 : typeof Derived1 + + // 1.5: y: Base + // Want: y: Derived1 + let y = x; +>y : Derived1 +>x : Derived1 + } +} + +function fn3(x: Base|Derived1) { +>fn3 : (x: Base | Derived1) => void +>x : Base | Derived1 +>Base : Base +>Derived1 : Derived1 + + if(x instanceof Derived2) { +>x instanceof Derived2 : boolean +>x : Base | Derived1 +>Derived2 : typeof Derived2 + + // 1.5: y: Derived2 + // Want: Derived2 + let y = x; +>y : Derived2 +>x : Derived2 + } +} + +function fn4(x: Base|Derived2) { +>fn4 : (x: Base | Derived2) => void +>x : Base | Derived2 +>Base : Base +>Derived2 : Derived2 + + if(x instanceof Derived1) { +>x instanceof Derived1 : boolean +>x : Base | Derived2 +>Derived1 : typeof Derived1 + + // 1.5: y: {} + // Want: Derived1 + let y = x; +>y : Derived1 +>x : Derived1 + } +} + +function fn5(x: Derived1) { +>fn5 : (x: Derived1) => void +>x : Derived1 +>Derived1 : Derived1 + + if(x instanceof Derived2) { +>x instanceof Derived2 : boolean +>x : Derived1 +>Derived2 : typeof Derived2 + + // 1.5: y: Derived1 + // Want: ??? + let y = x; +>y : Derived1 +>x : Derived1 + } +} + +function fn6(x: Animal|Mammal) { +>fn6 : (x: Animal | Mammal) => void +>x : Animal | Mammal +>Animal : Animal +>Mammal : Mammal + + if(x instanceof Giraffe) { +>x instanceof Giraffe : boolean +>x : Animal | Mammal +>Giraffe : typeof Giraffe + + // 1.5: y: Derived1 + // Want: ??? + let y = x; +>y : Giraffe +>x : Giraffe + } +} + +function fn7(x: Array|Array) { +>fn7 : (x: number[] | string[]) => void +>x : number[] | string[] +>Array : T[] +>Array : T[] + + if(x instanceof Array) { +>x instanceof Array : boolean +>x : number[] | string[] +>Array : ArrayConstructor + + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; +>y : number[] | string[] +>x : number[] | string[] + } +} + +interface Alpha { a } +>Alpha : Alpha +>a : any + +interface Beta { b } +>Beta : Beta +>b : any + +interface Gamma { c } +>Gamma : Gamma +>c : any + +class ABC { a; b; c; } +>ABC : ABC +>a : any +>b : any +>c : any + +function fn8(x: Alpha|Beta|Gamma) { +>fn8 : (x: Alpha | Beta | Gamma) => void +>x : Alpha | Beta | Gamma +>Alpha : Alpha +>Beta : Beta +>Gamma : Gamma + + if(x instanceof ABC) { +>x instanceof ABC : boolean +>x : Alpha | Beta | Gamma +>ABC : typeof ABC + + let y = x; +>y : ABC +>x : ABC + } +} + + + diff --git a/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt b/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt index 95adbbf671..138f3d9209 100644 --- a/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt +++ b/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt @@ -18,11 +18,9 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBa tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts(60,15): error TS2430: Interface 'Derived5' incorrectly extends interface 'Base1'. Types of property 'x' are incompatible. Type 'T' is not assignable to type '{ a: T; }'. - Property 'a' is missing in type '{}'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts(60,15): error TS2430: Interface 'Derived5' incorrectly extends interface 'Base2'. Types of property 'x' are incompatible. Type 'T' is not assignable to type '{ b: T; }'. - Property 'b' is missing in type '{}'. ==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts (6 errors) ==== @@ -111,12 +109,10 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBa !!! error TS2430: Interface 'Derived5' incorrectly extends interface 'Base1'. !!! error TS2430: Types of property 'x' are incompatible. !!! error TS2430: Type 'T' is not assignable to type '{ a: T; }'. -!!! error TS2430: Property 'a' is missing in type '{}'. ~~~~~~~~ !!! error TS2430: Interface 'Derived5' incorrectly extends interface 'Base2'. !!! error TS2430: Types of property 'x' are incompatible. !!! error TS2430: Type 'T' is not assignable to type '{ b: T; }'. -!!! error TS2430: Property 'b' is missing in type '{}'. x: T; } } \ No newline at end of file diff --git a/tests/baselines/reference/objectTypeWithRecursiveWrappedPropertyCheckedNominally.errors.txt b/tests/baselines/reference/objectTypeWithRecursiveWrappedPropertyCheckedNominally.errors.txt index 91a92dbd54..1f2f432c9d 100644 --- a/tests/baselines/reference/objectTypeWithRecursiveWrappedPropertyCheckedNominally.errors.txt +++ b/tests/baselines/reference/objectTypeWithRecursiveWrappedPropertyCheckedNominally.errors.txt @@ -5,9 +5,12 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRec Types of property 'data' are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(30,5): error TS2322: Type 'U' is not assignable to type 'T'. + Type 'MyList' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(31,5): error TS2322: Type 'T' is not assignable to type 'U'. + Type 'List' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(41,15): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(42,5): error TS2322: Type 'U' is not assignable to type 'T'. + Type 'MyList' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(43,5): error TS2322: Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(48,5): error TS2322: Type 'T' is not assignable to type 'List'. tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRecursiveWrappedPropertyCheckedNominally.ts(50,5): error TS2322: Type 'T' is not assignable to type 'MyList'. @@ -54,9 +57,11 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRec t = u; // error ~ !!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: Type 'MyList' is not assignable to type 'T'. u = t; // error ~ !!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'List' is not assignable to type 'U'. var a: List; var b: MyList; @@ -72,6 +77,7 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/objectTypeWithRec t = u; // error ~ !!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: Type 'MyList' is not assignable to type 'T'. u = t; // was error, ok after constraint made illegal, doesn't matter ~ !!! error TS2322: Type 'T' is not assignable to type 'U'. diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt index eeedf58ab7..2bb0db83e6 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt @@ -101,12 +101,14 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(132,7): error TS2415: Class 'D23' incorrectly extends base class 'C3'. Types of property 'foo' are incompatible. Type 'V' is not assignable to type 'T'. + Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(132,11): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(132,24): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(137,7): error TS2415: Class 'D24' incorrectly extends base class 'C3'. Types of property 'foo' are incompatible. Type 'V' is not assignable to type 'U'. + Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(137,11): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(137,24): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. @@ -441,6 +443,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D23' incorrectly extends base class 'C3'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'V' is not assignable to type 'T'. +!!! error TS2415: Type 'Date' is not assignable to type 'T'. ~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~ @@ -456,6 +459,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D24' incorrectly extends base class 'C3'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'V' is not assignable to type 'U'. +!!! error TS2415: Type 'Date' is not assignable to type 'U'. ~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~ diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt index a9b025ccc7..7b3d706606 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt @@ -1,11 +1,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(45,7): error TS2415: Class 'D3' incorrectly extends base class 'B1'. Types of property 'foo' are incompatible. Type 'V' is not assignable to type 'Foo'. - Property 'foo' is missing in type '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(55,7): error TS2415: Class 'D5' incorrectly extends base class 'B1'. Types of property 'foo' are incompatible. Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(60,7): error TS2415: Class 'D6' incorrectly extends base class 'B1'. Types of property 'foo' are incompatible. @@ -14,6 +14,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(65,7): error TS2415: Class 'D7' incorrectly extends base class 'B1'. Types of property 'foo' are incompatible. Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(75,7): error TS2415: Class 'D9' incorrectly extends base class 'B1'. Types of property 'foo' are incompatible. @@ -71,7 +72,6 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D3' incorrectly extends base class 'B1'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'V' is not assignable to type 'Foo'. -!!! error TS2415: Property 'foo' is missing in type '{}'. [x: string]: Foo; foo: V; // error ~~~~~~~ @@ -88,6 +88,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D5' incorrectly extends base class 'B1'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'U' is not assignable to type 'T'. +!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: U; // error ~~~~~~~ @@ -110,6 +111,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D7' incorrectly extends base class 'B1'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'T' is not assignable to type 'U'. +!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: T; // error ~~~~~~~ diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt index 867b622cf1..22b8c3cfb3 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt @@ -7,6 +7,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(66,11): error TS2415: Class 'D2' incorrectly extends base class 'Base'. Types of property 'foo' are incompatible. Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(66,14): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(66,32): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(66,50): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. @@ -14,6 +15,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(71,11): error TS2415: Class 'D3' incorrectly extends base class 'Base'. Types of property 'foo' are incompatible. Type 'V' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(71,14): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(71,32): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(71,50): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. @@ -21,6 +23,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(76,11): error TS2415: Class 'D4' incorrectly extends base class 'Base'. Types of property 'foo' are incompatible. Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(76,14): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(76,32): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(76,50): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. @@ -31,6 +34,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(86,11): error TS2415: Class 'D6' incorrectly extends base class 'Base'. Types of property 'foo' are incompatible. Type 'V' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(86,14): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(86,32): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(86,50): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. @@ -38,6 +42,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(91,11): error TS2415: Class 'D7' incorrectly extends base class 'Base'. Types of property 'foo' are incompatible. Type 'T' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(91,14): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(91,32): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(91,50): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. @@ -45,6 +50,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(96,11): error TS2415: Class 'D8' incorrectly extends base class 'Base'. Types of property 'foo' are incompatible. Type 'U' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(96,14): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(96,32): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(96,50): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. @@ -170,6 +176,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D2' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'U' is not assignable to type 'T'. +!!! error TS2415: Type 'Foo' is not assignable to type 'T'. ~~~~~~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~~~~~~ @@ -187,6 +194,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D3' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'V' is not assignable to type 'T'. +!!! error TS2415: Type 'Foo' is not assignable to type 'T'. ~~~~~~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~~~~~~ @@ -204,6 +212,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D4' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'T' is not assignable to type 'U'. +!!! error TS2415: Type 'Foo' is not assignable to type 'U'. ~~~~~~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~~~~~~ @@ -232,6 +241,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D6' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'V' is not assignable to type 'U'. +!!! error TS2415: Type 'Foo' is not assignable to type 'U'. ~~~~~~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~~~~~~ @@ -249,6 +259,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D7' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'T' is not assignable to type 'V'. +!!! error TS2415: Type 'Foo' is not assignable to type 'V'. ~~~~~~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~~~~~~ @@ -266,6 +277,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf !!! error TS2415: Class 'D8' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'foo' are incompatible. !!! error TS2415: Type 'U' is not assignable to type 'V'. +!!! error TS2415: Type 'Foo' is not assignable to type 'V'. ~~~~~~~~~~~~~~~~ !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/tupleTypeInference.js b/tests/baselines/reference/tupleTypeInference.js new file mode 100644 index 0000000000..dfc0de8302 --- /dev/null +++ b/tests/baselines/reference/tupleTypeInference.js @@ -0,0 +1,31 @@ +//// [tupleTypeInference.ts] +declare var $q: IQService; + +interface IQService { + all(x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; + all(x: [IPromise, IPromise]): IPromise<[T1, T2]>; + all(x: [IPromise]): IPromise<[T1]>; + when(t?: T): IPromise; +} + +interface IPromise { + then(callback: (t: T) => TResult): IPromise; +} + +// Implicit different types +var a = $q.all([$q.when(), $q.when()]); + +// Explicit different types +var b = $q.all([$q.when(), $q.when()]); + +// Implicit identical types +var c = $q.all([$q.when(), $q.when()]); + + +//// [tupleTypeInference.js] +// Implicit different types +var a = $q.all([$q.when(), $q.when()]); +// Explicit different types +var b = $q.all([$q.when(), $q.when()]); +// Implicit identical types +var c = $q.all([$q.when(), $q.when()]); diff --git a/tests/baselines/reference/tupleTypeInference.symbols b/tests/baselines/reference/tupleTypeInference.symbols new file mode 100644 index 0000000000..4dbed73e39 --- /dev/null +++ b/tests/baselines/reference/tupleTypeInference.symbols @@ -0,0 +1,110 @@ +=== tests/cases/compiler/tupleTypeInference.ts === +declare var $q: IQService; +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>IQService : Symbol(IQService, Decl(tupleTypeInference.ts, 0, 26)) + +interface IQService { +>IQService : Symbol(IQService, Decl(tupleTypeInference.ts, 0, 26)) + + all(x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; +>all : Symbol(all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 3, 8)) +>T2 : Symbol(T2, Decl(tupleTypeInference.ts, 3, 11)) +>T3 : Symbol(T3, Decl(tupleTypeInference.ts, 3, 15)) +>x : Symbol(x, Decl(tupleTypeInference.ts, 3, 20)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 3, 8)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T2 : Symbol(T2, Decl(tupleTypeInference.ts, 3, 11)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T3 : Symbol(T3, Decl(tupleTypeInference.ts, 3, 15)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 3, 8)) +>T2 : Symbol(T2, Decl(tupleTypeInference.ts, 3, 11)) +>T3 : Symbol(T3, Decl(tupleTypeInference.ts, 3, 15)) + + all(x: [IPromise, IPromise]): IPromise<[T1, T2]>; +>all : Symbol(all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 4, 8)) +>T2 : Symbol(T2, Decl(tupleTypeInference.ts, 4, 11)) +>x : Symbol(x, Decl(tupleTypeInference.ts, 4, 16)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 4, 8)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T2 : Symbol(T2, Decl(tupleTypeInference.ts, 4, 11)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 4, 8)) +>T2 : Symbol(T2, Decl(tupleTypeInference.ts, 4, 11)) + + all(x: [IPromise]): IPromise<[T1]>; +>all : Symbol(all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 5, 8)) +>x : Symbol(x, Decl(tupleTypeInference.ts, 5, 12)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 5, 8)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T1 : Symbol(T1, Decl(tupleTypeInference.ts, 5, 8)) + + when(t?: T): IPromise; +>when : Symbol(when, Decl(tupleTypeInference.ts, 5, 47)) +>T : Symbol(T, Decl(tupleTypeInference.ts, 6, 9)) +>t : Symbol(t, Decl(tupleTypeInference.ts, 6, 12)) +>T : Symbol(T, Decl(tupleTypeInference.ts, 6, 9)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T : Symbol(T, Decl(tupleTypeInference.ts, 6, 9)) +} + +interface IPromise { +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>T : Symbol(T, Decl(tupleTypeInference.ts, 9, 19)) + + then(callback: (t: T) => TResult): IPromise; +>then : Symbol(then, Decl(tupleTypeInference.ts, 9, 23)) +>TResult : Symbol(TResult, Decl(tupleTypeInference.ts, 10, 9)) +>callback : Symbol(callback, Decl(tupleTypeInference.ts, 10, 18)) +>t : Symbol(t, Decl(tupleTypeInference.ts, 10, 29)) +>T : Symbol(T, Decl(tupleTypeInference.ts, 9, 19)) +>TResult : Symbol(TResult, Decl(tupleTypeInference.ts, 10, 9)) +>IPromise : Symbol(IPromise, Decl(tupleTypeInference.ts, 7, 1)) +>TResult : Symbol(TResult, Decl(tupleTypeInference.ts, 10, 9)) +} + +// Implicit different types +var a = $q.all([$q.when(), $q.when()]); +>a : Symbol(a, Decl(tupleTypeInference.ts, 14, 3)) +>$q.all : Symbol(IQService.all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>all : Symbol(IQService.all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>$q.when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q.when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) + +// Explicit different types +var b = $q.all([$q.when(), $q.when()]); +>b : Symbol(b, Decl(tupleTypeInference.ts, 17, 3)) +>$q.all : Symbol(IQService.all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>all : Symbol(IQService.all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>$q.when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q.when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) + +// Implicit identical types +var c = $q.all([$q.when(), $q.when()]); +>c : Symbol(c, Decl(tupleTypeInference.ts, 20, 3)) +>$q.all : Symbol(IQService.all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>all : Symbol(IQService.all, Decl(tupleTypeInference.ts, 2, 21), Decl(tupleTypeInference.ts, 3, 91), Decl(tupleTypeInference.ts, 4, 69)) +>$q.when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q.when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) +>$q : Symbol($q, Decl(tupleTypeInference.ts, 0, 11)) +>when : Symbol(IQService.when, Decl(tupleTypeInference.ts, 5, 47)) + diff --git a/tests/baselines/reference/tupleTypeInference.types b/tests/baselines/reference/tupleTypeInference.types new file mode 100644 index 0000000000..999574a78e --- /dev/null +++ b/tests/baselines/reference/tupleTypeInference.types @@ -0,0 +1,122 @@ +=== tests/cases/compiler/tupleTypeInference.ts === +declare var $q: IQService; +>$q : IQService +>IQService : IQService + +interface IQService { +>IQService : IQService + + all(x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; +>all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>T1 : T1 +>T2 : T2 +>T3 : T3 +>x : [IPromise, IPromise, IPromise] +>IPromise : IPromise +>T1 : T1 +>IPromise : IPromise +>T2 : T2 +>IPromise : IPromise +>T3 : T3 +>IPromise : IPromise +>T1 : T1 +>T2 : T2 +>T3 : T3 + + all(x: [IPromise, IPromise]): IPromise<[T1, T2]>; +>all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>T1 : T1 +>T2 : T2 +>x : [IPromise, IPromise] +>IPromise : IPromise +>T1 : T1 +>IPromise : IPromise +>T2 : T2 +>IPromise : IPromise +>T1 : T1 +>T2 : T2 + + all(x: [IPromise]): IPromise<[T1]>; +>all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>T1 : T1 +>x : [IPromise] +>IPromise : IPromise +>T1 : T1 +>IPromise : IPromise +>T1 : T1 + + when(t?: T): IPromise; +>when : (t?: T) => IPromise +>T : T +>t : T +>T : T +>IPromise : IPromise +>T : T +} + +interface IPromise { +>IPromise : IPromise +>T : T + + then(callback: (t: T) => TResult): IPromise; +>then : (callback: (t: T) => TResult) => IPromise +>TResult : TResult +>callback : (t: T) => TResult +>t : T +>T : T +>TResult : TResult +>IPromise : IPromise +>TResult : TResult +} + +// Implicit different types +var a = $q.all([$q.when(), $q.when()]); +>a : IPromise<[string, number]> +>$q.all([$q.when(), $q.when()]) : IPromise<[string, number]> +>$q.all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>$q : IQService +>all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>[$q.when(), $q.when()] : [IPromise, IPromise] +>$q.when() : IPromise +>$q.when : (t?: T) => IPromise +>$q : IQService +>when : (t?: T) => IPromise +>$q.when() : IPromise +>$q.when : (t?: T) => IPromise +>$q : IQService +>when : (t?: T) => IPromise + +// Explicit different types +var b = $q.all([$q.when(), $q.when()]); +>b : IPromise<[string, number]> +>$q.all([$q.when(), $q.when()]) : IPromise<[string, number]> +>$q.all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>$q : IQService +>all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>[$q.when(), $q.when()] : [IPromise, IPromise] +>$q.when() : IPromise +>$q.when : (t?: T) => IPromise +>$q : IQService +>when : (t?: T) => IPromise +>$q.when() : IPromise +>$q.when : (t?: T) => IPromise +>$q : IQService +>when : (t?: T) => IPromise + +// Implicit identical types +var c = $q.all([$q.when(), $q.when()]); +>c : IPromise<[string, string]> +>$q.all([$q.when(), $q.when()]) : IPromise<[string, string]> +>$q.all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>$q : IQService +>all : { (x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; (x: [IPromise, IPromise]): IPromise<[T1, T2]>; (x: [IPromise]): IPromise<[T1]>; } +>[$q.when(), $q.when()] : [IPromise, IPromise] +>$q.when() : IPromise +>$q.when : (t?: T) => IPromise +>$q : IQService +>when : (t?: T) => IPromise +>$q.when() : IPromise +>$q.when : (t?: T) => IPromise +>$q : IQService +>when : (t?: T) => IPromise + diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt index 2f86b6797d..63b9de2aed 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt +++ b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt @@ -1,18 +1,16 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(12,10): error TS2339: Property 'bar' does not exist on type 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(33,5): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(34,10): error TS2339: Property 'bar' does not exist on type 'B'. -tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(65,10): error TS2339: Property 'bar1' does not exist on type 'C1 | C2'. -tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(66,10): error TS2339: Property 'bar2' does not exist on type 'C1 | C2'. +tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(66,10): error TS2339: Property 'bar2' does not exist on type 'C1'. tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(85,10): error TS2339: Property 'bar' does not exist on type 'D'. -tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(111,10): error TS2339: Property 'bar1' does not exist on type 'E1 | E2'. -tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(112,10): error TS2339: Property 'bar2' does not exist on type 'E1 | E2'. +tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(112,10): error TS2339: Property 'bar2' does not exist on type 'E1'. tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(134,11): error TS2339: Property 'foo' does not exist on type 'F | string'. tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(135,11): error TS2339: Property 'bar' does not exist on type 'F | string'. tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(160,11): error TS2339: Property 'foo2' does not exist on type 'G1'. tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(182,11): error TS2339: Property 'bar' does not exist on type 'H'. -==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts (12 errors) ==== +==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts (10 errors) ==== interface AConstructor { new (): A; } @@ -84,11 +82,9 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstru obj5.foo; obj5.c; obj5.bar1; - ~~~~ -!!! error TS2339: Property 'bar1' does not exist on type 'C1 | C2'. obj5.bar2; ~~~~ -!!! error TS2339: Property 'bar2' does not exist on type 'C1 | C2'. +!!! error TS2339: Property 'bar2' does not exist on type 'C1'. } var obj6: any; @@ -136,11 +132,9 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstru if (obj9 instanceof E) { // narrowed to E1 | E2 obj9.foo; obj9.bar1; - ~~~~ -!!! error TS2339: Property 'bar1' does not exist on type 'E1 | E2'. obj9.bar2; ~~~~ -!!! error TS2339: Property 'bar2' does not exist on type 'E1 | E2'. +!!! error TS2339: Property 'bar2' does not exist on type 'E1'. } var obj10: any; diff --git a/tests/baselines/reference/typeParameterAssignability2.errors.txt b/tests/baselines/reference/typeParameterAssignability2.errors.txt index b3cc924d41..ab8803e047 100644 --- a/tests/baselines/reference/typeParameterAssignability2.errors.txt +++ b/tests/baselines/reference/typeParameterAssignability2.errors.txt @@ -16,9 +16,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(24,28): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(25,5): error TS2322: Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(26,5): error TS2322: Type 'V' is not assignable to type 'T'. + Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(27,5): error TS2322: Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(29,5): error TS2322: Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(30,5): error TS2322: Type 'V' is not assignable to type 'U'. + Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(31,5): error TS2322: Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(33,5): error TS2322: Type 'T' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(34,5): error TS2322: Type 'U' is not assignable to type 'V'. @@ -29,9 +31,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(44,44): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(45,5): error TS2322: Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(46,5): error TS2322: Type 'V' is not assignable to type 'T'. + Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(47,5): error TS2322: Type 'Date' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(49,5): error TS2322: Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(50,5): error TS2322: Type 'V' is not assignable to type 'U'. + Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(51,5): error TS2322: Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(53,5): error TS2322: Type 'T' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability2.ts(54,5): error TS2322: Type 'U' is not assignable to type 'V'. @@ -110,6 +114,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara t = v; // error ~ !!! error TS2322: Type 'V' is not assignable to type 'T'. +!!! error TS2322: Type 'Date' is not assignable to type 'T'. t = new Date(); // error ~ !!! error TS2322: Type 'Date' is not assignable to type 'T'. @@ -120,6 +125,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara u = v; // error ~ !!! error TS2322: Type 'V' is not assignable to type 'U'. +!!! error TS2322: Type 'Date' is not assignable to type 'U'. u = new Date(); // error ~ !!! error TS2322: Type 'Date' is not assignable to type 'U'. @@ -156,6 +162,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara t = v; // error ~ !!! error TS2322: Type 'V' is not assignable to type 'T'. +!!! error TS2322: Type 'Date' is not assignable to type 'T'. t = new Date(); // error ~ !!! error TS2322: Type 'Date' is not assignable to type 'T'. @@ -166,6 +173,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara u = v; // error ~ !!! error TS2322: Type 'V' is not assignable to type 'U'. +!!! error TS2322: Type 'Date' is not assignable to type 'U'. u = new Date(); // error ~ !!! error TS2322: Type 'Date' is not assignable to type 'U'. diff --git a/tests/baselines/reference/typeParameterAssignability3.errors.txt b/tests/baselines/reference/typeParameterAssignability3.errors.txt index 7dbb24ef64..ca7850d747 100644 --- a/tests/baselines/reference/typeParameterAssignability3.errors.txt +++ b/tests/baselines/reference/typeParameterAssignability3.errors.txt @@ -1,7 +1,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability3.ts(14,5): error TS2322: Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability3.ts(15,5): error TS2322: Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability3.ts(22,9): error TS2322: Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability3.ts(23,9): error TS2322: Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typeParameterAssignability3.ts (4 errors) ==== @@ -21,9 +25,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara t = u; // error ~ !!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: Type 'Foo' is not assignable to type 'T'. u = t; // error ~ !!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'Foo' is not assignable to type 'U'. } class C { @@ -33,8 +39,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/typePara this.t = this.u; // error ~~~~~~ !!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: Type 'Foo' is not assignable to type 'T'. this.u = this.t; // error ~~~~~~ !!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'Foo' is not assignable to type 'U'. } } \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterDiamond3.errors.txt b/tests/baselines/reference/typeParameterDiamond3.errors.txt index abefeb2a2d..14d5e4a313 100644 --- a/tests/baselines/reference/typeParameterDiamond3.errors.txt +++ b/tests/baselines/reference/typeParameterDiamond3.errors.txt @@ -4,6 +4,9 @@ tests/cases/compiler/typeParameterDiamond3.ts(9,13): error TS2322: Type 'Bottom' Type 'Top | T | U' is not assignable to type 'T | U'. Type 'Top' is not assignable to type 'T | U'. Type 'Top' is not assignable to type 'U'. + Type 'Bottom' is not assignable to type 'U'. + Type 'Top | T | U' is not assignable to type 'U'. + Type 'Top' is not assignable to type 'U'. tests/cases/compiler/typeParameterDiamond3.ts(10,13): error TS2322: Type 'Bottom' is not assignable to type 'Top'. Type 'Top | T | U' is not assignable to type 'Top'. Type 'T' is not assignable to type 'Top'. @@ -27,6 +30,9 @@ tests/cases/compiler/typeParameterDiamond3.ts(10,13): error TS2322: Type 'Bottom !!! error TS2322: Type 'Top | T | U' is not assignable to type 'T | U'. !!! error TS2322: Type 'Top' is not assignable to type 'T | U'. !!! error TS2322: Type 'Top' is not assignable to type 'U'. +!!! error TS2322: Type 'Bottom' is not assignable to type 'U'. +!!! error TS2322: Type 'Top | T | U' is not assignable to type 'U'. +!!! error TS2322: Type 'Top' is not assignable to type 'U'. top = bottom; ~~~ !!! error TS2322: Type 'Bottom' is not assignable to type 'Top'. diff --git a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt index d86b63d2ce..d78faf74fa 100644 --- a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt +++ b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt @@ -2,6 +2,7 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsed tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(4,25): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(5,8): error TS2304: Cannot find name 'W'. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(8,16): error TS2322: Type 'W' is not assignable to type 'T'. + Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(12,16): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(12,29): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(15,8): error TS2304: Cannot find name 'W'. @@ -42,6 +43,7 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsed return x; ~ !!! error TS2322: Type 'W' is not assignable to type 'T'. +!!! error TS2322: Type 'V' is not assignable to type 'T'. } } diff --git a/tests/baselines/reference/typeParametersShouldNotBeEqual2.errors.txt b/tests/baselines/reference/typeParametersShouldNotBeEqual2.errors.txt index 0d9375140a..27ac1e07ea 100644 --- a/tests/baselines/reference/typeParametersShouldNotBeEqual2.errors.txt +++ b/tests/baselines/reference/typeParametersShouldNotBeEqual2.errors.txt @@ -1,8 +1,11 @@ tests/cases/compiler/typeParametersShouldNotBeEqual2.ts(4,5): error TS2322: Type 'U' is not assignable to type 'T'. + Type 'Date' is not assignable to type 'T'. tests/cases/compiler/typeParametersShouldNotBeEqual2.ts(5,5): error TS2322: Type 'V' is not assignable to type 'T'. tests/cases/compiler/typeParametersShouldNotBeEqual2.ts(6,5): error TS2322: Type 'T' is not assignable to type 'V'. + Type 'Date' is not assignable to type 'V'. tests/cases/compiler/typeParametersShouldNotBeEqual2.ts(7,5): error TS2322: Type 'V' is not assignable to type 'U'. tests/cases/compiler/typeParametersShouldNotBeEqual2.ts(8,5): error TS2322: Type 'U' is not assignable to type 'V'. + Type 'Date' is not assignable to type 'V'. tests/cases/compiler/typeParametersShouldNotBeEqual2.ts(9,5): error TS2322: Type 'Object' is not assignable to type 'T'. @@ -13,18 +16,21 @@ tests/cases/compiler/typeParametersShouldNotBeEqual2.ts(9,5): error TS2322: Type x = y; // Ok ~ !!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: Type 'Date' is not assignable to type 'T'. x = z; // Error ~ !!! error TS2322: Type 'V' is not assignable to type 'T'. z = x; // Error ~ !!! error TS2322: Type 'T' is not assignable to type 'V'. +!!! error TS2322: Type 'Date' is not assignable to type 'V'. y = z; // Error ~ !!! error TS2322: Type 'V' is not assignable to type 'U'. z = y; // Error ~ !!! error TS2322: Type 'U' is not assignable to type 'V'. +!!! error TS2322: Type 'Date' is not assignable to type 'V'. x = zz; // Error ~ !!! error TS2322: Type 'Object' is not assignable to type 'T'. diff --git a/tests/baselines/reference/typeParametersShouldNotBeEqual3.errors.txt b/tests/baselines/reference/typeParametersShouldNotBeEqual3.errors.txt index 5b1a8e9ae7..0169f57c06 100644 --- a/tests/baselines/reference/typeParametersShouldNotBeEqual3.errors.txt +++ b/tests/baselines/reference/typeParametersShouldNotBeEqual3.errors.txt @@ -1,4 +1,5 @@ tests/cases/compiler/typeParametersShouldNotBeEqual3.ts(4,5): error TS2322: Type 'U' is not assignable to type 'T'. + Type 'Object' is not assignable to type 'T'. tests/cases/compiler/typeParametersShouldNotBeEqual3.ts(5,5): error TS2322: Type 'Object' is not assignable to type 'T'. @@ -9,6 +10,7 @@ tests/cases/compiler/typeParametersShouldNotBeEqual3.ts(5,5): error TS2322: Type x = y; // Ok ~ !!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: Type 'Object' is not assignable to type 'T'. x = z; // Ok ~ !!! error TS2322: Type 'Object' is not assignable to type 'T'. diff --git a/tests/cases/compiler/assignmentNonObjectTypeConstraints.ts b/tests/cases/compiler/assignmentNonObjectTypeConstraints.ts new file mode 100644 index 0000000000..b68fad48e8 --- /dev/null +++ b/tests/cases/compiler/assignmentNonObjectTypeConstraints.ts @@ -0,0 +1,18 @@ +const enum E { A, B, C } + +function foo(x: T) { + var y: number = x; // Ok +} + +foo(5); +foo(E.A); + +class A { a } +class B { b } + +function bar(x: T) { + var y: A | B = x; // Ok +} + +bar(new A); +bar(new B); diff --git a/tests/cases/compiler/constEnumToStringNoComments.ts b/tests/cases/compiler/constEnumToStringNoComments.ts new file mode 100644 index 0000000000..802ee9068b --- /dev/null +++ b/tests/cases/compiler/constEnumToStringNoComments.ts @@ -0,0 +1,22 @@ +// @comments: false +const enum Foo { + X = 100, + Y = 0.5, + Z = 2., + A = -1, + B = -1.5, + C = -1. +} + +let x0 = Foo.X.toString(); +let x1 = Foo["X"].toString(); +let y0 = Foo.Y.toString(); +let y1 = Foo["Y"].toString(); +let z0 = Foo.Z.toString(); +let z1 = Foo["Z"].toString(); +let a0 = Foo.A.toString(); +let a1 = Foo["A"].toString(); +let b0 = Foo.B.toString(); +let b1 = Foo["B"].toString(); +let c0 = Foo.C.toString(); +let c1 = Foo["C"].toString(); diff --git a/tests/cases/compiler/constEnumToStringWithComments.ts b/tests/cases/compiler/constEnumToStringWithComments.ts new file mode 100644 index 0000000000..e10c359113 --- /dev/null +++ b/tests/cases/compiler/constEnumToStringWithComments.ts @@ -0,0 +1,22 @@ +// @comments: true +const enum Foo { + X = 100, + Y = 0.5, + Z = 2., + A = -1, + B = -1.5, + C = -1. +} + +let x0 = Foo.X.toString(); +let x1 = Foo["X"].toString(); +let y0 = Foo.Y.toString(); +let y1 = Foo["Y"].toString(); +let z0 = Foo.Z.toString(); +let z1 = Foo["Z"].toString(); +let a0 = Foo.A.toString(); +let a1 = Foo["A"].toString(); +let b0 = Foo.B.toString(); +let b1 = Foo["B"].toString(); +let c0 = Foo.C.toString(); +let c1 = Foo["C"].toString(); diff --git a/tests/cases/compiler/instanceOfAssignability.ts b/tests/cases/compiler/instanceOfAssignability.ts new file mode 100644 index 0000000000..909de1ff2a --- /dev/null +++ b/tests/cases/compiler/instanceOfAssignability.ts @@ -0,0 +1,88 @@ +interface Base { + foo: string|number; + optional?: number; +} + +// Derived1 is assignable to, but not a subtype of, Base +class Derived1 implements Base { + foo: string; +} +// Derived2 is a subtype of Base that is not assignable to Derived1 +class Derived2 implements Base { + foo: number; + optional: number; +} + +class Animal { + move; +} +class Mammal extends Animal { milk; } +class Giraffe extends Mammal { neck; } + +function fn1(x: Array|Array|boolean) { + if(x instanceof Array) { + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; + } +} + +function fn2(x: Base) { + if(x instanceof Derived1) { + // 1.5: y: Base + // Want: y: Derived1 + let y = x; + } +} + +function fn3(x: Base|Derived1) { + if(x instanceof Derived2) { + // 1.5: y: Derived2 + // Want: Derived2 + let y = x; + } +} + +function fn4(x: Base|Derived2) { + if(x instanceof Derived1) { + // 1.5: y: {} + // Want: Derived1 + let y = x; + } +} + +function fn5(x: Derived1) { + if(x instanceof Derived2) { + // 1.5: y: Derived1 + // Want: ??? + let y = x; + } +} + +function fn6(x: Animal|Mammal) { + if(x instanceof Giraffe) { + // 1.5: y: Derived1 + // Want: ??? + let y = x; + } +} + +function fn7(x: Array|Array) { + if(x instanceof Array) { + // 1.5: y: Array|Array + // Want: y: Array|Array + let y = x; + } +} + +interface Alpha { a } +interface Beta { b } +interface Gamma { c } +class ABC { a; b; c; } +function fn8(x: Alpha|Beta|Gamma) { + if(x instanceof ABC) { + let y = x; + } +} + + diff --git a/tests/cases/compiler/tupleTypeInference.ts b/tests/cases/compiler/tupleTypeInference.ts new file mode 100644 index 0000000000..7c5a49d3ca --- /dev/null +++ b/tests/cases/compiler/tupleTypeInference.ts @@ -0,0 +1,21 @@ +declare var $q: IQService; + +interface IQService { + all(x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; + all(x: [IPromise, IPromise]): IPromise<[T1, T2]>; + all(x: [IPromise]): IPromise<[T1]>; + when(t?: T): IPromise; +} + +interface IPromise { + then(callback: (t: T) => TResult): IPromise; +} + +// Implicit different types +var a = $q.all([$q.when(), $q.when()]); + +// Explicit different types +var b = $q.all([$q.when(), $q.when()]); + +// Implicit identical types +var c = $q.all([$q.when(), $q.when()]); diff --git a/tests/cases/fourslash/formattingOnChainedCallbacksAndPropertyAccesses.ts b/tests/cases/fourslash/formattingOnChainedCallbacksAndPropertyAccesses.ts new file mode 100644 index 0000000000..694f25f82e --- /dev/null +++ b/tests/cases/fourslash/formattingOnChainedCallbacksAndPropertyAccesses.ts @@ -0,0 +1,37 @@ +/// + +////var x = 1; + +////x +/////*1*/.toFixed + +////x +/////*2*/.toFixed() + +////x +/////*3*/.toFixed() +/////*4*/.length +/////*5*/.toString(); + +////x +/////*6*/.toFixed +/////*7*/.toString() +/////*8*/.length; + +format.document(); +goTo.marker('1'); +verify.currentLineContentIs(' .toFixed'); +goTo.marker('2'); +verify.currentLineContentIs(' .toFixed()'); +goTo.marker('3'); +verify.currentLineContentIs(' .toFixed()'); +goTo.marker('4'); +verify.currentLineContentIs(' .length'); +goTo.marker('5'); +verify.currentLineContentIs(' .toString();'); +goTo.marker('6'); +verify.currentLineContentIs(' .toFixed'); +goTo.marker('7'); +verify.currentLineContentIs(' .toString()'); +goTo.marker('8'); +verify.currentLineContentIs(' .length;');