mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into flagAllDuplication
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+301
-137
@@ -44,8 +44,10 @@ TypeScript is a trademark of Microsoft Corporation.
|
||||
* [3.3 Object Types](#3.3)
|
||||
* [3.3.1 Named Type References](#3.3.1)
|
||||
* [3.3.2 Array Types](#3.3.2)
|
||||
* [3.3.3 Anonymous Types](#3.3.3)
|
||||
* [3.3.4 Members](#3.3.4)
|
||||
* [3.3.3 Tuple Types](#3.3.3)
|
||||
* [3.3.4 Function Types](#3.3.4)
|
||||
* [3.3.5 Constructor Types](#3.3.5)
|
||||
* [3.3.6 Members](#3.3.6)
|
||||
* [3.4 Type Parameters](#3.4)
|
||||
* [3.4.1 Type Parameter Lists](#3.4.1)
|
||||
* [3.4.2 Type Argument Lists](#3.4.2)
|
||||
@@ -54,9 +56,13 @@ TypeScript is a trademark of Microsoft Corporation.
|
||||
* [3.6 Specifying Types](#3.6)
|
||||
* [3.6.1 Predefined Types](#3.6.1)
|
||||
* [3.6.2 Type References](#3.6.2)
|
||||
* [3.6.3 Type Queries](#3.6.3)
|
||||
* [3.6.4 Type Literals](#3.6.4)
|
||||
* [3.7 Object Type Literals](#3.7)
|
||||
* [3.6.3 Object Type Literals](#3.6.3)
|
||||
* [3.6.4 Array Type Literals](#3.6.4)
|
||||
* [3.6.5 Tuple Type Literals](#3.6.5)
|
||||
* [3.6.6 Function Type Literals](#3.6.6)
|
||||
* [3.6.7 Constructor Type Literals](#3.6.7)
|
||||
* [3.6.8 Type Queries](#3.6.8)
|
||||
* [3.7 Specifying Members](#3.7)
|
||||
* [3.7.1 Property Signatures](#3.7.1)
|
||||
* [3.7.2 Call Signatures](#3.7.2)
|
||||
* [3.7.3 Construct Signatures](#3.7.3)
|
||||
@@ -575,10 +581,10 @@ For this switch statement, the compiler will generate the following code.
|
||||
|
||||
```TypeScript
|
||||
switch (op) {
|
||||
case 0 /* Operator.ADD */ :
|
||||
case 0 /* Operator.ADD */:
|
||||
// execute add
|
||||
break;
|
||||
case 1 /* Operator.DIV */ :
|
||||
case 1 /* Operator.DIV */:
|
||||
// execute div
|
||||
break;
|
||||
// ...
|
||||
@@ -732,7 +738,7 @@ var M;
|
||||
return s;
|
||||
}
|
||||
M.f = f;
|
||||
})(M||(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.
|
||||
@@ -1041,7 +1047,20 @@ All string literal types are subtypes of the String primitive type.
|
||||
|
||||
## <a name="3.3"/>3.3 Object Types
|
||||
|
||||
The object types include references to class and interface types as well as anonymous object types created by a number of constructs such as object literals, function declarations, and module declarations. Object types are composed from properties, call signatures, construct signatures, and index signatures, collectively called members.
|
||||
Object types are composed from properties, call signatures, construct signatures, and index signatures, collectively called members.
|
||||
|
||||
Class and interface type references, array types, tuple types, function types, and constructor types are all classified as object types. Multiple constructs in the TypeScript language create object types, including:
|
||||
|
||||
* Object type literals (section [3.6.3](#3.6.3)).
|
||||
* Array type literals (section [3.6.4](#3.6.4)).
|
||||
* Tuple type literals (section [3.6.5](#3.6.5)).
|
||||
* Function type literals (section [3.6.6](#3.6.6)).
|
||||
* Constructor type literals (section [3.6.7](#3.6.7)).
|
||||
* Object literals (section [4.5](#4.5)).
|
||||
* Array literals (section [4.6](#4.6)).
|
||||
* Function expressions (section [4.9](#4.9)) and function declarations ([6.1](#6.1)).
|
||||
* Constructor function types created by class declarations (section [8.2.5](#8.2.5)).
|
||||
* Module instance types created by module declarations (section [10.3](#10.3)).
|
||||
|
||||
### <a name="3.3.1"/>3.3.1 Named Type References
|
||||
|
||||
@@ -1049,22 +1068,60 @@ Type references (section [3.6.2](#3.6.2)) to class and interface types are class
|
||||
|
||||
### <a name="3.3.2"/>3.3.2 Array Types
|
||||
|
||||
Array types represent JavaScript arrays. Array types are type references (section [3.6.2](#3.6.2)) created from the generic interface type ‘Array’ in the global module. Array type literals (section [3.6.4](#3.6.4)) provide a shorthand notation for creating such references.
|
||||
***Array types*** represent JavaScript arrays with a common element type. Array types are named type references created from the generic interface type ‘Array’ in the global module with the array element type as a type argument. Array type literals (section [3.6.4](#3.6.4)) provide a shorthand notation for creating such references.
|
||||
|
||||
Array literals (section [4.6](#4.6)) may be used to create values of array types.
|
||||
The declaration of the ‘Array’ interface includes a property ‘length’ and a numeric index signature for the element type, along with other members:
|
||||
|
||||
### <a name="3.3.3"/>3.3.3 Anonymous Types
|
||||
```TypeScript
|
||||
interface Array<T> {
|
||||
length: number;
|
||||
[x: number]: T;
|
||||
// Other members
|
||||
}
|
||||
```
|
||||
|
||||
Several constructs in the TypeScript language introduce new anonymous object types:
|
||||
Array literals (section [4.6](#4.6)) may be used to create values of array types. For example
|
||||
|
||||
* Function and constructor type literals (section [3.6.4](#3.6.4)).
|
||||
* Object type literals (section [3.7](#3.7)).
|
||||
* Object literals (section [4.5](#4.5)).
|
||||
* Function expressions (section [4.9](#4.9)) and function declarations ([6.1](#6.1)).
|
||||
* Constructor function types created by class declarations (section [8.2.5](#8.2.5)).
|
||||
* Module instance types created by module declarations (section [10.3](#10.3)).
|
||||
```TypeScript
|
||||
var a: string[] = ["hello", "world"];
|
||||
```
|
||||
|
||||
### <a name="3.3.4"/>3.3.4 Members
|
||||
### <a name="3.3.3"/>3.3.3 Tuple Types
|
||||
|
||||
***Tuple types*** represent JavaScript arrays with individually tracked element types. Tuple types are written using tuple type literals (section [3.6.5](#3.6.5)). A tuple type combines a set of numerically named properties with the members of an array type. Specifically, a tuple type
|
||||
|
||||
```TypeScript
|
||||
[ T0, T1, ..., Tn ]
|
||||
```
|
||||
|
||||
combines the set of properties
|
||||
|
||||
```TypeScript
|
||||
{
|
||||
0: T0;
|
||||
1: T1;
|
||||
...
|
||||
n: Tn;
|
||||
}
|
||||
```
|
||||
|
||||
with the members of an array type whose element type is the best common type (section [3.10](#3.10)) of the tuple element types.
|
||||
|
||||
Array literals (section [4.6](#4.6)) may be used to create values of tuple types. For example
|
||||
|
||||
```TypeScript
|
||||
var t: [number, string] = [1, "one"];
|
||||
```
|
||||
|
||||
### <a name="3.3.4"/>3.3.4 Function Types
|
||||
|
||||
An object type containing one or more call signatures is said to be a ***function type***. Function types may be written using function type literals (section [3.6.6](#3.6.6)) or by including call signatures in object type literals.
|
||||
|
||||
### <a name="3.3.5"/>3.3.5 Constructor Types
|
||||
|
||||
An object type containing one or more construct signatures is said to be a ***constructor type***. Constructor types may be written using constructor type literals (section [3.6.7](#3.6.7)) or by including construct signatures in object type literals.
|
||||
|
||||
### <a name="3.3.6"/>3.3.6 Members
|
||||
|
||||
Every object type is composed from zero or more of the following kinds of members:
|
||||
|
||||
@@ -1198,13 +1255,19 @@ class G<T> { // Introduce type parameter T
|
||||
|
||||
## <a name="3.6"/>3.6 Specifying Types
|
||||
|
||||
Types are specified either by referencing their keyword or name, by querying expression types, or by writing type literals which compose other types into new types.
|
||||
Types are specified either by referencing their keyword or name, or by writing object type literals, array type literals, tuple type literals, function type literals, constructor type literals, or type queries.
|
||||
|
||||
  *Type:*
|
||||
   *PredefinedType*
|
||||
   *TypeReference*
|
||||
   *TypeQuery*
|
||||
   *TypeLiteral*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
   *TupleType*
|
||||
   *FunctionType*
|
||||
   *ConstructorType*
|
||||
   *TypeQuery*
|
||||
|
||||
The different forms of type notations are described in the following sections.
|
||||
|
||||
### <a name="3.6.1"/>3.6.1 Predefined Types
|
||||
|
||||
@@ -1278,7 +1341,123 @@ var v1: {
|
||||
};
|
||||
```
|
||||
|
||||
### <a name="3.6.3"/>3.6.3 Type Queries
|
||||
### <a name="3.6.3"/>3.6.3 Object Type Literals
|
||||
|
||||
An object type literal defines an object type by specifying the set of members that are statically considered to be present in instances of the type. Object type literals can be given names using interface declarations but are otherwise anonymous.
|
||||
|
||||
  *ObjectType:*
|
||||
   `{` *TypeBody<sub>opt</sub>* `}`
|
||||
|
||||
  *TypeBody:*
|
||||
   *TypeMemberList* `;`*<sub>opt</sub>*
|
||||
|
||||
  *TypeMemberList:*
|
||||
   *TypeMember*
|
||||
   *TypeMemberList* `;` *TypeMember*
|
||||
|
||||
  *TypeMember:*
|
||||
   *PropertySignature*
|
||||
   *CallSignature*
|
||||
   *ConstructSignature*
|
||||
   *IndexSignature*
|
||||
   *MethodSignature*
|
||||
|
||||
The members of an object type literal are specified as a combination of property, call, construct, index, and method signatures. Object type members are described in section [3.7](#3.7).
|
||||
|
||||
### <a name="3.6.4"/>3.6.4 Array Type Literals
|
||||
|
||||
An array type literal is written as an element type followed by an open and close square bracket.
|
||||
|
||||
  *ArrayType:*
|
||||
   *ElementType* *[no LineTerminator here]* `[` `]`
|
||||
|
||||
  *ElementType:*
|
||||
   *PredefinedType*
|
||||
   *TypeReference*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
   *TupleType*
|
||||
   *TypeQuery*
|
||||
|
||||
An array type literal references an array type (section [3.3.2](#3.3.2)) with the given element type. An array type literal is simply shorthand notation for a reference to the generic interface type ‘Array’ in the global module with the element type as a type argument.
|
||||
|
||||
In order to avoid grammar ambiguities, array type literals permit only a restricted set of notations for the element type. Specifically, an *ArrayType* cannot start with a *FunctionType* or *ConstructorType*. To use one of those forms for the element type, an array type must be written using the ‘Array<T>’ notation. For example, the type
|
||||
|
||||
```TypeScript
|
||||
() => string[]
|
||||
```
|
||||
|
||||
denotes a function returning a string array, not an array of functions returning string. The latter can be expressed using ‘Array<T>’ notation
|
||||
|
||||
```TypeScript
|
||||
Array<() => string>
|
||||
```
|
||||
|
||||
or by writing the element type as an object type literal
|
||||
|
||||
```TypeScript
|
||||
{ (): string }[]
|
||||
```
|
||||
|
||||
### <a name="3.6.5"/>3.6.5 Tuple Type Literals
|
||||
|
||||
A tuple type literal is written as a sequence of element types, separated by commas and enclosed in square brackets.
|
||||
|
||||
  *TupleType:*
|
||||
   `[` *TupleElementTypes* `]`
|
||||
|
||||
  *TupleElementTypes:*
|
||||
   *TupleElementType*
|
||||
   *TupleElementTypes* `,` *TupleElementType*
|
||||
|
||||
  *TupleElementType:*
|
||||
   *Type*
|
||||
|
||||
A tuple type literal references a tuple type (section [3.3.3](#3.3.3)).
|
||||
|
||||
### <a name="3.6.6"/>3.6.6 Function Type Literals
|
||||
|
||||
A function type literal specifies the type parameters, regular parameters, and return type of a call signature.
|
||||
|
||||
  *FunctionType:*
|
||||
   *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
A function type literal is shorthand for an object type containing a single call signature. Specifically, a function type literal of the form
|
||||
|
||||
```TypeScript
|
||||
< T1, T2, ... > ( p1, p2, ... ) => R
|
||||
```
|
||||
|
||||
is exactly equivalent to the object type literal
|
||||
|
||||
```TypeScript
|
||||
{ < T1, T2, ... > ( p1, p2, ... ) : R }
|
||||
```
|
||||
|
||||
Note that function types with multiple call or construct signatures cannot be written as function type literals but must instead be written as object type literals.
|
||||
|
||||
### <a name="3.6.7"/>3.6.7 Constructor Type Literals
|
||||
|
||||
A constructor type literal specifies the type parameters, regular parameters, and return type of a construct signature.
|
||||
|
||||
  *ConstructorType:*
|
||||
   `new` *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
A constructor type literal is shorthand for an object type containing a single construct signature. Specifically, a constructor type literal of the form
|
||||
|
||||
```TypeScript
|
||||
new < T1, T2, ... > ( p1, p2, ... ) => R
|
||||
```
|
||||
|
||||
is exactly equivalent to the object type literal
|
||||
|
||||
```TypeScript
|
||||
{ new < T1, T2, ... > ( p1, p2, ... ) : R }
|
||||
```
|
||||
|
||||
Note that constructor types with multiple construct signatures cannot be written as constructor type literals but must instead be written as object type literals.
|
||||
|
||||
### <a name="3.6.8"/>3.6.8 Type Queries
|
||||
|
||||
A type query obtains the type of an expression.
|
||||
|
||||
@@ -1318,82 +1497,9 @@ var h: () => typeof h;
|
||||
|
||||
Here, ‘g’ and ‘g.x’ have the same recursive type, and likewise ‘h’ and ‘h()’ have the same recursive type.
|
||||
|
||||
### <a name="3.6.4"/>3.6.4 Type Literals
|
||||
## <a name="3.7"/>3.7 Specifying Members
|
||||
|
||||
Type literals compose other types into new anonymous types.
|
||||
|
||||
  *TypeLiteral:*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
   *FunctionType*
|
||||
   *ConstructorType*
|
||||
|
||||
  *ArrayType:*
|
||||
   *ElementType* *[no LineTerminator here]* `[` `]`
|
||||
|
||||
  *ElementType:*
|
||||
   *PredefinedType*
|
||||
   *TypeReference*
|
||||
   *TypeQuery*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
|
||||
  *FunctionType:*
|
||||
   *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
  *ConstructorType:*
|
||||
   `new` *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
Object type literals are the primary form of type literals and are described in section [3.7](#3.7). Array, function, and constructor type literals are simply shorthand notations for other types:
|
||||
|
||||
|Type literal|Equivalent form|
|
||||
|---|---|
|
||||
|`T [ ]`|`Array < T >`|
|
||||
|`< ... > ( ... ) => T`|`{ < ... > ( ... ) : T }`|
|
||||
|`new < ... > ( ... ) => T`|`{ new < ... > ( ... ) : T }`|
|
||||
|
||||
As the table above illustrates, an array type literal is shorthand for a reference to the generic interface type ‘Array’ in the global module, a function type literal is shorthand for an object type containing a single call signature, and a constructor type literal is shorthand for an object type containing a single construct signature. Note that function and constructor types with multiple call or construct signatures cannot be written as function or constructor type literals but must instead be written as object type literals.
|
||||
|
||||
In order to avoid grammar ambiguities, array type literals permit only a restricted set of notations for the element type. Specifically, an *ArrayType* cannot start with a *FunctionType* or *ConstructorType*. To use one of those forms for the element type, an array type must be written using the ‘Array<T>’ notation. For example, the type
|
||||
|
||||
```TypeScript
|
||||
() => string[]
|
||||
```
|
||||
|
||||
denotes a function returning a string array, not an array of functions returning string. The latter can be expressed using ‘Array<T>’ notation
|
||||
|
||||
```TypeScript
|
||||
Array<() => string>
|
||||
```
|
||||
|
||||
or by writing the element type as an object type literal
|
||||
|
||||
```TypeScript
|
||||
{ (): string }[]
|
||||
```
|
||||
|
||||
## <a name="3.7"/>3.7 Object Type Literals
|
||||
|
||||
An object type literal defines an object type by specifying the set of members that are statically considered to be present in instances of the type. Object type literals can be given names using interface declarations but are otherwise anonymous.
|
||||
|
||||
  *ObjectType:*
|
||||
   `{` *TypeBody<sub>opt</sub>* `}`
|
||||
|
||||
  *TypeBody:*
|
||||
   *TypeMemberList* `;`*<sub>opt</sub>*
|
||||
|
||||
  *TypeMemberList:*
|
||||
   *TypeMember*
|
||||
   *TypeMemberList* `;` *TypeMember*
|
||||
|
||||
  *TypeMember:*
|
||||
   *PropertySignature*
|
||||
   *CallSignature*
|
||||
   *ConstructSignature*
|
||||
   *IndexSignature*
|
||||
   *MethodSignature*
|
||||
|
||||
The members of an object type literal are specified as a combination of property, call, construct, index, and method signatures. The signatures are separated by semicolons and enclosed in curly braces.
|
||||
The members of an object type literal (section [3.6.3](#3.6.3)) are specified as a combination of property, call, construct, index, and method signatures.
|
||||
|
||||
### <a name="3.7.1"/>3.7.1 Property Signatures
|
||||
|
||||
@@ -1422,9 +1528,9 @@ A call signature defines the type parameters, parameter list, and return type as
|
||||
|
||||
A call signature that includes *TypeParameters* (section [3.4.1](#3.4.1)) is called a ***generic call signature***. Conversely, a call signature with no *TypeParameters* is called a non-generic call signature.
|
||||
|
||||
As well as being members of object type literals, call signatures occur in method signatures (section [3.7.5](#3.7.5)), function expressions (section [4.9](#4.9)), and function declarations (section [6.1](#6.1)).<sub>
|
||||
As well as being members of object type literals, call signatures occur in method signatures (section [3.7.5](#3.7.5)), function expressions (section [4.9](#4.9)), and function declarations (section [6.1](#6.1)).
|
||||
|
||||
</sub>An object type containing call signatures is said to be a ***function type***.
|
||||
An object type containing call signatures is said to be a ***function type***.
|
||||
|
||||
#### <a name="3.7.2.1"/>3.7.2.1 Type Parameters
|
||||
|
||||
@@ -1548,7 +1654,7 @@ The type parameters, parameter list, and return type of a construct signature ar
|
||||
|
||||
A type containing construct signatures is said to be a ***constructor type***.
|
||||
|
||||
### <a name="3.7.4"/>3.7.4 Index Signatures
|
||||
### <a name="3.7.4"/>3.7.4 Index Signatures
|
||||
|
||||
An index signature defines a type constraint for properties in the containing type.
|
||||
|
||||
@@ -1980,9 +2086,38 @@ When an object literal is contextually typed by a type that includes a string in
|
||||
|
||||
## <a name="4.6"/>4.6 Array Literals
|
||||
|
||||
In the absence of a contextual type, the type of an array literal is *C*`[]`, where *C* is the Undefined type (section [3.2.6](#3.2.6)) if the array literal is empty, or the best common type of the element expressions if the array literal is not empty.
|
||||
An array literal
|
||||
|
||||
When an array literal is contextually typed (section [4.19](#4.19)) by an object type containing a numeric index signature of type *T*, each element expression is contextually typed by *T* and the type of the array literal is the best common type of the contextual type *T* and the types of the element expressions.
|
||||
```TypeScript
|
||||
[expr1, expr2, ..., exprN]
|
||||
```
|
||||
|
||||
denotes a value of an array type (section [3.3.2](#3.3.2)) or a tuple type (section [3.3.3](#3.3.3)) depending on context.
|
||||
|
||||
Each element expression in a non-empty array literal is processed as follows:
|
||||
|
||||
* If the array literal is contextually typed (section [4.19](#4.19)) by a type *T* and *T* has a property with the numeric name *N*, where *N* is the index of the element expression in the array literal, the element expression is contextually typed by the type of that property.
|
||||
* Otherwise, if the array literal is contextually typed by a type *T* with a numeric index signature, the element expression is contextually typed by the type of the numeric index signature.
|
||||
* Otherwise, the element expression is not contextually typed.
|
||||
|
||||
The resulting type of a non-empty array literal expression is determined as follows:
|
||||
|
||||
* If the array literal is contextually typed by a type *T* and *T* has at least one property with a numeric name that matches the index of an element expression in the array literal, the resulting type is a tuple type constructed from the types of the element expressions.
|
||||
* Otherwise, if the array literal is contextually typed by a type T with a numeric index signature of type *S*, the resulting type is an array type where the element type is the best common type of the contextual type *S* and the types of the element expressions.
|
||||
* Otherwise, if the array literal is not contextually typed, the resulting type is an array type where the element type is the best common type of the types of the element expressions.
|
||||
|
||||
The resulting type of an empty array literal expression is determined as follows:
|
||||
|
||||
* If the array literal is contextually typed by a type *T* with a numeric index signature of type *S*, the resulting type is an array type with element type *S*.
|
||||
* Otherwise, the resulting type is an array type with the element type Undefined.
|
||||
|
||||
The rules above mean that an array literal is always of an array type, unless it is contextually typed by a type with numerically named properties (such as a tuple type). For example
|
||||
|
||||
```TypeScript
|
||||
var a = [1, 2]; // number[]
|
||||
var b = ["hello", true]; // {}[]
|
||||
var c: [number, string] = [3, "three"]; // [number, string]
|
||||
```
|
||||
|
||||
## <a name="4.7"/>4.7 Parentheses
|
||||
|
||||
@@ -2181,6 +2316,26 @@ where *object* and *index* are expressions, is used to access the property with
|
||||
* Otherwise, if *index* is of type Any, the String or Number primitive type, or an enum type, the property access is of type Any.
|
||||
* Otherwise, the property access is invalid and a compile-time error occurs.
|
||||
|
||||
The rules above mean that properties are strongly typed when accessed using bracket notation with the literal representation of their name. For example:
|
||||
|
||||
```TypeScript
|
||||
var type = {
|
||||
name: "boolean",
|
||||
primitive: true
|
||||
};
|
||||
|
||||
var s = type["name"]; // string
|
||||
var b = type["primitive"]; // boolean
|
||||
```
|
||||
|
||||
Tuple types assign numeric names to each of their elements and elements are therefore strongly typed when accessed using bracket notation with a numeric literal:
|
||||
|
||||
```TypeScript
|
||||
var data: [string, number] = ["five", 5];
|
||||
var s = data[0]; // string
|
||||
var n = data[1]; // number
|
||||
```
|
||||
|
||||
## <a name="4.11"/>4.11 The new Operator
|
||||
|
||||
A `new` operation has one of the following forms:
|
||||
@@ -2435,7 +2590,7 @@ The
|
||||
|
||||
### <a name="4.14.6"/>4.14.6 The typeof Operator
|
||||
|
||||
The ‘typeof’ operator takes an operand of any type and produces a value of the String primitive type. In positions where a type is expected, ‘typeof’ can also be used in a type query (section [3.6.3](#3.6.3)) to produce the type of an expression.
|
||||
The ‘typeof’ operator takes an operand of any type and produces a value of the String primitive type. In positions where a type is expected, ‘typeof’ can also be used in a type query (section [3.6.8](#3.6.8)) to produce the type of an expression.
|
||||
|
||||
```TypeScript
|
||||
var x = 5;
|
||||
@@ -2451,7 +2606,7 @@ The subsections that follow specify the compile-time processing rules of the bin
|
||||
|
||||
### <a name="4.15.1"/>4.15.1 The *, /, %, –, <<, >>, >>>, &, ^, and | operators
|
||||
|
||||
These operators require their operands to be of type Any, the Number primitive type, or an enum type. Operands of an enum type are treated as having the primitive type Number. If one operand is the `null` or `undefine``d` value, it is treated as having the type of the other operand. The result is always of the Number primitive type.
|
||||
These operators require their operands to be of type Any, the Number primitive type, or an enum type. Operands of an enum type are treated as having the primitive type Number. If one operand is the `null` or `undefined` value, it is treated as having the type of the other operand. The result is always of the Number primitive type.
|
||||
|
||||
||Any|Boolean|Number|String|Object|
|
||||
|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
@@ -4803,8 +4958,12 @@ This appendix contains a summary of the grammar found in the main document. As d
|
||||
  *Type:*
|
||||
   *PredefinedType*
|
||||
   *TypeReference*
|
||||
   *TypeQuery*
|
||||
   *TypeLiteral*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
   *TupleType*
|
||||
   *FunctionType*
|
||||
   *ConstructorType*
|
||||
   *TypeQuery*
|
||||
|
||||
  *PredefinedType:*
|
||||
   `any`
|
||||
@@ -4824,35 +4983,6 @@ This appendix contains a summary of the grammar found in the main document. As d
|
||||
   *Identifier*
|
||||
   *ModuleName* `.` *Identifier*
|
||||
|
||||
  *TypeQuery:*
|
||||
   `typeof` *TypeQueryExpression*
|
||||
|
||||
  *TypeQueryExpression:*
|
||||
   *Identifier*
|
||||
   *TypeQueryExpression* `.` *IdentifierName*
|
||||
|
||||
  *TypeLiteral:*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
   *FunctionType*
|
||||
   *ConstructorType*
|
||||
|
||||
  *ArrayType:*
|
||||
   *ElementType* *[no LineTerminator here]* `[` `]`
|
||||
|
||||
  *ElementType:*
|
||||
   *PredefinedType*
|
||||
   *TypeReference*
|
||||
   *TypeQuery*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
|
||||
  *FunctionType:*
|
||||
   *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
  *ConstructorType:*
|
||||
   `new` *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
  *ObjectType:*
|
||||
   `{` *TypeBody<sub>opt</sub>* `}`
|
||||
|
||||
@@ -4870,6 +5000,40 @@ This appendix contains a summary of the grammar found in the main document. As d
|
||||
   *IndexSignature*
|
||||
   *MethodSignature*
|
||||
|
||||
  *ArrayType:*
|
||||
   *ElementType* *[no LineTerminator here]* `[` `]`
|
||||
|
||||
  *ElementType:*
|
||||
   *PredefinedType*
|
||||
   *TypeReference*
|
||||
   *ObjectType*
|
||||
   *ArrayType*
|
||||
   *TupleType*
|
||||
   *TypeQuery*
|
||||
|
||||
  *TupleType:*
|
||||
   `[` *TupleElementTypes* `]`
|
||||
|
||||
  *TupleElementTypes:*
|
||||
   *TupleElementType*
|
||||
   *TupleElementTypes* `,` *TupleElementType*
|
||||
|
||||
  *TupleElementType:*
|
||||
   *Type*
|
||||
|
||||
  *FunctionType:*
|
||||
   *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
  *ConstructorType:*
|
||||
   `new` *TypeParameters<sub>opt</sub>* `(` *ParameterList<sub>opt</sub>* `)` `=>` *Type*
|
||||
|
||||
  *TypeQuery:*
|
||||
   `typeof` *TypeQueryExpression*
|
||||
|
||||
  *TypeQueryExpression:*
|
||||
   *Identifier*
|
||||
   *TypeQueryExpression* `.` *IdentifierName*
|
||||
|
||||
  *PropertySignature:*
|
||||
   *PropertyName* `?`*<sub>opt</sub>* *TypeAnnotation<sub>opt</sub>*
|
||||
|
||||
|
||||
+47
-19
@@ -92,7 +92,9 @@ module ts {
|
||||
getContextualType: getContextualType,
|
||||
getFullyQualifiedName: getFullyQualifiedName,
|
||||
getResolvedSignature: getResolvedSignature,
|
||||
getEnumMemberValue: getEnumMemberValue
|
||||
getEnumMemberValue: getEnumMemberValue,
|
||||
isValidPropertyAccess: isValidPropertyAccess,
|
||||
getAliasedSymbol: resolveImport
|
||||
};
|
||||
|
||||
var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined");
|
||||
@@ -4239,6 +4241,25 @@ module ts {
|
||||
return anyType;
|
||||
}
|
||||
|
||||
function isValidPropertyAccess(node: PropertyAccess, propertyName: string): boolean {
|
||||
var type = checkExpression(node.left);
|
||||
if (type !== unknownType && type !== anyType) {
|
||||
var apparentType = getApparentType(getWidenedType(type));
|
||||
var prop = getPropertyOfApparentType(apparentType, propertyName);
|
||||
if (prop && prop.parent && prop.parent.flags & SymbolFlags.Class) {
|
||||
if (node.left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.Method) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
var diagnosticsCount = diagnostics.length;
|
||||
checkClassPropertyAccess(node, type, prop);
|
||||
return diagnostics.length === diagnosticsCount
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkIndexedAccess(node: IndexedAccess): Type {
|
||||
var objectType = checkExpression(node.object);
|
||||
var indexType = checkExpression(node.index);
|
||||
@@ -4311,25 +4332,32 @@ module ts {
|
||||
}
|
||||
|
||||
function signatureHasCorrectArity(node: CallExpression, signature: Signature): boolean {
|
||||
var args = node.arguments || emptyArray;
|
||||
var isCorrect = args.length >= signature.minArgumentCount &&
|
||||
(signature.hasRestParameter || args.length <= signature.parameters.length) &&
|
||||
(!node.typeArguments || signature.typeParameters && node.typeArguments.length === signature.typeParameters.length);
|
||||
|
||||
// For error recovery, since we have parsed OmittedExpressions for any extra commas
|
||||
// in the argument list, if we see any OmittedExpressions, just return true.
|
||||
// The reason this is ok is because omitted expressions here are syntactically
|
||||
// illegal, and will cause a parse error.
|
||||
// Note: It may be worth keeping the upper bound check on arity, but removing
|
||||
// the lower bound check if there are omitted expressions.
|
||||
if (!isCorrect) {
|
||||
// Technically this type assertion is not safe because args could be initialized to emptyArray
|
||||
// above.
|
||||
if ((<NodeArray<Node>>args).hasTrailingComma || forEach(args, arg => arg.kind === SyntaxKind.OmittedExpression)) {
|
||||
return true;
|
||||
}
|
||||
if (!node.arguments) {
|
||||
// This only happens when we have something of the form:
|
||||
// new C
|
||||
//
|
||||
return signature.minArgumentCount === 0;
|
||||
}
|
||||
return isCorrect;
|
||||
|
||||
// For IDE scenarios, since we may have an incomplete call, we make two modifications
|
||||
// to arity checking.
|
||||
// 1. A trailing comma is tantamount to adding another argument
|
||||
// 2. If the call is incomplete (no closing paren) allow fewer arguments than expected
|
||||
var args = node.arguments;
|
||||
var numberOfArgs = args.hasTrailingComma ? args.length + 1 : args.length;
|
||||
var hasTooManyArguments = !signature.hasRestParameter && numberOfArgs > signature.parameters.length;
|
||||
var hasRightNumberOfTypeArguments = !node.typeArguments ||
|
||||
(signature.typeParameters && node.typeArguments.length === signature.typeParameters.length);
|
||||
|
||||
if (hasTooManyArguments || !hasRightNumberOfTypeArguments) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are missing the close paren, the call is incomplete, and we should skip
|
||||
// the lower bound check.
|
||||
var callIsIncomplete = args.end === node.end;
|
||||
var hasEnoughArguments = numberOfArgs >= signature.minArgumentCount;
|
||||
return callIsIncomplete || hasEnoughArguments;
|
||||
}
|
||||
|
||||
// If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
|
||||
|
||||
@@ -5,6 +5,7 @@ module ts {
|
||||
Unterminated_string_literal: { code: 1002, category: DiagnosticCategory.Error, key: "Unterminated string literal." },
|
||||
Identifier_expected: { code: 1003, category: DiagnosticCategory.Error, key: "Identifier expected." },
|
||||
_0_expected: { code: 1005, category: DiagnosticCategory.Error, key: "'{0}' expected." },
|
||||
A_file_cannot_have_a_reference_to_itself: { code: 1006, category: DiagnosticCategory.Error, key: "A file cannot have a reference to itself." },
|
||||
Trailing_comma_not_allowed: { code: 1009, category: DiagnosticCategory.Error, key: "Trailing comma not allowed." },
|
||||
Asterisk_Slash_expected: { code: 1010, category: DiagnosticCategory.Error, key: "'*/' expected." },
|
||||
Unexpected_token: { code: 1012, category: DiagnosticCategory.Error, key: "Unexpected token." },
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
"'{0}' expected.": {
|
||||
"category": "Error",
|
||||
"code": 1005
|
||||
},
|
||||
"A file cannot have a reference to itself.": {
|
||||
"category": "Error",
|
||||
"code": 1006
|
||||
},
|
||||
"Trailing comma not allowed.": {
|
||||
"category": "Error",
|
||||
@@ -1355,6 +1359,7 @@
|
||||
"category": "Error",
|
||||
"code": 5001
|
||||
},
|
||||
|
||||
"Cannot find the common subdirectory path for the input files.": {
|
||||
"category": "Error",
|
||||
"code": 5009
|
||||
|
||||
@@ -3150,7 +3150,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveScriptReference(sourceFile: SourceFile, reference: FileReference) {
|
||||
function tryResolveScriptReference(sourceFile: SourceFile, reference: FileReference) {
|
||||
var referenceFileName = normalizePath(combinePaths(getDirectoryPath(sourceFile.filename), reference.filename));
|
||||
return program.getSourceFile(referenceFileName);
|
||||
}
|
||||
@@ -3180,12 +3180,12 @@ module ts {
|
||||
if (!compilerOptions.noResolve) {
|
||||
var addedGlobalFileReference = false;
|
||||
forEach(root.referencedFiles, fileReference => {
|
||||
var referencedFile = resolveScriptReference(root, fileReference);
|
||||
var referencedFile = tryResolveScriptReference(root, fileReference);
|
||||
|
||||
// All the references that are not going to be part of same file
|
||||
if ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
|
||||
if (referencedFile && ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
|
||||
shouldEmitToOwnFile(referencedFile, compilerOptions) || // This is referenced file is emitting its own js file
|
||||
!addedGlobalFileReference) { // Or the global out file corresponding to this reference was not added
|
||||
!addedGlobalFileReference)) { // Or the global out file corresponding to this reference was not added
|
||||
|
||||
writeReferencePath(referencedFile);
|
||||
if (!isExternalModuleOrDeclarationFile(referencedFile)) {
|
||||
@@ -3205,11 +3205,11 @@ module ts {
|
||||
// Check what references need to be added
|
||||
if (!compilerOptions.noResolve) {
|
||||
forEach(sourceFile.referencedFiles, fileReference => {
|
||||
var referencedFile = resolveScriptReference(sourceFile, fileReference);
|
||||
var referencedFile = tryResolveScriptReference(sourceFile, fileReference);
|
||||
|
||||
// If the reference file is a declaration file or an external module, emit that reference
|
||||
if (isExternalModuleOrDeclarationFile(referencedFile) &&
|
||||
!contains(emittedReferencedFiles, referencedFile)) { // If the file reference was not already emitted
|
||||
if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) &&
|
||||
!contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted
|
||||
|
||||
writeReferencePath(referencedFile);
|
||||
emittedReferencedFiles.push(referencedFile);
|
||||
|
||||
+27
-17
@@ -1073,7 +1073,7 @@ module ts {
|
||||
case ParsingContext.TypeParameters:
|
||||
return isIdentifier();
|
||||
case ParsingContext.ArgumentExpressions:
|
||||
return isExpression();
|
||||
return token === SyntaxKind.CommaToken || isExpression();
|
||||
case ParsingContext.ArrayLiteralMembers:
|
||||
return token === SyntaxKind.CommaToken || isExpression();
|
||||
case ParsingContext.Parameters:
|
||||
@@ -1226,18 +1226,6 @@ module ts {
|
||||
error(Diagnostics._0_expected, ",");
|
||||
}
|
||||
else if (isListTerminator(kind)) {
|
||||
// Check if the last token was a comma.
|
||||
if (commaStart >= 0) {
|
||||
if (!allowTrailingComma) {
|
||||
if (file.syntacticErrors.length === errorCountBeforeParsingList) {
|
||||
// Report a grammar error so we don't affect lookahead
|
||||
grammarErrorAtPos(commaStart, scanner.getStartPos() - commaStart, Diagnostics.Trailing_comma_not_allowed);
|
||||
}
|
||||
}
|
||||
// Always preserve a trailing comma by marking it on the NodeArray
|
||||
result.hasTrailingComma = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1248,6 +1236,23 @@ module ts {
|
||||
nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
// Recording the trailing comma is deliberately done after the previous
|
||||
// loop, and not just if we see a list terminator. This is because the list
|
||||
// may have ended incorrectly, but it is still important to know if there
|
||||
// was a trailing comma.
|
||||
// Check if the last token was a comma.
|
||||
if (commaStart >= 0) {
|
||||
if (!allowTrailingComma) {
|
||||
if (file.syntacticErrors.length === errorCountBeforeParsingList) {
|
||||
// Report a grammar error so we don't affect lookahead
|
||||
grammarErrorAtPos(commaStart, scanner.getStartPos() - commaStart, Diagnostics.Trailing_comma_not_allowed);
|
||||
}
|
||||
}
|
||||
// Always preserve a trailing comma by marking it on the NodeArray
|
||||
result.hasTrailingComma = true;
|
||||
}
|
||||
|
||||
result.end = getNodeEnd();
|
||||
parsingContext = saveParsingContext;
|
||||
return result;
|
||||
@@ -3826,15 +3831,17 @@ module ts {
|
||||
}
|
||||
else {
|
||||
var matchResult = fullTripleSlashReferencePathRegEx.exec(comment);
|
||||
var start = range.pos;
|
||||
var end = range.end;
|
||||
var length = end - start;
|
||||
|
||||
if (!matchResult) {
|
||||
var start = range.pos;
|
||||
var length = range.end - start;
|
||||
errorAtPos(start, length, Diagnostics.Invalid_reference_directive_syntax);
|
||||
}
|
||||
else {
|
||||
referencedFiles.push({
|
||||
pos: range.pos,
|
||||
end: range.end,
|
||||
pos: start,
|
||||
end: end,
|
||||
filename: matchResult[3]
|
||||
});
|
||||
}
|
||||
@@ -3951,6 +3958,9 @@ module ts {
|
||||
else if (!findSourceFile(filename, isDefaultLib, refFile, refPos, refEnd)) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
}
|
||||
else if (refFile && host.getCanonicalFileName(filename) === host.getCanonicalFileName(refFile.filename)) {
|
||||
diagnostic = Diagnostics.A_file_cannot_have_a_reference_to_itself;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(findSourceFile(filename + ".ts", isDefaultLib, refFile, refPos, refEnd) || findSourceFile(filename + ".d.ts", isDefaultLib, refFile, refPos, refEnd))) {
|
||||
|
||||
@@ -655,6 +655,9 @@ module ts {
|
||||
// Returns the constant value of this enum member, or 'undefined' if the enum member has a
|
||||
// computed value.
|
||||
getEnumMemberValue(node: EnumMember): number;
|
||||
|
||||
isValidPropertyAccess(node: PropertyAccess, propertyName: string): boolean;
|
||||
getAliasedSymbol(symbol: Symbol): Symbol;
|
||||
}
|
||||
|
||||
export interface TextWriter {
|
||||
|
||||
+74
-75
@@ -412,6 +412,11 @@ module FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private raiseError(message: string) {
|
||||
message = "Marker: " + currentTestState.lastKnownMarker + "\n" + message;
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
private getDiagnostics(fileName: string): ts.Diagnostic[] {
|
||||
var syntacticErrors = this.languageService.getSyntacticDiagnostics(fileName);
|
||||
var semanticErrors = this.languageService.getSemanticDiagnostics(fileName);
|
||||
@@ -500,7 +505,7 @@ module FourSlash {
|
||||
this.printErrorLog(false, errors);
|
||||
var errorMsg = "Actual number of errors (" + actual + ") does not match expected number (" + expected + ")";
|
||||
Harness.IO.log(errorMsg);
|
||||
throw new Error(errorMsg);
|
||||
this.raiseError(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +519,7 @@ module FourSlash {
|
||||
|
||||
var evaluation = new Function(emit.outputFiles[0].text + ';\r\nreturn (' + expr + ');')();
|
||||
if (evaluation !== value) {
|
||||
throw new Error('Expected evaluation of expression "' + expr + '" to equal "' + value + '", but got "' + evaluation + '"');
|
||||
this.raiseError('Expected evaluation of expression "' + expr + '" to equal "' + value + '", but got "' + evaluation + '"');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +536,7 @@ module FourSlash {
|
||||
this.assertItemInCompletionList(members.entries, symbol, type, docComment, fullSymbolName, kind);
|
||||
}
|
||||
else {
|
||||
throw new Error("Expected a member list, but none was provided");
|
||||
this.raiseError("Expected a member list, but none was provided");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,11 +559,11 @@ module FourSlash {
|
||||
var match = members.entries.length === expectedCount;
|
||||
|
||||
if ((!match && !negative) || (match && negative)) {
|
||||
throw new Error("Member list count was " + members.entries.length + ". Expected " + expectedCount);
|
||||
this.raiseError("Member list count was " + members.entries.length + ". Expected " + expectedCount);
|
||||
}
|
||||
}
|
||||
else if (expectedCount) {
|
||||
throw new Error("Member list count was 0. Expected " + expectedCount);
|
||||
this.raiseError("Member list count was 0. Expected " + expectedCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +573,7 @@ module FourSlash {
|
||||
|
||||
var members = this.getMemberListAtCaret();
|
||||
if (members.entries.filter(e => e.name === symbol).length !== 0) {
|
||||
throw new Error('Member list did contain ' + symbol);
|
||||
this.raiseError('Member list did contain ' + symbol);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,7 +584,7 @@ module FourSlash {
|
||||
var itemsCount = completions.entries.length;
|
||||
|
||||
if (itemsCount <= count) {
|
||||
throw new Error('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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,7 +597,7 @@ module FourSlash {
|
||||
|
||||
var members = this.getMemberListAtCaret();
|
||||
if ((!members || members.entries.length === 0) && negative) {
|
||||
throw new Error("Member list is empty at Caret");
|
||||
this.raiseError("Member list is empty at Caret");
|
||||
} else if ((members && members.entries.length !== 0) && !negative) {
|
||||
|
||||
var errorMsg = "\n" + "Member List contains: [" + members.entries[0].name;
|
||||
@@ -602,7 +607,7 @@ module FourSlash {
|
||||
errorMsg += "]\n";
|
||||
|
||||
Harness.IO.log(errorMsg);
|
||||
throw new Error("Member list is not empty at Caret");
|
||||
this.raiseError("Member list is not empty at Caret");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -612,7 +617,7 @@ module FourSlash {
|
||||
|
||||
var completions = this.getCompletionListAtCaret();
|
||||
if ((!completions || completions.entries.length === 0) && negative) {
|
||||
throw new Error("Completion list is empty at Caret");
|
||||
this.raiseError("Completion list is empty at Caret");
|
||||
} else if ((completions && completions.entries.length !== 0) && !negative) {
|
||||
|
||||
var errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name;
|
||||
@@ -622,7 +627,7 @@ module FourSlash {
|
||||
errorMsg += "]\n";
|
||||
|
||||
Harness.IO.log(errorMsg);
|
||||
throw new Error("Completion list is not empty at Caret");
|
||||
this.raiseError("Completion list is not empty at Caret");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -638,7 +643,7 @@ module FourSlash {
|
||||
|
||||
var completions = this.getCompletionListAtCaret();
|
||||
if (completions && completions.entries && completions.entries.filter(e => e.name === symbol).length !== 0) {
|
||||
throw new Error('Completion list did contain ' + symbol);
|
||||
this.raiseError('Completion list did contain ' + symbol);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,21 +673,21 @@ module FourSlash {
|
||||
var references = this.getReferencesAtCaret();
|
||||
|
||||
if (!references || references.length === 0) {
|
||||
throw new Error('verifyReferencesAtPositionListContains failed - found 0 references, expected at least one.');
|
||||
this.raiseError('verifyReferencesAtPositionListContains failed - found 0 references, expected at least one.');
|
||||
}
|
||||
|
||||
for (var i = 0; i < references.length; i++) {
|
||||
var reference = references[i];
|
||||
if (reference && reference.fileName === fileName && reference.textSpan.start() === start && reference.textSpan.end() === end) {
|
||||
if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) {
|
||||
throw new Error('verifyReferencesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + reference.isWriteAccess + ', expected: ' + isWriteAccess + '.');
|
||||
this.raiseError('verifyReferencesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + reference.isWriteAccess + ', expected: ' + isWriteAccess + '.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess };
|
||||
throw new Error('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) {
|
||||
@@ -706,7 +711,7 @@ module FourSlash {
|
||||
|
||||
if (referencesCount !== count) {
|
||||
var condition = localFilesOnly ? "excluding libs" : "including libs";
|
||||
throw new Error("Expected references count (" + condition + ") to be " + count + ", but is actually " + referencesCount);
|
||||
this.raiseError("Expected references count (" + condition + ") to be " + count + ", but is actually " + referencesCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,7 +734,7 @@ module FourSlash {
|
||||
|
||||
if (implementorsCount !== count) {
|
||||
var condition = localFilesOnly ? "excluding libs" : "including libs";
|
||||
throw new Error("Expected implementors count (" + condition + ") to be " + count + ", but is actually " + implementors.length);
|
||||
this.raiseError("Expected implementors count (" + condition + ") to be " + count + ", but is actually " + implementors.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,12 +811,12 @@ module FourSlash {
|
||||
var actualQuickInfo = this.languageService.getTypeAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (negative) {
|
||||
if (actualQuickInfo) {
|
||||
throw new Error('verifyQuickInfoExists failed. Expected quick info NOT to exist');
|
||||
this.raiseError('verifyQuickInfoExists failed. Expected quick info NOT to exist');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!actualQuickInfo) {
|
||||
throw new Error('verifyQuickInfoExists failed. Expected quick info to exist');
|
||||
this.raiseError('verifyQuickInfoExists failed. Expected quick info to exist');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -886,31 +891,38 @@ module FourSlash {
|
||||
assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
public verifySignatureHelpArgumentCount(expected: number) {
|
||||
this.taoInvalidReason = 'verifySignatureHelpArgumentCount NYI';
|
||||
var signatureHelpItems = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
var actual = signatureHelpItems.argumentCount;
|
||||
assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
public verifySignatureHelpPresent(shouldBePresent = true) {
|
||||
this.taoInvalidReason = 'verifySignatureHelpPresent NYI';
|
||||
|
||||
var actual = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (shouldBePresent) {
|
||||
if (!actual) {
|
||||
throw new Error("Expected signature help to be present, but it wasn't");
|
||||
this.raiseError("Expected signature help to be present, but it wasn't");
|
||||
}
|
||||
} else {
|
||||
if (actual) {
|
||||
throw new Error("Expected no signature help, but got '" + JSON.stringify(actual) + "'");
|
||||
this.raiseError("Expected no signature help, but got '" + JSON.stringify(actual) + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private validate(name: string, expected: string, actual: string) {
|
||||
if (expected && expected !== actual) {
|
||||
throw new Error("Expected " + name + " '" + expected + "'. Got '" + actual + "' instead.");
|
||||
this.raiseError("Expected " + name + " '" + expected + "'. Got '" + actual + "' instead.");
|
||||
}
|
||||
}
|
||||
|
||||
public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
|
||||
var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (!renameInfo.canRename) {
|
||||
throw new Error("Rename did not succeed");
|
||||
this.raiseError("Rename did not succeed");
|
||||
}
|
||||
|
||||
this.validate("displayName", displayName, renameInfo.displayName);
|
||||
@@ -919,13 +931,13 @@ module FourSlash {
|
||||
this.validate("kindModifiers", kindModifiers, renameInfo.kindModifiers);
|
||||
|
||||
if (this.getRanges().length !== 1) {
|
||||
throw new Error("Expected a single range to be selected in the test file.");
|
||||
this.raiseError("Expected a single range to be selected in the test file.");
|
||||
}
|
||||
|
||||
var expectedRange = this.getRanges()[0];
|
||||
if (renameInfo.triggerSpan.start() !== expectedRange.start ||
|
||||
renameInfo.triggerSpan.end() !== expectedRange.end) {
|
||||
throw new Error("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" +
|
||||
this.raiseError("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" +
|
||||
renameInfo.triggerSpan.start() + "," + renameInfo.triggerSpan.end() + ") instead.");
|
||||
}
|
||||
}
|
||||
@@ -933,35 +945,22 @@ module FourSlash {
|
||||
public verifyRenameInfoFailed(message?: string) {
|
||||
var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (renameInfo.canRename) {
|
||||
throw new Error("Rename was expected to fail");
|
||||
this.raiseError("Rename was expected to fail");
|
||||
}
|
||||
|
||||
this.validate("error", message, renameInfo.localizedErrorMessage);
|
||||
}
|
||||
|
||||
//private getFormalParameter() {
|
||||
// var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
// return help.formal;
|
||||
//}
|
||||
|
||||
private getActiveSignatureHelpItem() {
|
||||
var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
|
||||
// If the signature hasn't been narrowed down yet (e.g. no parameters have yet been entered),
|
||||
// 'activeFormal' will be -1 (even if there is only 1 signature). Signature help will show the
|
||||
// first signature in the signature group, so go with that
|
||||
var index = help.selectedItemIndex < 0 ? 0 : help.selectedItemIndex;
|
||||
|
||||
var index = help.selectedItemIndex;
|
||||
return help.items[index];
|
||||
}
|
||||
|
||||
private getActiveParameter(): ts.SignatureHelpParameter {
|
||||
var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
|
||||
var item = help.items[help.selectedItemIndex];
|
||||
|
||||
// Same logic as in getActiveSignatureHelp - this value might be -1 until a parameter value actually gets typed
|
||||
var currentParam = help.argumentIndex < 0 ? 0 : help.argumentIndex;
|
||||
var currentParam = help.argumentIndex;
|
||||
return item.parameters[currentParam];
|
||||
}
|
||||
|
||||
@@ -1009,7 +1008,7 @@ module FourSlash {
|
||||
|
||||
// If there is not emiThisFile flag specified in the test file, throw an error
|
||||
if (emitFiles.length === 0) {
|
||||
throw new Error("No emitThisFile is specified in the test file");
|
||||
this.raiseError("No emitThisFile is specified in the test file");
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
@@ -1309,7 +1308,7 @@ module FourSlash {
|
||||
//var fullSyntaxErrs = JSON.stringify(refSyntaxTree.diagnostics());
|
||||
|
||||
//if (incrSyntaxErrs !== fullSyntaxErrs) {
|
||||
// throw new Error('Mismatched incremental/full syntactic errors for file ' + this.activeFile.fileName + '.\n=== Incremental errors ===\n' + incrSyntaxErrs + '\n=== Full Errors ===\n' + fullSyntaxErrs);
|
||||
// this.raiseError('Mismatched incremental/full syntactic errors for file ' + this.activeFile.fileName + '.\n=== Incremental errors ===\n' + incrSyntaxErrs + '\n=== Full Errors ===\n' + fullSyntaxErrs);
|
||||
//}
|
||||
|
||||
// if (this.editValidation !== IncrementalEditValidation.SyntacticOnly) {
|
||||
@@ -1326,7 +1325,7 @@ module FourSlash {
|
||||
// var incrSemanticErrs = JSON.stringify(this.languageService.getSemanticDiagnostics(this.testData.files[i].fileName));
|
||||
|
||||
// if (incrSemanticErrs !== refSemanticErrs) {
|
||||
// throw new Error('Mismatched incremental/full semantic errors for file ' + this.testData.files[i].fileName + '\n=== Incremental errors ===\n' + incrSemanticErrs + '\n=== Full Errors ===\n' + refSemanticErrs);
|
||||
// this.raiseError('Mismatched incremental/full semantic errors for file ' + this.testData.files[i].fileName + '\n=== Incremental errors ===\n' + incrSemanticErrs + '\n=== Full Errors ===\n' + refSemanticErrs);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -1365,7 +1364,7 @@ module FourSlash {
|
||||
var newContent = snapshot.getText(0, snapshot.getLength());
|
||||
|
||||
if (newContent.replace(/\s/g, '') !== oldContent.replace(/\s/g, '')) {
|
||||
throw new Error('Formatting operation destroyed non-whitespace content');
|
||||
this.raiseError('Formatting operation destroyed non-whitespace content');
|
||||
}
|
||||
}
|
||||
return runningOffset;
|
||||
@@ -1422,11 +1421,11 @@ module FourSlash {
|
||||
|
||||
var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (!definitions || !definitions.length) {
|
||||
throw new Error('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) {
|
||||
throw new Error('goToDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')');
|
||||
this.raiseError('goToDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')');
|
||||
}
|
||||
|
||||
var definition = definitions[definitionIndex];
|
||||
@@ -1442,10 +1441,10 @@ module FourSlash {
|
||||
var foundDefinitions = definitions && definitions.length;
|
||||
|
||||
if (foundDefinitions && negative) {
|
||||
throw new Error('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) {
|
||||
throw new Error('goToDefinition - expected to at least one definition location but got 0');
|
||||
this.raiseError('goToDefinition - expected to at least one definition location but got 0');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1480,7 +1479,7 @@ module FourSlash {
|
||||
|
||||
var actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (actual != numberOfSpaces) {
|
||||
throw new Error('verifyIndentationAtCurrentPosition failed - expected: ' + numberOfSpaces + ', actual: ' + actual);
|
||||
this.raiseError('verifyIndentationAtCurrentPosition failed - expected: ' + numberOfSpaces + ', actual: ' + actual);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1489,7 +1488,7 @@ module FourSlash {
|
||||
|
||||
var actual = this.getIndentation(fileName, position);
|
||||
if (actual !== numberOfSpaces) {
|
||||
throw new Error('verifyIndentationAtPosition failed - expected: ' + numberOfSpaces + ', actual: ' + actual);
|
||||
this.raiseError('verifyIndentationAtPosition failed - expected: ' + numberOfSpaces + ', actual: ' + actual);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1532,14 +1531,14 @@ module FourSlash {
|
||||
|
||||
var span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition);
|
||||
if (span === null) {
|
||||
throw new Error('verifyCurrentNameOrDottedNameSpanText\n' +
|
||||
this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' +
|
||||
'\tExpected: "' + text + '"\n' +
|
||||
'\t Actual: null');
|
||||
}
|
||||
|
||||
var actual = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(span.start(), span.end());
|
||||
if (actual !== text) {
|
||||
throw new Error('verifyCurrentNameOrDottedNameSpanText\n' +
|
||||
this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' +
|
||||
'\tExpected: "' + text + '"\n' +
|
||||
'\t Actual: "' + actual + '"');
|
||||
}
|
||||
@@ -1577,7 +1576,7 @@ module FourSlash {
|
||||
|
||||
private verifyClassifications(expected: { classificationType: string; text: string }[], actual: ts.ClassifiedSpan[]) {
|
||||
if (actual.length !== expected.length) {
|
||||
throw new Error('verifySyntacticClassification failed - expected total classifications to be ' + expected.length + ', but was ' + actual.length);
|
||||
this.raiseError('verifySyntacticClassification failed - expected total classifications to be ' + expected.length + ', but was ' + actual.length);
|
||||
}
|
||||
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
@@ -1586,7 +1585,7 @@ module FourSlash {
|
||||
|
||||
var expectedType: string = (<any>ts.ClassificationTypeNames)[expectedClassification.classificationType];
|
||||
if (expectedType !== actualClassification.classificationType) {
|
||||
throw new Error('verifySyntacticClassification failed - expected classifications type to be ' +
|
||||
this.raiseError('verifySyntacticClassification failed - expected classifications type to be ' +
|
||||
expectedType + ', but was ' +
|
||||
actualClassification.classificationType);
|
||||
}
|
||||
@@ -1594,7 +1593,7 @@ module FourSlash {
|
||||
var actualSpan = actualClassification.textSpan;
|
||||
var actualText = this.activeFile.content.substr(actualSpan.start(), actualSpan.length());
|
||||
if (expectedClassification.text !== actualText) {
|
||||
throw new Error('verifySyntacticClassification failed - expected classificatied text to be ' +
|
||||
this.raiseError('verifySyntacticClassification failed - expected classificatied text to be ' +
|
||||
expectedClassification.text + ', but was ' +
|
||||
actualText);
|
||||
}
|
||||
@@ -1621,14 +1620,14 @@ module FourSlash {
|
||||
var actual = this.languageService.getOutliningSpans(this.activeFile.fileName);
|
||||
|
||||
if (actual.length !== spans.length) {
|
||||
throw new Error('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 (var i = 0; i < spans.length; i++) {
|
||||
var expectedSpan = spans[i];
|
||||
var actualSpan = actual[i];
|
||||
if (expectedSpan.start !== actualSpan.textSpan.start() || expectedSpan.end !== actualSpan.textSpan.end()) {
|
||||
throw new Error('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualSpan.textSpan.start() + ',' + actualSpan.textSpan.end() + ')');
|
||||
this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualSpan.textSpan.start() + ',' + actualSpan.textSpan.end() + ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1638,7 +1637,7 @@ module FourSlash {
|
||||
descriptors.map(d => { return { text: d, priority: 0 }; }));
|
||||
|
||||
if (actual.length !== spans.length) {
|
||||
throw new Error('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 (var i = 0; i < spans.length; i++) {
|
||||
@@ -1647,7 +1646,7 @@ module FourSlash {
|
||||
var actualCommentSpan = new TypeScript.TextSpan(actualComment.position, actualComment.message.length);
|
||||
|
||||
if (expectedSpan.start !== actualCommentSpan.start() || expectedSpan.end !== actualCommentSpan.end()) {
|
||||
throw new Error('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualCommentSpan.start() + ',' + actualCommentSpan.end() + ')');
|
||||
this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualCommentSpan.start() + ',' + actualCommentSpan.end() + ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1658,7 +1657,7 @@ module FourSlash {
|
||||
var actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition);
|
||||
|
||||
if (actual.length !== 2) {
|
||||
throw new Error('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);
|
||||
}
|
||||
|
||||
var actualMatchPosition = -1;
|
||||
@@ -1667,11 +1666,11 @@ module FourSlash {
|
||||
} else if (bracePosition === actual[1].start()) {
|
||||
actualMatchPosition = actual[0].start();
|
||||
} else {
|
||||
throw new Error('verifyMatchingBracePosition failed - could not find the brace position: ' + bracePosition + ' in the returned list: (' + actual[0].start() + ',' + actual[0].end() + ') and (' + actual[1].start() + ',' + actual[1].end() + ')');
|
||||
this.raiseError('verifyMatchingBracePosition failed - could not find the brace position: ' + bracePosition + ' in the returned list: (' + actual[0].start() + ',' + actual[0].end() + ') and (' + actual[1].start() + ',' + actual[1].end() + ')');
|
||||
}
|
||||
|
||||
if (actualMatchPosition !== expectedMatchPosition) {
|
||||
throw new Error('verifyMatchingBracePosition failed - expected: ' + actualMatchPosition + ', actual: ' + expectedMatchPosition);
|
||||
this.raiseError('verifyMatchingBracePosition failed - expected: ' + actualMatchPosition + ', actual: ' + expectedMatchPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1681,7 +1680,7 @@ module FourSlash {
|
||||
var actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition);
|
||||
|
||||
if (actual.length !== 0) {
|
||||
throw new Error('verifyNoMatchingBracePosition failed - expected: 0 spans, actual: ' + actual.length);
|
||||
this.raiseError('verifyNoMatchingBracePosition failed - expected: 0 spans, actual: ' + actual.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1768,7 +1767,7 @@ module FourSlash {
|
||||
}
|
||||
|
||||
if (expected != actual) {
|
||||
throw new Error('verifyNavigationItemsCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
|
||||
this.raiseError('verifyNavigationItemsCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1788,7 +1787,7 @@ module FourSlash {
|
||||
var items = this.languageService.getNavigateToItems(searchValue);
|
||||
|
||||
if (!items || items.length === 0) {
|
||||
throw new Error('verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one.');
|
||||
this.raiseError('verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one.');
|
||||
}
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
@@ -1804,7 +1803,7 @@ module FourSlash {
|
||||
// if there was an explicit match kind specified, then it should be validated.
|
||||
if (matchKind !== undefined) {
|
||||
var missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName };
|
||||
throw new Error('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) + ')');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1815,7 +1814,7 @@ module FourSlash {
|
||||
var actual = this.getNavigationBarItemsCount(items);
|
||||
|
||||
if (expected != actual) {
|
||||
throw new Error('verifyGetScriptLexicalStructureListCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
|
||||
this.raiseError('verifyGetScriptLexicalStructureListCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1840,7 +1839,7 @@ module FourSlash {
|
||||
var items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
|
||||
|
||||
if (!items || items.length === 0) {
|
||||
throw new Error('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)) {
|
||||
@@ -1848,7 +1847,7 @@ module FourSlash {
|
||||
}
|
||||
|
||||
var missingItem = { name: name, kind: kind };
|
||||
throw new Error('verifyGetScriptLexicalStructureListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items) + ')');
|
||||
this.raiseError('verifyGetScriptLexicalStructureListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items) + ')');
|
||||
}
|
||||
|
||||
private navigationBarItemsContains(items: ts.NavigationBarItem[], name: string, kind: string) {
|
||||
@@ -1902,21 +1901,21 @@ module FourSlash {
|
||||
var occurances = this.getOccurancesAtCurrentPosition();
|
||||
|
||||
if (!occurances || occurances.length === 0) {
|
||||
throw new Error('verifyOccurancesAtPositionListContains failed - found 0 references, expected at least one.');
|
||||
this.raiseError('verifyOccurancesAtPositionListContains failed - found 0 references, expected at least one.');
|
||||
}
|
||||
|
||||
for (var i = 0; i < occurances.length; i++) {
|
||||
var occurance = occurances[i];
|
||||
if (occurance && occurance.fileName === fileName && occurance.textSpan.start() === start && occurance.textSpan.end() === end) {
|
||||
if (typeof isWriteAccess !== "undefined" && occurance.isWriteAccess !== isWriteAccess) {
|
||||
throw new Error('verifyOccurancesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + occurance.isWriteAccess + ', expected: ' + isWriteAccess + '.');
|
||||
this.raiseError('verifyOccurancesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + occurance.isWriteAccess + ', expected: ' + isWriteAccess + '.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess };
|
||||
throw new Error('verifyOccurancesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(occurances) + ')');
|
||||
this.raiseError('verifyOccurancesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(occurances) + ')');
|
||||
}
|
||||
|
||||
public verifyOccurrencesAtPositionListCount(expectedCount: number) {
|
||||
@@ -1925,7 +1924,7 @@ module FourSlash {
|
||||
var occurances = this.getOccurancesAtCurrentPosition();
|
||||
var actualCount = occurances ? occurances.length : 0;
|
||||
if (expectedCount !== actualCount) {
|
||||
throw new Error('verifyOccurrencesAtPositionListCount failed - actual: ' + actualCount + ', expected:' + expectedCount);
|
||||
this.raiseError('verifyOccurrencesAtPositionListCount failed - actual: ' + actualCount + ', expected:' + expectedCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2010,7 +2009,7 @@ module FourSlash {
|
||||
|
||||
var itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind })).join(",\n");
|
||||
|
||||
throw new Error("Marker: " + currentTestState.lastKnownMarker + "\n" + 'Expected "' + JSON.stringify({ name: name, type: type, docComment: docComment, fullSymbolName: fullSymbolName, kind: kind }) + '" to be in list [' + itemsString + ']');
|
||||
this.raiseError('Expected "' + JSON.stringify({ name: name, type: type, docComment: docComment, fullSymbolName: fullSymbolName, kind: kind }) + '" to be in list [' + itemsString + ']');
|
||||
}
|
||||
|
||||
private findFile(indexOrName: any) {
|
||||
|
||||
+204
-45
@@ -256,7 +256,7 @@ module ts {
|
||||
var declarations = this.getDeclarations();
|
||||
if (declarations) {
|
||||
for (var i = 0, n = declarations.length; i < n; i++) {
|
||||
this.processDocumentationCommentDeclaration(lines, declarations[0]);
|
||||
this.processDocumentationCommentDeclaration(lines, declarations[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ module ts {
|
||||
|
||||
for (var i = 0, n = commentRanges.length; i < n; i++) {
|
||||
this.processDocumentationCommentRange(
|
||||
lines, sourceFile, commentRanges[0]);
|
||||
lines, sourceFile, commentRanges[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1025,6 +1025,8 @@ module ts {
|
||||
static primitiveType = "primitive type";
|
||||
|
||||
static label = "label";
|
||||
|
||||
static alias = "alias"
|
||||
}
|
||||
|
||||
export class ScriptElementKindModifier {
|
||||
@@ -2038,15 +2040,6 @@ module ts {
|
||||
return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation);
|
||||
}
|
||||
|
||||
function isVisibleWithinClassDeclaration(symbol: Symbol, containingClass: Declaration): boolean {
|
||||
var declaration = symbol.declarations && symbol.declarations[0];
|
||||
if (declaration && (declaration.flags & NodeFlags.Private)) {
|
||||
var declarationClass = getAncestor(declaration, SyntaxKind.ClassDeclaration);
|
||||
return containingClass === declarationClass;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function filterContextualMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] {
|
||||
if (!existingMembers || existingMembers.length === 0) {
|
||||
return contextualMemberSymbols;
|
||||
@@ -2130,7 +2123,7 @@ module ts {
|
||||
}
|
||||
|
||||
// TODO: this is a hack for now, we need a proper walking mechanism to verify that we have the correct node
|
||||
var mappedNode = getNodeAtPosition(sourceFile, TypeScript.end(node) - 1);
|
||||
var mappedNode = getTouchingToken(sourceFile, TypeScript.end(node) - 1);
|
||||
if (isPunctuation(mappedNode.kind)) {
|
||||
mappedNode = mappedNode.parent;
|
||||
}
|
||||
@@ -2150,15 +2143,20 @@ module ts {
|
||||
// Right of dot member completion list
|
||||
if (isRightOfDot) {
|
||||
var symbols: Symbol[] = [];
|
||||
var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration);
|
||||
isMemberCompletion = true;
|
||||
|
||||
if (mappedNode.kind === SyntaxKind.Identifier || mappedNode.kind === SyntaxKind.QualifiedName || mappedNode.kind === SyntaxKind.PropertyAccess) {
|
||||
var symbol = typeInfoResolver.getSymbolInfo(mappedNode);
|
||||
|
||||
// This is an alias, follow what it aliases
|
||||
if (symbol && symbol.flags & SymbolFlags.Import) {
|
||||
symbol = typeInfoResolver.getAliasedSymbol(symbol);
|
||||
}
|
||||
|
||||
if (symbol && symbol.flags & SymbolFlags.HasExports) {
|
||||
// Extract module or enum members
|
||||
forEachValue(symbol.exports, symbol => {
|
||||
if (isVisibleWithinClassDeclaration(symbol, containingClass)) {
|
||||
if (typeInfoResolver.isValidPropertyAccess(<PropertyAccess>(mappedNode.parent), symbol.name)) {
|
||||
symbols.push(symbol);
|
||||
}
|
||||
});
|
||||
@@ -2170,7 +2168,7 @@ module ts {
|
||||
if (apparentType) {
|
||||
// Filter private properties
|
||||
forEach(apparentType.getApparentProperties(), symbol => {
|
||||
if (isVisibleWithinClassDeclaration(symbol, containingClass)) {
|
||||
if (typeInfoResolver.isValidPropertyAccess(<PropertyAccess>(mappedNode.parent), symbol.name)) {
|
||||
symbols.push(symbol);
|
||||
}
|
||||
});
|
||||
@@ -2205,7 +2203,7 @@ module ts {
|
||||
else {
|
||||
isMemberCompletion = false;
|
||||
/// TODO filter meaning based on the current context
|
||||
var symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace;
|
||||
var symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Import;
|
||||
var symbols = typeInfoResolver.getSymbolsInScope(mappedNode, symbolMeanings);
|
||||
|
||||
getCompletionEntriesFromSymbols(symbols, activeCompletionSession);
|
||||
@@ -2303,6 +2301,7 @@ module ts {
|
||||
if (flags & SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement;
|
||||
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
|
||||
if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement;
|
||||
if (flags & SymbolFlags.Import) return ScriptElementKind.alias;
|
||||
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
@@ -2368,7 +2367,7 @@ module ts {
|
||||
|
||||
fileName = TypeScript.switchToForwardSlashes(fileName);
|
||||
var sourceFile = getSourceFile(fileName);
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -2476,7 +2475,7 @@ module ts {
|
||||
|
||||
fileName = TypeScript.switchToForwardSlashes(fileName);
|
||||
var sourceFile = getSourceFile(fileName);
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -2559,7 +2558,7 @@ module ts {
|
||||
filename = TypeScript.switchToForwardSlashes(filename);
|
||||
var sourceFile = getSourceFile(filename);
|
||||
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -2623,7 +2622,7 @@ module ts {
|
||||
filename = TypeScript.switchToForwardSlashes(filename);
|
||||
var sourceFile = getSourceFile(filename);
|
||||
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -2645,6 +2644,11 @@ module ts {
|
||||
return getReturnOccurrences(<ReturnStatement>node.parent);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ThrowKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.ThrowStatement)) {
|
||||
return getThrowOccurrences(<ThrowStatement>node.parent);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.TryKeyword:
|
||||
case SyntaxKind.CatchKeyword:
|
||||
case SyntaxKind.FinallyKeyword:
|
||||
@@ -2685,6 +2689,11 @@ module ts {
|
||||
return getConstructorOccurrences(<ConstructorDeclaration>node.parent);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.GetAccessor) || hasKind(node.parent, SyntaxKind.SetAccessor)) {
|
||||
return getGetAndSetOccurrences(<AccessorDeclaration>node.parent);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -2762,12 +2771,108 @@ module ts {
|
||||
}
|
||||
|
||||
var keywords: Node[] = []
|
||||
forEachReturnStatement(<Block>(<FunctionDeclaration>func).body, returnStatement => {
|
||||
forEachReturnStatement(<Block>func.body, returnStatement => {
|
||||
pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword);
|
||||
});
|
||||
|
||||
// Include 'throw' statements that do not occur within a try block.
|
||||
forEach(aggregateOwnedThrowStatements(func.body), throwStatement => {
|
||||
pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword);
|
||||
});
|
||||
|
||||
return map(keywords, getReferenceEntryFromNode);
|
||||
}
|
||||
|
||||
function getThrowOccurrences(throwStatement: ThrowStatement) {
|
||||
var owner = getThrowStatementOwner(throwStatement);
|
||||
|
||||
if (!owner) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var keywords: Node[] = [];
|
||||
|
||||
forEach(aggregateOwnedThrowStatements(owner), throwStatement => {
|
||||
pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword);
|
||||
});
|
||||
|
||||
// If the "owner" is a function, then we equate 'return' and 'throw' statements in their
|
||||
// ability to "jump out" of the function, and include occurrences for both.
|
||||
if (owner.kind === SyntaxKind.FunctionBlock) {
|
||||
forEachReturnStatement(<Block>owner, returnStatement => {
|
||||
pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword);
|
||||
});
|
||||
}
|
||||
|
||||
return map(keywords, getReferenceEntryFromNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregates all throw-statements within this node *without* crossing
|
||||
* into function boundaries and try-blocks with catch-clauses.
|
||||
*/
|
||||
function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] {
|
||||
var statementAccumulator: ThrowStatement[] = []
|
||||
aggregate(node);
|
||||
return statementAccumulator;
|
||||
|
||||
function aggregate(node: Node): void {
|
||||
if (node.kind === SyntaxKind.ThrowStatement) {
|
||||
statementAccumulator.push(<ThrowStatement>node);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.TryStatement) {
|
||||
var tryStatement = <TryStatement>node;
|
||||
|
||||
if (tryStatement.catchBlock) {
|
||||
aggregate(tryStatement.catchBlock);
|
||||
}
|
||||
else {
|
||||
// Exceptions thrown within a try block lacking a catch clause
|
||||
// are "owned" in the current context.
|
||||
aggregate(tryStatement.tryBlock);
|
||||
}
|
||||
|
||||
if (tryStatement.finallyBlock) {
|
||||
aggregate(tryStatement.finallyBlock);
|
||||
}
|
||||
}
|
||||
// Do not cross function boundaries.
|
||||
else if (!isAnyFunction(node)) {
|
||||
forEachChild(node, aggregate);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* For lack of a better name, this function takes a throw statement and returns the
|
||||
* nearest ancestor that is a try-block (whose try statement has a catch clause),
|
||||
* function-block, or source file.
|
||||
*/
|
||||
function getThrowStatementOwner(throwStatement: ThrowStatement): Node {
|
||||
var child: Node = throwStatement;
|
||||
|
||||
while (child.parent) {
|
||||
var parent = child.parent;
|
||||
|
||||
if (parent.kind === SyntaxKind.FunctionBlock || parent.kind === SyntaxKind.SourceFile) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
// A throw-statement is only owned by a try-statement if the try-statement has
|
||||
// a catch clause, and if the throw-statement occurs within the try block.
|
||||
if (parent.kind === SyntaxKind.TryStatement) {
|
||||
var tryStatement = <TryStatement>parent;
|
||||
|
||||
if (tryStatement.tryBlock === child && tryStatement.catchBlock) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
child = parent;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getTryCatchFinallyOccurrences(tryStatement: TryStatement): ReferenceEntry[] {
|
||||
var keywords: Node[] = [];
|
||||
@@ -2919,6 +3024,23 @@ module ts {
|
||||
return map(keywords, getReferenceEntryFromNode);
|
||||
}
|
||||
|
||||
function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): ReferenceEntry[] {
|
||||
var keywords: Node[] = [];
|
||||
|
||||
tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor);
|
||||
tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor);
|
||||
|
||||
return map(keywords, getReferenceEntryFromNode);
|
||||
|
||||
function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void {
|
||||
var accessor = getDeclarationOfKind(accessorSymbol, accessorKind);
|
||||
|
||||
if (accessor) {
|
||||
forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if 'node' is defined and has a matching 'kind'.
|
||||
function hasKind(node: Node, kind: SyntaxKind) {
|
||||
return node !== undefined && node.kind === kind;
|
||||
@@ -2945,7 +3067,7 @@ module ts {
|
||||
filename = TypeScript.switchToForwardSlashes(filename);
|
||||
var sourceFile = getSourceFile(filename);
|
||||
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -3128,7 +3250,7 @@ module ts {
|
||||
forEach(possiblePositions, position => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
if (!node || node.getWidth() !== labelName.length) {
|
||||
return;
|
||||
}
|
||||
@@ -3184,7 +3306,7 @@ module ts {
|
||||
forEach(possiblePositions, position => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
var referenceLocation = getNodeAtPosition(sourceFile, position);
|
||||
var referenceLocation = getTouchingPropertyName(sourceFile, position);
|
||||
if (!isValidReferencePosition(referenceLocation, searchText)) {
|
||||
return;
|
||||
}
|
||||
@@ -3236,7 +3358,7 @@ module ts {
|
||||
forEach(possiblePositions, position => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
|
||||
if (!node || node.kind !== SyntaxKind.SuperKeyword) {
|
||||
return;
|
||||
@@ -3302,7 +3424,7 @@ module ts {
|
||||
forEach(possiblePositions, position => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
if (!node || node.kind !== SyntaxKind.ThisKeyword) {
|
||||
return;
|
||||
}
|
||||
@@ -4116,7 +4238,7 @@ module ts {
|
||||
var sourceFile = getCurrentSourceFile(filename);
|
||||
var result: TypeScript.TextSpan[] = [];
|
||||
|
||||
var token = getTokenAtPosition(sourceFile, position);
|
||||
var token = getTouchingToken(sourceFile, position);
|
||||
|
||||
if (token.getStart(sourceFile) === position) {
|
||||
var matchKind = getMatchingTokenKind(token);
|
||||
@@ -4400,7 +4522,7 @@ module ts {
|
||||
fileName = TypeScript.switchToForwardSlashes(fileName);
|
||||
var sourceFile = getSourceFile(fileName);
|
||||
|
||||
var node = getNodeAtPosition(sourceFile, position);
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
|
||||
// Can only rename an identifier.
|
||||
if (node && node.kind === SyntaxKind.Identifier) {
|
||||
@@ -4486,26 +4608,58 @@ module ts {
|
||||
/// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
|
||||
/// we have a series of divide operator. this list allows us to be more accurate by ruling out
|
||||
/// locations where a regexp cannot exist.
|
||||
var noRegexTable: boolean[];
|
||||
if (!noRegexTable) {
|
||||
noRegexTable = [];
|
||||
noRegexTable[SyntaxKind.Identifier] = true;
|
||||
noRegexTable[SyntaxKind.StringLiteral] = true;
|
||||
noRegexTable[SyntaxKind.NumericLiteral] = true;
|
||||
noRegexTable[SyntaxKind.RegularExpressionLiteral] = true;
|
||||
noRegexTable[SyntaxKind.ThisKeyword] = true;
|
||||
noRegexTable[SyntaxKind.PlusPlusToken] = true;
|
||||
noRegexTable[SyntaxKind.MinusMinusToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseParenToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseBracketToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseBraceToken] = true;
|
||||
noRegexTable[SyntaxKind.TrueKeyword] = true;
|
||||
noRegexTable[SyntaxKind.FalseKeyword] = true;
|
||||
var noRegexTable: boolean[] = [];
|
||||
noRegexTable[SyntaxKind.Identifier] = true;
|
||||
noRegexTable[SyntaxKind.StringLiteral] = true;
|
||||
noRegexTable[SyntaxKind.NumericLiteral] = true;
|
||||
noRegexTable[SyntaxKind.RegularExpressionLiteral] = true;
|
||||
noRegexTable[SyntaxKind.ThisKeyword] = true;
|
||||
noRegexTable[SyntaxKind.PlusPlusToken] = true;
|
||||
noRegexTable[SyntaxKind.MinusMinusToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseParenToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseBracketToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseBraceToken] = true;
|
||||
noRegexTable[SyntaxKind.TrueKeyword] = true;
|
||||
noRegexTable[SyntaxKind.FalseKeyword] = true;
|
||||
|
||||
function isAccessibilityModifier(kind: SyntaxKind) {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */
|
||||
function canFollow(keyword1: SyntaxKind, keyword2: SyntaxKind) {
|
||||
if (isAccessibilityModifier(keyword1)) {
|
||||
if (keyword2 === SyntaxKind.GetKeyword ||
|
||||
keyword2 === SyntaxKind.SetKeyword ||
|
||||
keyword2 === SyntaxKind.ConstructorKeyword ||
|
||||
keyword2 === SyntaxKind.StaticKeyword) {
|
||||
|
||||
// Allow things like "public get", "public constructor" and "public static".
|
||||
// These are all legal.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Any other keyword following "public" is actually an identifier an not a real
|
||||
// keyword.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume any other keyword combination is legal. This can be refined in the future
|
||||
// if there are more cases we want the classifier to be better at.
|
||||
return true;
|
||||
}
|
||||
|
||||
function getClassificationsForLine(text: string, lexState: EndOfLineState): ClassificationResult {
|
||||
var offset = 0;
|
||||
var lastTokenOrCommentEnd = 0;
|
||||
var token = SyntaxKind.Unknown;
|
||||
var lastNonTriviaToken = SyntaxKind.Unknown;
|
||||
|
||||
// If we're in a string literal, then prepend: "\
|
||||
@@ -4535,8 +4689,6 @@ module ts {
|
||||
entries: []
|
||||
};
|
||||
|
||||
|
||||
var token = SyntaxKind.Unknown;
|
||||
do {
|
||||
token = scanner.scan();
|
||||
|
||||
@@ -4549,6 +4701,13 @@ module ts {
|
||||
else if (lastNonTriviaToken === SyntaxKind.DotToken && isKeyword(token)) {
|
||||
token = SyntaxKind.Identifier;
|
||||
}
|
||||
else if (isKeyword(lastNonTriviaToken) && isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
|
||||
// We have two keywords in a row. Only treat the second as a keyword if
|
||||
// it's a sequence that could legally occur in the language. Otherwise
|
||||
// treat it as an identifier. This way, if someone writes "private var"
|
||||
// we recognize that 'var' is actually an identifier here.
|
||||
token = SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
lastNonTriviaToken = token;
|
||||
}
|
||||
|
||||
@@ -344,12 +344,6 @@ module ts {
|
||||
}
|
||||
var options = compilationSettingsToCompilerOptions(<CompilerOptions>JSON.parse(<any>settingsJson));
|
||||
|
||||
/// TODO: this should be pushed into VS.
|
||||
/// We can not ask the LS instance to resolve, as this will lead to asking the host about files it does not know about,
|
||||
/// something it is not designed to handle. for now make sure we never get a "noresolve == false".
|
||||
/// This value should not matter, as the host runs resolution logic independently
|
||||
options.noResolve = true;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
@@ -172,15 +172,15 @@ module ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var argumentList = getContainingArgumentList(startingToken);
|
||||
var argumentInfo = getContainingArgumentInfo(startingToken);
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
// Semantic filtering of signature help
|
||||
if (!argumentList) {
|
||||
if (!argumentInfo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var call = <CallExpression>argumentList.parent;
|
||||
var call = <CallExpression>argumentInfo.list.parent;
|
||||
var candidates = <Signature[]>[];
|
||||
var resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates);
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
@@ -189,13 +189,13 @@ module ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return createSignatureHelpItems(candidates, resolvedSignature, argumentList);
|
||||
return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo);
|
||||
|
||||
/**
|
||||
* If node is an argument, returns its index in the argument list.
|
||||
* If not, returns -1.
|
||||
*/
|
||||
function getImmediatelyContainingArgumentList(node: Node): Node {
|
||||
function getImmediatelyContainingArgumentInfo(node: Node): ListItemInfo {
|
||||
if (node.parent.kind !== SyntaxKind.CallExpression && node.parent.kind !== SyntaxKind.NewExpression) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -216,10 +216,14 @@ module ts.SignatureHelp {
|
||||
var parent = <CallExpression>node.parent;
|
||||
// Find out if 'node' is an argument, a type argument, or neither
|
||||
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
|
||||
// Find the list that starts right *after* the < or ( token
|
||||
// Find the list that starts right *after* the < or ( token.
|
||||
// If the user has just opened a list, consider this item 0.
|
||||
var list = getChildListThatStartsWithOpenerToken(parent, node, sourceFile);
|
||||
Debug.assert(list);
|
||||
return list;
|
||||
return {
|
||||
list: list,
|
||||
listItemIndex: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.GreaterThanToken
|
||||
@@ -228,18 +232,18 @@ module ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return findContainingList(node);
|
||||
return findListItemInfo(node);
|
||||
}
|
||||
|
||||
function getContainingArgumentList(node: Node): Node {
|
||||
function getContainingArgumentInfo(node: Node): ListItemInfo {
|
||||
for (var n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) {
|
||||
if (n.kind === SyntaxKind.FunctionBlock) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var argumentList = getImmediatelyContainingArgumentList(n);
|
||||
if (argumentList) {
|
||||
return argumentList;
|
||||
var argumentInfo = getImmediatelyContainingArgumentInfo(n);
|
||||
if (argumentInfo) {
|
||||
return argumentInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +252,35 @@ module ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentListOrTypeArgumentList: Node): SignatureHelpItems {
|
||||
/**
|
||||
* The selectedItemIndex could be negative for several reasons.
|
||||
* 1. There are too many arguments for all of the overloads
|
||||
* 2. None of the overloads were type compatible
|
||||
* The solution here is to try to pick the best overload by picking
|
||||
* either the first one that has an appropriate number of parameters,
|
||||
* or the one with the most parameters.
|
||||
*/
|
||||
function selectBestInvalidOverloadIndex(candidates: Signature[], argumentCount: number): number {
|
||||
var maxParamsSignatureIndex = -1;
|
||||
var maxParams = -1;
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
var candidate = candidates[i];
|
||||
|
||||
if (candidate.hasRestParameter || candidate.parameters.length >= argumentCount) {
|
||||
return i;
|
||||
}
|
||||
|
||||
if (candidate.parameters.length > maxParams) {
|
||||
maxParams = candidate.parameters.length;
|
||||
maxParamsSignatureIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return maxParamsSignatureIndex;
|
||||
}
|
||||
|
||||
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentInfoOrTypeArgumentInfo: ListItemInfo): SignatureHelpItems {
|
||||
var argumentListOrTypeArgumentList = argumentInfoOrTypeArgumentInfo.list;
|
||||
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
|
||||
var parameters = candidateSignature.parameters;
|
||||
var parameterHelpItems: SignatureHelpParameter[] = parameters.length === 0 ? emptyArray : map(parameters, p => {
|
||||
@@ -321,11 +353,6 @@ module ts.SignatureHelp {
|
||||
};
|
||||
});
|
||||
|
||||
var selectedItemIndex = candidates.indexOf(bestSignature);
|
||||
if (selectedItemIndex < 0) {
|
||||
selectedItemIndex = 0;
|
||||
}
|
||||
|
||||
// We use full start and skip trivia on the end because we want to include trivia on
|
||||
// both sides. For example,
|
||||
//
|
||||
@@ -338,63 +365,38 @@ module ts.SignatureHelp {
|
||||
var applicableSpanEnd = skipTrivia(sourceFile.text, argumentListOrTypeArgumentList.end, /*stopAfterLineBreak*/ false);
|
||||
var applicableSpan = new TypeScript.TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
|
||||
|
||||
var state = getSignatureHelpCurrentArgumentState(sourceFile, position, applicableSpanStart);
|
||||
// The listItemIndex we got back includes commas. Our goal is to return the index of the proper
|
||||
// item (not including commas). Here are some examples:
|
||||
// 1. foo(a, b, c $) -> the listItemIndex is 4, we want to return 2
|
||||
// 2. foo(a, b, $ c) -> listItemIndex is 3, we want to return 2
|
||||
// 3. foo($a) -> listItemIndex is 0, we want to return 0
|
||||
//
|
||||
// In general, we want to subtract the number of commas before the current index.
|
||||
// But if we are on a comma, we also want to pretend we are on the argument *following*
|
||||
// the comma. That amounts to taking the ceiling of half the index.
|
||||
var argumentIndex = (argumentInfoOrTypeArgumentInfo.listItemIndex + 1) >> 1;
|
||||
|
||||
// argumentCount is the number of commas plus one, unless the list is completely empty,
|
||||
// in which case there are 0.
|
||||
var argumentCount = argumentListOrTypeArgumentList.getChildCount() === 0
|
||||
? 0
|
||||
: 1 + countWhere(argumentListOrTypeArgumentList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken);
|
||||
|
||||
var selectedItemIndex = candidates.indexOf(bestSignature);
|
||||
if (selectedItemIndex < 0) {
|
||||
selectedItemIndex = selectBestInvalidOverloadIndex(candidates, argumentCount);
|
||||
}
|
||||
|
||||
return {
|
||||
items: items,
|
||||
applicableSpan: applicableSpan,
|
||||
selectedItemIndex: selectedItemIndex,
|
||||
argumentIndex: state.argumentIndex,
|
||||
argumentCount: state.argumentCount
|
||||
argumentIndex: argumentIndex,
|
||||
argumentCount: argumentCount
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getSignatureHelpCurrentArgumentState(sourceFile: SourceFile, position: number, applicableSpanStart: number): { argumentIndex: number; argumentCount: number } {
|
||||
var tokenPrecedingSpanStart = findPrecedingToken(applicableSpanStart, sourceFile);
|
||||
if (!tokenPrecedingSpanStart) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (tokenPrecedingSpanStart.kind !== SyntaxKind.OpenParenToken && tokenPrecedingSpanStart.kind !== SyntaxKind.LessThanToken) {
|
||||
// The span start must have moved backward in the file (for example if the open paren was backspaced)
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var tokenPrecedingCurrentPosition = findPrecedingToken(position, sourceFile);
|
||||
var call = <CallExpression>tokenPrecedingSpanStart.parent;
|
||||
Debug.assert(call.kind === SyntaxKind.CallExpression || call.kind === SyntaxKind.NewExpression, "wrong call kind " + SyntaxKind[call.kind]);
|
||||
if (tokenPrecedingCurrentPosition.kind === SyntaxKind.CloseParenToken || tokenPrecedingCurrentPosition.kind === SyntaxKind.GreaterThanToken) {
|
||||
if (tokenPrecedingCurrentPosition.parent === call) {
|
||||
// This call expression is complete. Stop signature help.
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
var argumentListOrTypeArgumentList = getChildListThatStartsWithOpenerToken(call, tokenPrecedingSpanStart, sourceFile);
|
||||
// Debug.assert(argumentListOrTypeArgumentList.getChildCount() === 0 || argumentListOrTypeArgumentList.getChildCount() % 2 === 1, "Even number of children");
|
||||
|
||||
// The call might be finished, but incorrectly. Check if we are still within the bounds of the call
|
||||
if (position > skipTrivia(sourceFile.text, argumentListOrTypeArgumentList.end, /*stopAfterLineBreak*/ false)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var numberOfCommas = countWhere(argumentListOrTypeArgumentList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken);
|
||||
var argumentCount = numberOfCommas + 1;
|
||||
if (argumentCount <= 1) {
|
||||
return { argumentIndex: 0, argumentCount: argumentCount };
|
||||
}
|
||||
|
||||
var indexOfNodeContainingPosition = findListItemIndexContainingPosition(argumentListOrTypeArgumentList, position);
|
||||
|
||||
// indexOfNodeContainingPosition checks that position is between pos and end of each child, so it is
|
||||
// possible that we are to the right of all children. Assume that we are still within
|
||||
// the applicable span and that we are typing the last argument
|
||||
// Alternatively, we could be in range of one of the arguments, in which case we need to divide
|
||||
// by 2 to exclude commas. Use bit shifting in order to take the floor of the division.
|
||||
var argumentIndex = indexOfNodeContainingPosition < 0 ? argumentCount - 1 : indexOfNodeContainingPosition >> 1;
|
||||
return { argumentIndex: argumentIndex, argumentCount: argumentCount };
|
||||
}
|
||||
|
||||
function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node {
|
||||
var children = parent.getChildren(sourceFile);
|
||||
var indexOfOpenerToken = children.indexOf(openerToken);
|
||||
|
||||
+58
-26
@@ -50,34 +50,54 @@ module ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Get a token that contains the position. This is guaranteed to return a token, the position can be in the
|
||||
* leading trivia or within the token text.
|
||||
*/
|
||||
export function getTokenAtPosition(sourceFile: SourceFile, position: number) {
|
||||
var current: Node = sourceFile;
|
||||
outer: while (true) {
|
||||
// find the child that has this
|
||||
for (var i = 0, n = current.getChildCount(); i < n; i++) {
|
||||
var child = current.getChildAt(i);
|
||||
if (child.getFullStart() <= position && position < child.getEnd()) {
|
||||
current = child;
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
/* Gets the token whose text has range [start, end) and
|
||||
* position >= start and (position < end or (position === end && token is keyword or identifier))
|
||||
*/
|
||||
export function getTouchingWord(sourceFile: SourceFile, position: number): Node {
|
||||
return getTouchingToken(sourceFile, position, isWord);
|
||||
}
|
||||
|
||||
/** Get the token whose text contains the position, or the containing node. */
|
||||
export function getNodeAtPosition(sourceFile: SourceFile, position: number) {
|
||||
/* Gets the token whose text has range [start, end) and position >= start
|
||||
* and (position < end or (position === end && token is keyword or identifier or numeric\string litera))
|
||||
*/
|
||||
export function getTouchingPropertyName(sourceFile: SourceFile, position: number): Node {
|
||||
return getTouchingToken(sourceFile, position, isPropertyName);
|
||||
}
|
||||
|
||||
/** Returns the token if position is in [start, end) or if position === end and includeItemAtEndPosition(token) === true */
|
||||
export function getTouchingToken(sourceFile: SourceFile, position: number, includeItemAtEndPosition?: (n: Node) => boolean): Node {
|
||||
return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includeItemAtEndPosition);
|
||||
}
|
||||
|
||||
/** Returns a token if position is in [start-of-leading-trivia, end) */
|
||||
export function getTokenAtPosition(sourceFile: SourceFile, position: number): Node {
|
||||
return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includeItemAtEndPosition*/ undefined);
|
||||
}
|
||||
|
||||
/** Get the token whose text contains the position */
|
||||
function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeItemAtEndPosition: (n: Node) => boolean): Node {
|
||||
var current: Node = sourceFile;
|
||||
outer: while (true) {
|
||||
// find the child that has this
|
||||
for (var i = 0, n = current.getChildCount(); i < n; i++) {
|
||||
if (isToken(current)) {
|
||||
// exit early
|
||||
return current;
|
||||
}
|
||||
|
||||
// find the child that contains 'position'
|
||||
for (var i = 0, n = current.getChildCount(sourceFile); i < n; i++) {
|
||||
var child = current.getChildAt(i);
|
||||
if (child.getStart() <= position && position < child.getEnd()) {
|
||||
current = child;
|
||||
continue outer;
|
||||
var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile);
|
||||
if (start <= position) {
|
||||
if (position < child.getEnd()) {
|
||||
current = child;
|
||||
continue outer;
|
||||
}
|
||||
else if (includeItemAtEndPosition && child.getEnd() === position) {
|
||||
var previousToken = findPrecedingToken(position, sourceFile, child);
|
||||
if (previousToken && includeItemAtEndPosition(previousToken)) {
|
||||
return previousToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return current;
|
||||
@@ -130,8 +150,8 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function findPrecedingToken(position: number, sourceFile: SourceFile): Node {
|
||||
return find(sourceFile);
|
||||
export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node): Node {
|
||||
return find(startNode || sourceFile);
|
||||
|
||||
function findRightmostToken(n: Node): Node {
|
||||
if (isToken(n)) {
|
||||
@@ -167,7 +187,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
Debug.assert(n.kind === SyntaxKind.SourceFile);
|
||||
Debug.assert(startNode || n.kind === SyntaxKind.SourceFile);
|
||||
|
||||
// Here we know that none of child token nodes embrace the position,
|
||||
// the only known case is when position is at the end of the file.
|
||||
@@ -205,4 +225,16 @@ module ts {
|
||||
function isToken(n: Node): boolean {
|
||||
return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken;
|
||||
}
|
||||
|
||||
function isKeyword(n: Node): boolean {
|
||||
return n.kind >= SyntaxKind.FirstKeyword && n.kind <= SyntaxKind.LastKeyword;
|
||||
}
|
||||
|
||||
function isWord(n: Node): boolean {
|
||||
return n.kind === SyntaxKind.Identifier || isKeyword(n);
|
||||
}
|
||||
|
||||
function isPropertyName(n: Node): boolean {
|
||||
return n.kind === SyntaxKind.StringLiteral || n.kind === SyntaxKind.NumericLiteral || isWord(n);
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -1,9 +1,12 @@
|
||||
main.ts(1,1): error TS1006: A file cannot have a reference to itself.
|
||||
main.ts(2,1): error TS6053: File 'nonExistingFile1.ts' not found.
|
||||
main.ts(3,1): error TS6053: File 'nonExistingFile2.ts' not found.
|
||||
|
||||
|
||||
==== main.ts (2 errors) ====
|
||||
==== main.ts (3 errors) ====
|
||||
/// <reference path="main.ts" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1006: A file cannot have a reference to itself.
|
||||
/// <reference path="nonExistingFile1.ts" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS6053: File 'nonExistingFile1.ts' not found.
|
||||
|
||||
+4
-1
@@ -1,9 +1,12 @@
|
||||
main.ts(1,1): error TS1006: A file cannot have a reference to itself.
|
||||
main.ts(2,1): error TS6053: File 'nonExistingFile1.ts' not found.
|
||||
main.ts(3,1): error TS6053: File 'nonExistingFile2.ts' not found.
|
||||
|
||||
|
||||
==== main.ts (2 errors) ====
|
||||
==== main.ts (3 errors) ====
|
||||
/// <reference path="main.ts" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1006: A file cannot have a reference to itself.
|
||||
/// <reference path="nonExistingFile1.ts" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS6053: File 'nonExistingFile1.ts' not found.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
tests/cases/compiler/selfReferencingFile.ts(1,1): error TS1006: A file cannot have a reference to itself.
|
||||
|
||||
|
||||
==== tests/cases/compiler/selfReferencingFile.ts (1 errors) ====
|
||||
///<reference path='selfReferencingFile.ts'/>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1006: A file cannot have a reference to itself.
|
||||
|
||||
class selfReferencingFile {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
tests/cases/compiler/selfReferencingFile2.ts(1,1): error TS6053: File 'tests/cases/selfReferencingFile2.ts' not found.
|
||||
|
||||
|
||||
==== tests/cases/compiler/selfReferencingFile2.ts (1 errors) ====
|
||||
///<reference path='../selfReferencingFile2.ts'/>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS6053: File 'selfReferencingFile2.ts' not found.
|
||||
|
||||
class selfReferencingFile2 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
tests/cases/compiler/selfReferencingFile3.ts(1,1): error TS1006: A file cannot have a reference to itself.
|
||||
|
||||
|
||||
==== tests/cases/compiler/selfReferencingFile3.ts (1 errors) ====
|
||||
///<reference path='./selfReferencingFile3.ts'/>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1006: A file cannot have a reference to itself.
|
||||
|
||||
class selfReferencingFile3 {
|
||||
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(4,7): error TS1009: Trailing comma not allowed.
|
||||
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(9,8): error TS1009: Trailing comma not allowed.
|
||||
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(9,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
|
||||
|
||||
==== tests/cases/compiler/trailingSeparatorInFunctionCall.ts (2 errors) ====
|
||||
==== tests/cases/compiler/trailingSeparatorInFunctionCall.ts (4 errors) ====
|
||||
function f(x, y) {
|
||||
}
|
||||
|
||||
f(1, 2, );
|
||||
~
|
||||
!!! error TS1009: Trailing comma not allowed.
|
||||
~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
|
||||
function f2<T>(x: T, y: T) {
|
||||
}
|
||||
|
||||
f2(1, 2, );
|
||||
~
|
||||
!!! error TS1009: Trailing comma not allowed.
|
||||
!!! error TS1009: Trailing comma not allowed.
|
||||
~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
@@ -0,0 +1,5 @@
|
||||
///<reference path='selfReferencingFile.ts'/>
|
||||
|
||||
class selfReferencingFile {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
///<reference path='../selfReferencingFile2.ts'/>
|
||||
|
||||
class selfReferencingFile2 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
///<reference path='./selfReferencingFile3.ts'/>
|
||||
|
||||
class selfReferencingFile3 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private privateMethod() { }
|
||||
//// private privateProperty;
|
||||
////
|
||||
//// protected protectedMethod() { }
|
||||
//// protected protectedProperty;
|
||||
////
|
||||
//// public publicMethod() { }
|
||||
//// public publicProperty;
|
||||
////
|
||||
//// protected protectedOverriddenMethod() { }
|
||||
//// protected protectedOverriddenProperty;
|
||||
////
|
||||
//// test() {
|
||||
//// this./*1*/;
|
||||
////
|
||||
//// var b: Base;
|
||||
//// var c: C1;
|
||||
////
|
||||
//// b./*2*/;
|
||||
//// c./*3*/;
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////class C1 extends Base {
|
||||
//// protected protectedOverriddenMethod() { }
|
||||
//// protected protectedOverriddenProperty;
|
||||
////}
|
||||
|
||||
|
||||
// Same class, everything is visible
|
||||
goTo.marker("1");
|
||||
verify.memberListContains('privateMethod');
|
||||
verify.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
goTo.marker("2");
|
||||
verify.memberListContains('privateMethod');
|
||||
verify.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
// Can not access protected properties overridden in subclass
|
||||
goTo.marker("3");
|
||||
verify.memberListContains('privateMethod');
|
||||
verify.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.not.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
@@ -0,0 +1,76 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private privateMethod() { }
|
||||
//// private privateProperty;
|
||||
////
|
||||
//// protected protectedMethod() { }
|
||||
//// protected protectedProperty;
|
||||
////
|
||||
//// public publicMethod() { }
|
||||
//// public publicProperty;
|
||||
////
|
||||
//// protected protectedOverriddenMethod() { }
|
||||
//// protected protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
////class C1 extends Base {
|
||||
//// protected protectedOverriddenMethod() { }
|
||||
//// protected protectedOverriddenProperty;
|
||||
////
|
||||
//// test() {
|
||||
//// this./*1*/;
|
||||
//// super./*2*/;
|
||||
////
|
||||
//// var b: Base;
|
||||
//// var c: C1;
|
||||
////
|
||||
//// b./*3*/;
|
||||
//// c./*4*/;
|
||||
//// }
|
||||
////}
|
||||
|
||||
|
||||
// Same class, everything is visible
|
||||
goTo.marker("1");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
// Can not access properties on super
|
||||
goTo.marker("2");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.not.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
// Can not access protected properties through base class
|
||||
goTo.marker("3");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.not.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.not.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
// Same class, everything is visible
|
||||
goTo.marker("4");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
@@ -0,0 +1,46 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private privateMethod() { }
|
||||
//// private privateProperty;
|
||||
////
|
||||
//// protected protectedMethod() { }
|
||||
//// protected protectedProperty;
|
||||
////
|
||||
//// public publicMethod() { }
|
||||
//// public publicProperty;
|
||||
////
|
||||
//// protected protectedOverriddenMethod() { }
|
||||
//// protected protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
////class C1 extends Base {
|
||||
//// protected protectedOverriddenMethod() { }
|
||||
//// protected protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
//// var b: Base;
|
||||
//// var c: C1;
|
||||
//// b./*1*/;
|
||||
//// c./*2*/;
|
||||
|
||||
// Only public properties are visible outside the class
|
||||
goTo.marker("1");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.not.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.not.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
goTo.marker("2");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.not.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.not.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
@@ -0,0 +1,34 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private privateMethod() { }
|
||||
//// private privateProperty;
|
||||
////
|
||||
//// protected protectedMethod() { }
|
||||
//// protected protectedProperty;
|
||||
////
|
||||
//// public publicMethod() { }
|
||||
//// public publicProperty;
|
||||
////
|
||||
//// protected protectedOverriddenMethod() { }
|
||||
//// protected protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
////class C1 extends Base {
|
||||
//// public protectedOverriddenMethod() { }
|
||||
//// public protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
//// var c: C1;
|
||||
//// c./*1*/
|
||||
|
||||
|
||||
goTo.marker("1");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.not.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////module M {
|
||||
//// export var value;
|
||||
////
|
||||
//// import x = M;
|
||||
//// /*1*/
|
||||
//// x./*2*/
|
||||
////}
|
||||
|
||||
goTo.marker("1");
|
||||
verify.memberListContains("x", undefined, undefined, undefined ,/*kind: */ "alias");
|
||||
|
||||
goTo.marker("2");
|
||||
verify.memberListContains("value");
|
||||
@@ -0,0 +1,74 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////module M {
|
||||
//// export interface I { }
|
||||
//// export class C {
|
||||
//// static property;
|
||||
//// }
|
||||
//// export enum E {
|
||||
//// value = 0
|
||||
//// }
|
||||
//// export module N {
|
||||
//// export var v;
|
||||
//// }
|
||||
//// export var V = 0;
|
||||
//// export function F() { }
|
||||
//// export import A = M;
|
||||
////}
|
||||
////
|
||||
////import m = M;
|
||||
////import c = M.C;
|
||||
////import e = M.E;
|
||||
////import n = M.N;
|
||||
////import v = M.V;
|
||||
////import f = M.F;
|
||||
////import a = M.A;
|
||||
////
|
||||
////m./*1*/;
|
||||
////c./*2*/;
|
||||
////e./*3*/;
|
||||
////n./*4*/;
|
||||
////v./*5*/;
|
||||
////f./*6*/;
|
||||
////a./*7*/;
|
||||
|
||||
|
||||
// Module m
|
||||
goTo.marker("1");
|
||||
verify.memberListContains("I");
|
||||
verify.memberListContains("C");
|
||||
verify.memberListContains("E");
|
||||
verify.memberListContains("N");
|
||||
verify.memberListContains("V");
|
||||
verify.memberListContains("F");
|
||||
verify.memberListContains("A");
|
||||
|
||||
// Class C
|
||||
goTo.marker("2");
|
||||
verify.memberListContains("property");
|
||||
|
||||
// Enum E
|
||||
goTo.marker("3");
|
||||
verify.memberListContains("value");
|
||||
|
||||
// Module N
|
||||
goTo.marker("4");
|
||||
verify.memberListContains("v");
|
||||
|
||||
// var V
|
||||
goTo.marker("5");
|
||||
verify.memberListContains("toFixed");
|
||||
|
||||
// function F
|
||||
goTo.marker("6");
|
||||
verify.memberListContains("call");
|
||||
|
||||
// alias a
|
||||
goTo.marker("7");
|
||||
verify.memberListContains("I");
|
||||
verify.memberListContains("C");
|
||||
verify.memberListContains("E");
|
||||
verify.memberListContains("N");
|
||||
verify.memberListContains("V");
|
||||
verify.memberListContains("F");
|
||||
verify.memberListContains("A");
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////declare module 'foobar' {
|
||||
//// interface Q { x: number; }
|
||||
////}
|
||||
////declare module 'thing' {
|
||||
//// import x = require('foobar');
|
||||
//// var m: x./*1*/;
|
||||
////}
|
||||
|
||||
// Q does not show up in member list of x
|
||||
goTo.marker("1");
|
||||
verify.memberListContains("Q");
|
||||
@@ -0,0 +1,44 @@
|
||||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
////class Base {
|
||||
//// protected y;
|
||||
//// constructor(protected x) {}
|
||||
//// method() { this./*1*/; }
|
||||
////}
|
||||
////class D1 extends Base {
|
||||
//// protected z;
|
||||
//// method1() { this./*2*/; }
|
||||
////}
|
||||
////class D2 extends Base {
|
||||
//// method2() { this./*3*/; }
|
||||
////}
|
||||
////class D3 extends D1 {
|
||||
//// method2() { this./*4*/; }
|
||||
////}
|
||||
////var b: Base;
|
||||
////f./*5*/
|
||||
|
||||
goTo.marker("1");
|
||||
verify.memberListContains("y");
|
||||
verify.memberListContains("x");
|
||||
verify.not.memberListContains("z");
|
||||
|
||||
goTo.marker("2");
|
||||
verify.memberListContains("y");
|
||||
verify.memberListContains("x");
|
||||
verify.memberListContains("z");
|
||||
|
||||
goTo.marker("3");
|
||||
verify.memberListContains("y");
|
||||
verify.memberListContains("x");
|
||||
verify.not.memberListContains("z");
|
||||
|
||||
goTo.marker("4");
|
||||
verify.memberListContains("y");
|
||||
verify.memberListContains("x");
|
||||
verify.memberListContains("z");
|
||||
|
||||
goTo.marker("5");
|
||||
verify.not.memberListContains("x");
|
||||
verify.not.memberListContains("y");
|
||||
verify.not.memberListContains("z");
|
||||
@@ -0,0 +1,59 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private static privateMethod() { }
|
||||
//// private static privateProperty;
|
||||
////
|
||||
//// protected static protectedMethod() { }
|
||||
//// protected static protectedProperty;
|
||||
////
|
||||
//// public static publicMethod() { }
|
||||
//// public static publicProperty;
|
||||
////
|
||||
//// protected static protectedOverriddenMethod() { }
|
||||
//// protected static protectedOverriddenProperty;
|
||||
////
|
||||
//// static test() {
|
||||
//// Base./*1*/;
|
||||
//// this./*2*/;
|
||||
//// C1./*3*/;
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////class C1 extends Base {
|
||||
//// protected static protectedOverriddenMethod() { }
|
||||
//// protected static protectedOverriddenProperty;
|
||||
////}
|
||||
|
||||
|
||||
// Same class, everything is visible
|
||||
goTo.marker("1");
|
||||
verify.memberListContains('privateMethod');
|
||||
verify.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
goTo.marker("2");
|
||||
verify.memberListContains('privateMethod');
|
||||
verify.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
// Can not access protected properties overridden in subclass
|
||||
goTo.marker("3");
|
||||
verify.memberListContains('privateMethod');
|
||||
verify.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.not.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
@@ -0,0 +1,70 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private static privateMethod() { }
|
||||
//// private static privateProperty;
|
||||
////
|
||||
//// protected static protectedMethod() { }
|
||||
//// protected static protectedProperty;
|
||||
////
|
||||
//// public static publicMethod() { }
|
||||
//// public static publicProperty;
|
||||
////
|
||||
//// protected static protectedOverriddenMethod() { }
|
||||
//// protected static protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
////class C2 extends Base {
|
||||
//// protected static protectedOverriddenMethod() { }
|
||||
//// protected static protectedOverriddenProperty;
|
||||
////
|
||||
//// static test() {
|
||||
//// Base./*1*/;
|
||||
//// C2./*2*/;
|
||||
//// this./*3*/;
|
||||
//// super./*4*/;
|
||||
//// }
|
||||
////}
|
||||
|
||||
|
||||
// Same class, everything is visible
|
||||
goTo.marker("1");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
goTo.marker("2");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
goTo.marker("3");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
// only public and protected methods of the base class are accessible through super
|
||||
goTo.marker("4");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.not.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
@@ -0,0 +1,45 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private static privateMethod() { }
|
||||
//// private static privateProperty;
|
||||
////
|
||||
//// protected static protectedMethod() { }
|
||||
//// protected static protectedProperty;
|
||||
////
|
||||
//// public static publicMethod() { }
|
||||
//// public static publicProperty;
|
||||
////
|
||||
//// protected static protectedOverriddenMethod() { }
|
||||
//// protected static protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
////class C3 extends Base {
|
||||
//// protected static protectedOverriddenMethod() { }
|
||||
//// protected static protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
////Base./*1*/;
|
||||
////C3./*2*/;
|
||||
|
||||
|
||||
// Only public properties are visible outside the class
|
||||
goTo.marker("1");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.not.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.not.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
goTo.marker("2");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.not.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.not.memberListContains('protectedOverriddenMethod');
|
||||
verify.not.memberListContains('protectedOverriddenProperty');
|
||||
@@ -0,0 +1,49 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Base {
|
||||
//// private static privateMethod() { }
|
||||
//// private static privateProperty;
|
||||
////
|
||||
//// protected static protectedMethod() { }
|
||||
//// protected static protectedProperty;
|
||||
////
|
||||
//// public static publicMethod() { }
|
||||
//// public static publicProperty;
|
||||
////
|
||||
//// protected static protectedOverriddenMethod() { }
|
||||
//// protected static protectedOverriddenProperty;
|
||||
////}
|
||||
////
|
||||
/////// Make the protected members public
|
||||
////class C4 extends Base {
|
||||
//// public static protectedOverriddenMethod() { }
|
||||
//// public static protectedOverriddenProperty;
|
||||
////}
|
||||
////class Derived extends C4 {
|
||||
//// test() {
|
||||
//// Derived./*1*/
|
||||
//// }
|
||||
////}
|
||||
//// Derived./*2*/
|
||||
|
||||
// Sub class, everything but private is visible
|
||||
goTo.marker("1");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.memberListContains('protectedMethod');
|
||||
verify.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
|
||||
// Can see protected methods elevated to public
|
||||
goTo.marker("2");
|
||||
verify.not.memberListContains('privateMethod');
|
||||
verify.not.memberListContains('privateProperty');
|
||||
verify.not.memberListContains('protectedMethod');
|
||||
verify.not.memberListContains('protectedProperty');
|
||||
verify.memberListContains('publicMethod');
|
||||
verify.memberListContains('publicProperty');
|
||||
verify.memberListContains('protectedOverriddenMethod');
|
||||
verify.memberListContains('protectedOverriddenProperty');
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
|
||||
goTo.marker();
|
||||
verify.memberListContains("publicProperty");
|
||||
verify.not.memberListContains("publicProperty");
|
||||
verify.memberListContains("publicInstanceMethod");
|
||||
// No statics
|
||||
verify.not.memberListContains("publicStaticProperty");
|
||||
|
||||
@@ -294,6 +294,10 @@ module FourSlashInterface {
|
||||
FourSlash.currentTestState.verifySignatureHelpCount(expected);
|
||||
}
|
||||
|
||||
public signatureHelpArgumentCountIs(expected: number) {
|
||||
FourSlash.currentTestState.verifySignatureHelpArgumentCount(expected);
|
||||
}
|
||||
|
||||
public currentSignatureParamterCountIs(expected: number) {
|
||||
FourSlash.currentTestState.verifyCurrentSignatureHelpParameterCount(expected);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////if/*1*/ (true) {
|
||||
//// if/*2*/ (false) {
|
||||
//// }
|
||||
//// else/*3*/ {
|
||||
//// }
|
||||
//// if/*4*/ (true) {
|
||||
//// }
|
||||
//// else/*5*/ {
|
||||
//// if/*6*/ (false)
|
||||
//// if/*7*/ (true)
|
||||
//// var x = undefined;
|
||||
//// }
|
||||
////}
|
||||
////else/*8*/ if (null) {
|
||||
////}
|
||||
////else/*9*/ /* whar garbl */ if/*10*/ (undefined) {
|
||||
////}
|
||||
////else/*11*/
|
||||
////if/*12*/ (false) {
|
||||
////}
|
||||
////else/*13*/ { }
|
||||
|
||||
function verifyOccurencesAtMarker(marker: string, count: number) {
|
||||
goTo.marker(marker);
|
||||
verify.occurrencesAtPositionCount(count);
|
||||
}
|
||||
|
||||
verifyOccurencesAtMarker("1", 7);
|
||||
verifyOccurencesAtMarker("2", 2);
|
||||
verifyOccurencesAtMarker("3", 2);
|
||||
verifyOccurencesAtMarker("4", 2);
|
||||
verifyOccurencesAtMarker("5", 2);
|
||||
verifyOccurencesAtMarker("6", 1);
|
||||
verifyOccurencesAtMarker("7", 1);
|
||||
verifyOccurencesAtMarker("8", 7);
|
||||
verifyOccurencesAtMarker("9", 7);
|
||||
verifyOccurencesAtMarker("10", 7);
|
||||
verifyOccurencesAtMarker("11", 7);
|
||||
verifyOccurencesAtMarker("12", 7);
|
||||
verifyOccurencesAtMarker("13", 7);
|
||||
@@ -1,29 +0,0 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////if/*1*/ (true) {
|
||||
//// if/*2*/ (false) {
|
||||
//// }
|
||||
//// else/*3*/ {
|
||||
//// }
|
||||
//// if/*4*/ (true) {
|
||||
//// }
|
||||
//// else/*5*/ {
|
||||
//// if/*6*/ (false)
|
||||
//// if/*7*/ (true)
|
||||
//// var x = undefined;
|
||||
//// }
|
||||
////}
|
||||
////else/*8*/ if (null) {
|
||||
////}
|
||||
////else/*9*/ /* whar garbl */ if/*10*/ (undefined) {
|
||||
////}
|
||||
////else/*11*/
|
||||
////if/*12*/ (false) {
|
||||
////}
|
||||
////else/*13*/ { }
|
||||
|
||||
|
||||
test.markers().forEach(m => {
|
||||
goTo.position(m.position, m.fileName)
|
||||
verify.occurrencesAtPositionCount(0);
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////var arr = [1, 2, 3, 4];
|
||||
////label1: for (var n in arr) {
|
||||
//// break;
|
||||
//// continue;
|
||||
//// break label1;
|
||||
//// continue label1;
|
||||
////
|
||||
//// label2: for (var i = 0; i < arr[n]; i++) {
|
||||
//// break label1;
|
||||
//// continue label1;
|
||||
////
|
||||
//// break;
|
||||
//// continue;
|
||||
//// break label2;
|
||||
//// continue label2;
|
||||
////
|
||||
//// function foo() {
|
||||
//// label3: while (true) {
|
||||
//// break;
|
||||
//// continue;
|
||||
//// break label3;
|
||||
//// continue label3;
|
||||
////
|
||||
//// // these cross function boundaries
|
||||
//// br/*1*/eak label1;
|
||||
//// cont/*2*/inue label1;
|
||||
//// bre/*3*/ak label2;
|
||||
//// c/*4*/ontinue label2;
|
||||
////
|
||||
//// label4: do {
|
||||
//// break;
|
||||
//// continue;
|
||||
//// break label4;
|
||||
//// continue label4;
|
||||
////
|
||||
//// break label3;
|
||||
//// continue label3;
|
||||
////
|
||||
//// switch (10) {
|
||||
//// case 1:
|
||||
//// case 2:
|
||||
//// break;
|
||||
//// break label4;
|
||||
//// default:
|
||||
//// continue;
|
||||
//// }
|
||||
////
|
||||
//// // these cross function boundaries
|
||||
//// br/*5*/eak label1;
|
||||
//// co/*6*/ntinue label1;
|
||||
//// br/*7*/eak label2;
|
||||
//// con/*8*/tinue label2;
|
||||
//// () => { b/*9*/reak; }
|
||||
//// } while (true)
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////label5: while (true) break label5;
|
||||
////
|
||||
////label7: while (true) co/*10*/ntinue label5;
|
||||
|
||||
test.markers().forEach(m => {
|
||||
goTo.position(m.position);
|
||||
|
||||
verify.occurrencesAtPositionCount(0);
|
||||
});
|
||||
+12
-4
@@ -19,7 +19,15 @@
|
||||
//// return/*7*/ true;
|
||||
////}
|
||||
|
||||
test.markers().forEach(m => {
|
||||
goTo.position(m.position, m.fileName)
|
||||
verify.occurrencesAtPositionCount(0);
|
||||
});
|
||||
function verifyOccurencesAtMarker(marker: string, count: number) {
|
||||
goTo.marker(marker);
|
||||
verify.occurrencesAtPositionCount(count);
|
||||
}
|
||||
|
||||
verifyOccurencesAtMarker("1", 4);
|
||||
verifyOccurencesAtMarker("2", 4);
|
||||
verifyOccurencesAtMarker("3", 4);
|
||||
verifyOccurencesAtMarker("4", 4);
|
||||
verifyOccurencesAtMarker("5", 1);
|
||||
verifyOccurencesAtMarker("6", 3);
|
||||
verifyOccurencesAtMarker("7", 3);
|
||||
@@ -0,0 +1,34 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class Foo {
|
||||
//// [|set|] bar(b: any) {
|
||||
//// }
|
||||
////
|
||||
//// public [|get|] bar(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////
|
||||
//// public set set(s: any) {
|
||||
//// }
|
||||
////
|
||||
//// public get set(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////
|
||||
//// public set get(g: any) {
|
||||
//// }
|
||||
////
|
||||
//// public get get(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class Foo {
|
||||
//// set bar(b: any) {
|
||||
//// }
|
||||
////
|
||||
//// public get bar(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////
|
||||
//// public [|set|] set(s: any) {
|
||||
//// }
|
||||
////
|
||||
//// public [|get|] set(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////
|
||||
//// public set get(g: any) {
|
||||
//// }
|
||||
////
|
||||
//// public get get(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class Foo {
|
||||
//// set bar(b: any) {
|
||||
//// }
|
||||
////
|
||||
//// public get bar(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////
|
||||
//// public set set(s: any) {
|
||||
//// }
|
||||
////
|
||||
//// public get set(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////
|
||||
//// public [|set|] get(g: any) {
|
||||
//// }
|
||||
////
|
||||
//// public [|get|] get(): any {
|
||||
//// return undefined;
|
||||
//// }
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////switch/*1*/ (10) {
|
||||
//// case/*2*/ 1:
|
||||
//// case/*3*/ 2:
|
||||
//// case/*4*/ 4:
|
||||
//// case/*5*/ 8:
|
||||
//// foo: switch/*6*/ (20) {
|
||||
//// case/*7*/ 1:
|
||||
//// case/*8*/ 2:
|
||||
//// break/*9*/;
|
||||
//// default/*10*/:
|
||||
//// break foo;
|
||||
//// }
|
||||
//// case/*11*/ 0xBEEF:
|
||||
//// default/*12*/:
|
||||
//// break/*13*/;
|
||||
//// case 16/*14*/:
|
||||
////}
|
||||
|
||||
function verifyOccurencesAtMarker(marker: string, count: number) {
|
||||
goTo.marker(marker);
|
||||
verify.occurrencesAtPositionCount(count);
|
||||
}
|
||||
|
||||
verifyOccurencesAtMarker("1", 9);
|
||||
verifyOccurencesAtMarker("2", 9);
|
||||
verifyOccurencesAtMarker("3", 9);
|
||||
verifyOccurencesAtMarker("4", 9);
|
||||
verifyOccurencesAtMarker("5", 9);
|
||||
verifyOccurencesAtMarker("6", 6);
|
||||
verifyOccurencesAtMarker("7", 6);
|
||||
verifyOccurencesAtMarker("8", 6);
|
||||
verifyOccurencesAtMarker("9", 6);
|
||||
verifyOccurencesAtMarker("10", 6);
|
||||
verifyOccurencesAtMarker("11", 9);
|
||||
verifyOccurencesAtMarker("12", 9);
|
||||
verifyOccurencesAtMarker("13", 9);
|
||||
verifyOccurencesAtMarker("14", 0);
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////switch/*1*/ (10) {
|
||||
//// case/*2*/ 1:
|
||||
//// case/*3*/ 2:
|
||||
//// case/*4*/ 4:
|
||||
//// case/*5*/ 8:
|
||||
//// foo: switch/*6*/ (20) {
|
||||
//// case/*7*/ 1:
|
||||
//// case/*8*/ 2:
|
||||
//// break/*9*/;
|
||||
//// default/*10*/:
|
||||
//// break foo;
|
||||
//// }
|
||||
//// case/*11*/ 0xBEEF:
|
||||
//// default/*12*/:
|
||||
//// break/*13*/;
|
||||
//// case 16/*14*/:
|
||||
////}
|
||||
|
||||
|
||||
for (var i = 1; i <= test.markers().length; i++) {
|
||||
goTo.marker("" + i);
|
||||
verify.occurrencesAtPositionCount(0);
|
||||
}
|
||||
+10
-4
@@ -142,8 +142,14 @@
|
||||
////}
|
||||
|
||||
|
||||
test.markers().forEach(m => {
|
||||
goTo.position(m.position, m.fileName)
|
||||
function verifyOccurencesAtMarker(marker: string, count: number) {
|
||||
goTo.marker(marker);
|
||||
verify.occurrencesAtPositionCount(count);
|
||||
}
|
||||
|
||||
verify.occurrencesAtPositionCount(0);
|
||||
});
|
||||
verifyOccurencesAtMarker("1", 2);
|
||||
verifyOccurencesAtMarker("2", 6);
|
||||
verifyOccurencesAtMarker("3", 1);
|
||||
verifyOccurencesAtMarker("4", 1);
|
||||
verifyOccurencesAtMarker("5", 1);
|
||||
verifyOccurencesAtMarker("6", 0);
|
||||
@@ -0,0 +1,58 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(a: number) {
|
||||
//// try {
|
||||
//// throw "Hello";
|
||||
////
|
||||
//// try {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// [|return|] 100;
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// [|throw|] "Something";
|
||||
//// }
|
||||
//// finally {
|
||||
//// [|throw|] "Also something";
|
||||
//// }
|
||||
//// if (a > 0) {
|
||||
//// [|return|] (function () {
|
||||
//// return;
|
||||
//// return;
|
||||
//// return;
|
||||
////
|
||||
//// if (false) {
|
||||
//// return true;
|
||||
//// }
|
||||
//// throw "Hello!";
|
||||
//// })() || true;
|
||||
//// }
|
||||
////
|
||||
//// [|th/**/row|] 10;
|
||||
////
|
||||
//// var unusued = [1, 2, 3, 4].map(x => { throw 4 })
|
||||
////
|
||||
//// [|return|];
|
||||
//// [|return|] true;
|
||||
//// [|throw|] false;
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
goTo.marker();
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(a: number) {
|
||||
//// try {
|
||||
//// throw "Hello";
|
||||
////
|
||||
//// try {
|
||||
//// [|t/**/hrow|] 10;
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// return 100;
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// throw "Something";
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw "Also something";
|
||||
//// }
|
||||
//// if (a > 0) {
|
||||
//// return (function () {
|
||||
//// return;
|
||||
//// return;
|
||||
//// return;
|
||||
////
|
||||
//// if (false) {
|
||||
//// return true;
|
||||
//// }
|
||||
//// throw "Hello!";
|
||||
//// })() || true;
|
||||
//// }
|
||||
////
|
||||
//// throw 10;
|
||||
////
|
||||
//// var unusued = [1, 2, 3, 4].map(x => { throw 4 })
|
||||
////
|
||||
//// return;
|
||||
//// return true;
|
||||
//// throw false;
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
goTo.marker();
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(a: number) {
|
||||
//// try {
|
||||
//// [|throw|] "Hello";
|
||||
////
|
||||
//// try {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// return 100;
|
||||
//// }
|
||||
//// finally {
|
||||
//// [|thr/**/ow|] 10;
|
||||
//// }
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// throw "Something";
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw "Also something";
|
||||
//// }
|
||||
//// if (a > 0) {
|
||||
//// return (function () {
|
||||
//// return;
|
||||
//// return;
|
||||
//// return;
|
||||
////
|
||||
//// if (false) {
|
||||
//// return true;
|
||||
//// }
|
||||
//// throw "Hello!";
|
||||
//// })() || true;
|
||||
//// }
|
||||
////
|
||||
//// throw 10;
|
||||
////
|
||||
//// var unusued = [1, 2, 3, 4].map(x => { throw 4 })
|
||||
////
|
||||
//// return;
|
||||
//// return true;
|
||||
//// throw false;
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
goTo.marker();
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(a: number) {
|
||||
//// try {
|
||||
//// throw "Hello";
|
||||
////
|
||||
//// try {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// return 100;
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// throw "Something";
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw "Also something";
|
||||
//// }
|
||||
//// if (a > 0) {
|
||||
//// return (function () {
|
||||
//// [|return|];
|
||||
//// [|return|];
|
||||
//// [|return|];
|
||||
////
|
||||
//// if (false) {
|
||||
//// [|return|] true;
|
||||
//// }
|
||||
//// [|th/**/row|] "Hello!";
|
||||
//// })() || true;
|
||||
//// }
|
||||
////
|
||||
//// throw 10;
|
||||
////
|
||||
//// var unusued = [1, 2, 3, 4].map(x => { throw 4 })
|
||||
////
|
||||
//// return;
|
||||
//// return true;
|
||||
//// throw false;
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
goTo.marker();
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(a: number) {
|
||||
//// try {
|
||||
//// throw "Hello";
|
||||
////
|
||||
//// try {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// return 100;
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// throw "Something";
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw "Also something";
|
||||
//// }
|
||||
//// if (a > 0) {
|
||||
//// return (function () {
|
||||
//// return;
|
||||
//// return;
|
||||
//// return;
|
||||
////
|
||||
//// if (false) {
|
||||
//// return true;
|
||||
//// }
|
||||
//// throw "Hello!";
|
||||
//// })() || true;
|
||||
//// }
|
||||
////
|
||||
//// throw 10;
|
||||
////
|
||||
//// var unusued = [1, 2, 3, 4].map(x => { [|thr/**/ow|] 4 })
|
||||
////
|
||||
//// return;
|
||||
//// return true;
|
||||
//// throw false;
|
||||
////}
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
goTo.marker();
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////[|throw|] 100;
|
||||
////
|
||||
////try {
|
||||
//// throw 0;
|
||||
//// var x = () => { throw 0; };
|
||||
////}
|
||||
////catch (y) {
|
||||
//// var x = () => { throw 0; };
|
||||
//// [|throw|] 200;
|
||||
////}
|
||||
////finally {
|
||||
//// [|throw|] 300;
|
||||
////}
|
||||
|
||||
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////try {
|
||||
//// [|throw|] 10;
|
||||
////
|
||||
//// try {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// [|throw|] 10;
|
||||
//// }
|
||||
//// finally {
|
||||
//// [|throw|] 10;
|
||||
//// }
|
||||
////}
|
||||
////finally {
|
||||
//// [|throw|] 10;
|
||||
////}
|
||||
////
|
||||
////[|throw|] 10;
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////try {
|
||||
//// throw 10;
|
||||
////
|
||||
//// try {
|
||||
//// [|throw|] 10;
|
||||
//// }
|
||||
//// catch (x) {
|
||||
//// throw 10;
|
||||
//// }
|
||||
//// finally {
|
||||
//// throw 10;
|
||||
//// }
|
||||
////}
|
||||
////finally {
|
||||
//// throw 10;
|
||||
////}
|
||||
////
|
||||
////throw 10;
|
||||
|
||||
test.ranges().forEach(r => {
|
||||
goTo.position(r.start);
|
||||
|
||||
test.ranges().forEach(range => {
|
||||
verify.occurrencesAtPositionContains(range, false);
|
||||
});
|
||||
|
||||
verify.occurrencesAtPositionCount(test.ranges().length);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////try/*1*/ {
|
||||
//// try/*2*/ {
|
||||
//// }
|
||||
//// catch/*3*/ (x) {
|
||||
//// }
|
||||
////
|
||||
//// try/*4*/ {
|
||||
//// }
|
||||
//// finally/*5*/ {/*8*/
|
||||
//// }
|
||||
////}
|
||||
////catch/*6*/ (e) {
|
||||
////}
|
||||
////finally/*7*/ {
|
||||
////}
|
||||
function verifyOccurencesAtMarker(marker: string, count: number) {
|
||||
goTo.marker(marker);
|
||||
verify.occurrencesAtPositionCount(count);
|
||||
}
|
||||
|
||||
verifyOccurencesAtMarker("1", 3);
|
||||
verifyOccurencesAtMarker("2", 2);
|
||||
verifyOccurencesAtMarker("3", 2);
|
||||
verifyOccurencesAtMarker("4", 2);
|
||||
verifyOccurencesAtMarker("5", 2);
|
||||
verifyOccurencesAtMarker("6", 3);
|
||||
verifyOccurencesAtMarker("7", 3);
|
||||
verifyOccurencesAtMarker("8", 0);
|
||||
@@ -1,23 +0,0 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////try/*1*/ {
|
||||
//// try/*2*/ {
|
||||
//// }
|
||||
//// catch/*3*/ (x) {
|
||||
//// }
|
||||
////
|
||||
//// try/*4*/ {
|
||||
//// }
|
||||
//// finally/*5*/ {/*8*/
|
||||
//// }
|
||||
////}
|
||||
////catch/*6*/ (e) {
|
||||
////}
|
||||
////finally/*7*/ {
|
||||
////}
|
||||
|
||||
|
||||
for (var i = 1; i <= test.markers().length; i++) {
|
||||
goTo.marker("" + i);
|
||||
verify.occurrencesAtPositionCount(0);
|
||||
}
|
||||
@@ -5,7 +5,12 @@
|
||||
|
||||
// @Filename: Consumption.ts
|
||||
//// var n = new /*1*/c();
|
||||
//// var n = new c/*3*/();
|
||||
|
||||
goTo.marker('1');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('2');
|
||||
|
||||
goTo.marker('3');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('2');
|
||||
|
||||
@@ -13,6 +13,6 @@ verify.currentParameterSpanIs("x: string");
|
||||
edit.insert("'',");
|
||||
|
||||
verify.signatureHelpCountIs(2);
|
||||
// verify.currentSignatureHelpIs("fn(x: string, y: number): any");
|
||||
// verify.currentParameterHelpArgumentNameIs("y");
|
||||
// verify.currentParameterSpanIs("y: number");
|
||||
verify.currentSignatureHelpIs("fn(x: string, y: number): any");
|
||||
verify.currentParameterHelpArgumentNameIs("y");
|
||||
verify.currentParameterSpanIs("y: number");
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////declare function f(s: string);
|
||||
////declare function f(n: number);
|
||||
////declare function f(s: string, b: boolean);
|
||||
////declare function f(n: number, b: boolean);
|
||||
////
|
||||
////f(1/**/
|
||||
|
||||
goTo.marker();
|
||||
verify.signatureHelpCountIs(4);
|
||||
verify.currentSignatureHelpIs("f(n: number): any");
|
||||
verify.currentParameterHelpArgumentNameIs("n");
|
||||
verify.currentParameterSpanIs("n: number");
|
||||
|
||||
edit.insert(", ");
|
||||
verify.signatureHelpCountIs(4);
|
||||
verify.currentSignatureHelpIs("f(n: number, b: boolean): any");
|
||||
verify.currentParameterHelpArgumentNameIs("b");
|
||||
verify.currentParameterSpanIs("b: boolean");
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////declare function f(s: string);
|
||||
////declare function f(n: number);
|
||||
////declare function f(s: string, b: boolean);
|
||||
////declare function f(n: number, b: boolean);
|
||||
////
|
||||
////f(1/**/ var
|
||||
|
||||
goTo.marker();
|
||||
verify.signatureHelpCountIs(4);
|
||||
verify.currentSignatureHelpIs("f(n: number): any");
|
||||
verify.currentParameterHelpArgumentNameIs("n");
|
||||
verify.currentParameterSpanIs("n: number");
|
||||
|
||||
edit.insert(", ");
|
||||
verify.signatureHelpCountIs(4);
|
||||
verify.currentSignatureHelpIs("f(n: number, b: boolean): any");
|
||||
verify.currentParameterHelpArgumentNameIs("b");
|
||||
verify.currentParameterSpanIs("b: boolean");
|
||||
@@ -0,0 +1,26 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////declare function f();
|
||||
////declare function f(s: string);
|
||||
////declare function f(s: string, b: boolean);
|
||||
////declare function f(n: number, b: boolean);
|
||||
////
|
||||
////f(/**/
|
||||
|
||||
goTo.marker();
|
||||
verify.signatureHelpCountIs(4);
|
||||
verify.currentSignatureHelpIs("f(): any");
|
||||
verify.currentSignatureParamterCountIs(0);
|
||||
verify.signatureHelpArgumentCountIs(0);
|
||||
|
||||
edit.insert(", ");
|
||||
verify.signatureHelpCountIs(4);
|
||||
verify.currentSignatureHelpIs("f(s: string, b: boolean): any");
|
||||
verify.currentSignatureParamterCountIs(2);
|
||||
verify.currentParameterHelpArgumentNameIs("b");
|
||||
verify.currentParameterSpanIs("b: boolean");
|
||||
|
||||
edit.insert(", ");
|
||||
verify.signatureHelpCountIs(4);
|
||||
verify.currentSignatureHelpIs("f(s: string, b: boolean): any");
|
||||
verify.currentSignatureParamterCountIs(2);
|
||||
@@ -217,5 +217,19 @@ describe('Colorization', function () {
|
||||
keyword("var"),
|
||||
finalEndOfLineState(ts.EndOfLineState.Start));
|
||||
});
|
||||
|
||||
it("classifies multiple keywords properly", function () {
|
||||
test("public static",
|
||||
ts.EndOfLineState.Start,
|
||||
keyword("public"),
|
||||
keyword("static"),
|
||||
finalEndOfLineState(ts.EndOfLineState.Start));
|
||||
|
||||
test("public var",
|
||||
ts.EndOfLineState.Start,
|
||||
keyword("public"),
|
||||
identifier("var"),
|
||||
finalEndOfLineState(ts.EndOfLineState.Start));
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user