This commit is contained in:
Yui T
2014-09-29 16:53:58 -07:00
17 changed files with 148 additions and 82 deletions
+1
View File
@@ -36,4 +36,5 @@ tests/*.d.ts
*.config
scripts/debug.bat
scripts/run.bat
scripts/word2md.js
coverage/
+34
View File
@@ -2,6 +2,7 @@
var fs = require("fs");
var path = require("path");
var child_process = require("child_process");
// Variables
var compilerDirectory = "src/compiler/";
@@ -9,6 +10,7 @@ var servicesDirectory = "src/services/";
var harnessDirectory = "src/harness/";
var libraryDirectory = "src/lib/";
var scriptsDirectory = "scripts/";
var docDirectory = "doc/";
var builtDirectory = "built/";
var builtLocalDirectory = "built/local/";
@@ -260,6 +262,38 @@ task("clean", function() {
jake.rmRf(builtDirectory);
});
// Generate Markdown spec
var word2mdJs = path.join(scriptsDirectory, "word2md.js");
var word2mdTs = path.join(scriptsDirectory, "word2md.ts");
var specWord = path.join(docDirectory, "TypeScript Language Specification.docx");
var specMd = path.join(docDirectory, "spec.md");
var headerMd = path.join(docDirectory, "header.md");
file(word2mdTs);
// word2md script
compileFile(word2mdJs,
[word2mdTs],
[word2mdTs],
[],
false);
// The generated spec.md; built for the 'generate-spec' task
file(specMd, [word2mdJs, specWord], function () {
jake.cpR(headerMd, specMd, {silent: true});
var specWordFullPath = path.resolve(specWord);
var cmd = "cscript //nologo " + word2mdJs + ' "' + specWordFullPath + '" >>' + specMd;
console.log(cmd);
child_process.exec(cmd, function () {
complete();
});
}, {async: true})
desc("Generates a Markdown version of the Language Specification");
task("generate-spec", [specMd])
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
desc("Makes a new LKG out of the built js files");
task("LKG", libraryTargets, function() {
Binary file not shown.
+14 -14
View File
@@ -102,9 +102,9 @@ TypeScript is a trademark of Microsoft Corporation.
* [4.14.5 The void Operator](#4.14.5)
* [4.14.6 The typeof Operator](#4.14.6)
* [4.15 Binary Operators](#4.15)
* [4.15.1 The *, /, %, , <<, >>, >>>, &, ^, and | operators](#4.15.1)
* [4.15.1 The *, /, %, , &lt;&lt;, >>, >>>, &, ^, and | operators](#4.15.1)
* [4.15.2 The + operator](#4.15.2)
* [4.15.3 The <, >, <=, >=, ==, !=, ===, and !== operators](#4.15.3)
* [4.15.3 The &lt;, >, &lt;=, >=, ==, !=, ===, and !== operators](#4.15.3)
* [4.15.4 The instanceof operator](#4.15.4)
* [4.15.5 The in operator](#4.15.5)
* [4.15.6 The && operator](#4.15.6)
@@ -1088,7 +1088,7 @@ Since a type parameter represents a multitude of different type arguments, type
### <a name="3.4.1"/>3.4.1 Type Parameter Lists
Class, interface, and function declarations may optionally include lists of type parameters enclosed in < and > brackets. Type parameters are also permitted in call signatures of object, function, and constructor type literals.
Class, interface, and function declarations may optionally include lists of type parameters enclosed in &lt; and > brackets. Type parameters are also permitted in call signatures of object, function, and constructor type literals.
&emsp;&emsp;*TypeParameters:*
&emsp;&emsp;&emsp;`<`&emsp;*TypeParameterList*&emsp;`>`
@@ -1149,7 +1149,7 @@ Given the declaration
interface G<T, U extends Function> { }
```
a type reference of the form G<A, B> places no requirements on A but requires B to be assignable to Function.
a type reference of the form G&lt;A, B> places no requirements on A but requires B to be assignable to Function.
The process of substituting type arguments for type parameters in a generic type or generic signature is known as ***instantiating*** the generic type or signature. Instantiation of a generic type or signature can fail if the supplied type arguments do not satisfy the constraints of their corresponding type parameters.
@@ -1354,13 +1354,13 @@ Object type literals are the primary form of type literals and are described in
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 A*rrayType* 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
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&lt;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
denotes a function returning a string array, not an array of functions returning string. The latter can be expressed using Array&lt;T> notation
```TypeScript
Array<() => string>
@@ -1833,7 +1833,7 @@ interface List<T> {
}
```
List<T> has a member owner of type List<List<T>>, which has a member owner of type List<List<List<T>>>, which has a member owner of type List<List<List<List<T>>>> and so on, ad infinitum. Since type relationships are determined structurally, possibly exploring the constituent types to their full depth, in order to determine type relationships involving infinitely expanding generic types it may be necessary for the compiler to terminate the recursion at some point with the assumption that no further exploration will change the outcome.
List&lt;T> has a member owner of type List&lt;List&lt;T>>, which has a member owner of type List&lt;List&lt;List&lt;T>>>, which has a member owner of type List&lt;List&lt;List&lt;List&lt;T>>>> and so on, ad infinitum. Since type relationships are determined structurally, possibly exploring the constituent types to their full depth, in order to determine type relationships involving infinitely expanding generic types it may be necessary for the compiler to terminate the recursion at some point with the assumption that no further exploration will change the outcome.
## <a name="3.9"/>3.9 Widened Types
@@ -2247,7 +2247,7 @@ A signature is said to be an ***applicable signature*** with respect to an argum
### <a name="4.12.2"/>4.12.2 Type Argument Inference
Given a signature < *T<sub>1</sub>* , *T<sub>2</sub>* , … , *T<sub>n</sub>* > ( *p<sub>1</sub>* : *P<sub>1</sub>* , *p<sub>2</sub>* : *P<sub>2</sub>* , … , *p<sub>m</sub>* : *P<sub>m</sub>* ), where each parameter type *P* references zero or more of the type parameters *T*, and an argument list ( *e<sub>1</sub>* , *e<sub>2</sub>* , … , *e<sub>m</sub>* ), the task of type argument inference is to find a set of type arguments *A<sub>1</sub>*…*A<sub>n</sub>* to substitute for *T<sub>1</sub>*…*T<sub>n</sub>* such that the argument list becomes an applicable signature.
Given a signature &lt; *T<sub>1</sub>* , *T<sub>2</sub>* , … , *T<sub>n</sub>* > ( *p<sub>1</sub>* : *P<sub>1</sub>* , *p<sub>2</sub>* : *P<sub>2</sub>* , … , *p<sub>m</sub>* : *P<sub>m</sub>* ), where each parameter type *P* references zero or more of the type parameters *T*, and an argument list ( *e<sub>1</sub>* , *e<sub>2</sub>* , … , *e<sub>m</sub>* ), the task of type argument inference is to find a set of type arguments *A<sub>1</sub>*…*A<sub>n</sub>* to substitute for *T<sub>1</sub>*…*T<sub>n</sub>* such that the argument list becomes an applicable signature.
The inferred type argument for a particular type parameter is determined from a set of candidate types. Given a type parameter *T*, let *C* denote the widened form (section [3.9](#3.9)) of the best common type (section [3.10](#3.10)) of the set of candidate types *T*. Then,
@@ -2337,7 +2337,7 @@ The inclusion of type arguments in the *Arguments* production (section [4.12](#4
f(g<A, B>(7));
```
could be interpreted as a call to f with two arguments, g < A and B > (7). Alternatively, it could be interpreted as a call to f with one argument, which is a call to a generic function g with two type arguments and one regular argument.
could be interpreted as a call to f with two arguments, g &lt; A and B > (7). Alternatively, it could be interpreted as a call to f with one argument, which is a call to a generic function g with two type arguments and one regular argument.
The grammar ambiguity is resolved as follows: In a context where one possible interpretation of a sequence of tokens is an *Arguments* production, if the initial sequence of tokens forms a syntactically correct *TypeArguments* production and is followed by a `(` token, then the sequence of tokens is processed an *Arguments* production, and any other possible interpretation is discarded. Otherwise, the sequence of tokens is not considered an *Arguments* production.
@@ -2449,7 +2449,7 @@ In the example above,
The subsections that follow specify the compile-time processing rules of the binary operators. In general, if the operands of a binary operator do not meet the stated requirements, a compile-time error occurs and the result of the operation defaults to type any in further processing. Tables that summarize the compile-time processing rules for operands of the Any type, the Boolean, Number, and String primitive types, and all object types and type parameters (the Object column in the tables) are provided.
### <a name="4.15.1"/>4.15.1 The *, /, %, , <<, >>, >>>, &, ^, and | operators
### <a name="4.15.1"/>4.15.1 The *, /, %, , &lt;&lt;, >>, >>>, &, ^, 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.
@@ -2483,7 +2483,7 @@ var s = getValue() + "";
The example above converts the result of getValue() to a string if it isnt a string already. The type inferred for s is the String primitive type regardless of the return type of getValue.
### <a name="4.15.3"/>4.15.3 The <, >, <=, >=, ==, !=, ===, and !== operators
### <a name="4.15.3"/>4.15.3 The &lt;, >, &lt;=, >=, ==, !=, ===, and !== operators
These operators require one operand type to be identical to or a subtype of the other operand type. The result is always of the Boolean primitive type.
@@ -4398,7 +4398,7 @@ The source elements permitted in a TypeScript implementation source file are a s
Declaration source files are restricted to contain declarations only. Declaration source files can be used to declare the static type information associated with existing JavaScript code in an adjunct manner. They are entirely optional but enable the TypeScript compiler and tools to provide better verification and assistance when integrating existing JavaScript code and libraries in a TypeScript application.
Implementation and declaration source files that contain no import or export declarations form the single ***global module***. Entities declared in the global module are in scope everywhere in a program. Initialization order of the source files that make up the global module ultimately depends on the order in which the generated JavaScript files are loaded at run-time (which, for example, may be controlled by <script/> tags that reference the generated JavaScript files).
Implementation and declaration source files that contain no import or export declarations form the single ***global module***. Entities declared in the global module are in scope everywhere in a program. Initialization order of the source files that make up the global module ultimately depends on the order in which the generated JavaScript files are loaded at run-time (which, for example, may be controlled by &lt;script/> tags that reference the generated JavaScript files).
Implementation and declaration source files that contain at least one external import declaration, export assignment, or top-level exported declaration are considered separate ***external modules***. Entities declared in an external module are in scope only in that module, but exported entities can be imported into other modules using import declarations. Initialization order of external modules is determined by the module loader being and is not specified by the TypeScript language. However, it is generally the case that non-circularly dependent modules are automatically loaded and initialized in the correct order.
@@ -4408,7 +4408,7 @@ External modules can additionally be declared using *AmbientExternalModuleDeclar
The TypeScript compiler automatically determines a source files dependencies and includes those dependencies in the program being compiled. The determination is made from “reference comments” and external import declarations as follows:
* A comment of the form /// <reference path="…"/> adds a dependency on the source file specified in the path argument. The path is resolved relative to the directory of the containing source file.
* A comment of the form /// &lt;reference path="…"/> adds a dependency on the source file specified in the path argument. The path is resolved relative to the directory of the containing source file.
* An external import declaration that specifies a relative external module name (section [11.2.1](#11.2.1)) resolves the name relative to the directory of the containing source file. If a source file with the resulting path and file extension .ts exists, that file is added as a dependency. Otherwise, if a source file with the resulting path and file extension .d.ts exists, that file is added as a dependency.
* An external import declaration that specifies a top-level external module name (section [11.2.1](#11.2.1)) resolves the name in a host dependent manner (typically by resolving the name relative to a module name space root or searching for the name in a series of directories). If a source file with extension .ts or .d.ts corresponding to the reference is located, that file is added as a dependency.
@@ -4619,7 +4619,7 @@ The special
# <a name="12"/>12 Ambients
Ambient declarations are used to provide static typing over existing JavaScript code. Ambient declarations differ from regular declarations in that no JavaScript code is emitted for them. Instead of introducing new variables, functions, classes, enums, or modules, ambient declarations provide type information for entities that exist “ambiently” and are included in a program by external means, for example by referencing a JavaScript library in a <script/> tag.
Ambient declarations are used to provide static typing over existing JavaScript code. Ambient declarations differ from regular declarations in that no JavaScript code is emitted for them. Instead of introducing new variables, functions, classes, enums, or modules, ambient declarations provide type information for entities that exist “ambiently” and are included in a program by external means, for example by referencing a JavaScript library in a &lt;script/> tag.
## <a name="12.1"/>12.1 Ambient Declarations
+10 -14
View File
@@ -1,11 +1,3 @@
// word2md - Word to Markdown conversion tool
//
// word2md converts a Microsoft Word document to Markdown formatted text. The tool uses the
// Word Automation APIs to start an instance of Word and access the contents of the document
// being converted. The tool must be run using the cscript.exe script host and requires Word
// to be installed on the target machine. The name of the document to convert must be specified
// as a command line argument and the resulting Markdown is written to standard output. The
// tool recognizes the specific Word styles used in the TypeScript Language Specification.
var sys = (function () {
var args = [];
for (var i = 0; i < WScript.Arguments.length; i++) {
@@ -37,13 +29,13 @@ function convertDocumentToMarkdown(doc) {
}
}
}
function findReplace(findText, findProps, replaceText, replaceProps) {
function findReplace(findText, findOptions, replaceText, replaceOptions) {
var find = doc.range().find;
find.clearFormatting();
setProperties(find, findProps);
setProperties(find, findOptions);
var replace = find.replacement;
replace.clearFormatting();
setProperties(replace, replaceProps);
setProperties(replace, replaceOptions);
find.execute(findText, false, false, false, false, false, true, 0, true, replaceText, 2);
}
function write(s) {
@@ -162,10 +154,14 @@ function convertDocumentToMarkdown(doc) {
}
writeBlockEnd();
}
findReplace("<", {}, "&lt;", {});
findReplace("&lt;", { style: "Code" }, "<", {});
findReplace("&lt;", { style: "Code Fragment" }, "<", {});
findReplace("&lt;", { style: "Terminal" }, "<", {});
findReplace("", { font: { subscript: true } }, "<sub>^&</sub>", { font: { subscript: false } });
findReplace("", { style: "Code Fragment" }, "`^&`", { style: -66 /* default font */ });
findReplace("", { style: "Production" }, "*^&*", { style: -66 /* default font */ });
findReplace("", { style: "Terminal" }, "`^&`", { style: -66 /* default font */ });
findReplace("", { style: "Code Fragment" }, "`^&`", { style: -66 });
findReplace("", { style: "Production" }, "*^&*", { style: -66 });
findReplace("", { style: "Terminal" }, "`^&`", { style: -66 });
findReplace("", { font: { bold: true, italic: true } }, "***^&***", { font: { bold: false, italic: false } });
findReplace("", { font: { italic: true } }, "*^&*", { font: { italic: false } });
doc.fields.toggleShowCodes();
+18 -5
View File
@@ -97,7 +97,7 @@ module Word {
}
export interface Fields extends Collection<Field> {
toggleShowCodes();
toggleShowCodes(): void;
}
export interface Document {
@@ -129,6 +129,15 @@ var sys = (function () {
};
})();
interface FindReplaceOptions {
style?: any;
font?: {
bold?: boolean;
italic?: boolean;
subscript?: boolean;
};
}
function convertDocumentToMarkdown(doc: Word.Document): string {
var result: string = "";
@@ -138,7 +147,7 @@ function convertDocumentToMarkdown(doc: Word.Document): string {
var tableCellIndex: number;
var columnAlignment: number[] = [];
function setProperties(target: {}, properties: {}) {
function setProperties(target: any, properties: any) {
for (var name in properties) {
if (properties.hasOwnProperty(name)) {
var value = properties[name];
@@ -152,13 +161,13 @@ function convertDocumentToMarkdown(doc: Word.Document): string {
}
}
function findReplace(findText: string, findProps: {}, replaceText: string, replaceProps: {}) {
function findReplace(findText: string, findOptions: FindReplaceOptions, replaceText: string, replaceOptions: FindReplaceOptions) {
var find = doc.range().find;
find.clearFormatting();
setProperties(find, findProps);
setProperties(find, findOptions);
var replace = find.replacement;
replace.clearFormatting();
setProperties(replace, replaceProps);
setProperties(replace, replaceOptions);
find.execute(findText, false, false, false, false, false, true, 0, true, replaceText, 2);
}
@@ -295,6 +304,10 @@ function convertDocumentToMarkdown(doc: Word.Document): string {
writeBlockEnd();
}
findReplace("<", {}, "&lt;", {});
findReplace("&lt;", { style: "Code" }, "<", {});
findReplace("&lt;", { style: "Code Fragment" }, "<", {});
findReplace("&lt;", { style: "Terminal" }, "<", {});
findReplace("", { font: { subscript: true } }, "<sub>^&</sub>", { font: { subscript: false } });
findReplace("", { style: "Code Fragment" }, "`^&`", { style: -66 /* default font */ });
findReplace("", { style: "Production" }, "*^&*", { style: -66 /* default font */});
+4
View File
@@ -648,6 +648,10 @@ module ts {
return SyntaxKind.FirstKeyword <= token && token <= SyntaxKind.LastKeyword;
}
export function isTrivia(token: SyntaxKind) {
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
}
export function isModifier(token: SyntaxKind): boolean {
switch (token) {
case SyntaxKind.PublicKeyword:
+2 -3
View File
@@ -959,10 +959,9 @@ module FourSlash {
var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
var item = help.items[help.selectedItemIndex];
var state = this.languageService.getSignatureHelpCurrentArgumentState(this.activeFile.fileName, this.currentCaretPosition, help.applicableSpan.start());
// Same logic as in getActiveSignatureHelp - this value might be -1 until a parameter value actually gets typed
var currentParam = state === undefined ? 0 : state.argumentIndex;
var currentParam = help.argumentIndex < 0 ? 0 : help.argumentIndex;
return item.parameters[currentParam];
}
+1 -1
View File
@@ -7,7 +7,7 @@ class UnitTestRunner extends RunnerBase {
}
public initializeTests() {
this.tests = this.enumerateFiles('tests/cases/unittests/services');
this.tests = this.enumerateFiles('tests/cases/unittests/services', /\.ts/i);
var outfile = new Harness.Compiler.WriterAggregator()
var outerr = new Harness.Compiler.WriterAggregator();
+2 -2
View File
@@ -174,7 +174,7 @@ module ts.formatting {
function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: Node, childStartLine: number, sourceFile: SourceFile): boolean {
if (parent.kind === SyntaxKind.IfStatement && (<IfStatement>parent).elseStatement === child) {
var elseKeyword = forEach(parent.getChildren(), c => c.kind === SyntaxKind.ElseKeyword && c);
var elseKeyword = findChildOfKind(parent, SyntaxKind.ElseKeyword, sourceFile);
Debug.assert(elseKeyword);
var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
@@ -383,7 +383,7 @@ module ts.formatting {
return isCompletedNode((<WhileStatement>n).statement, sourceFile);
case SyntaxKind.DoStatement:
// rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
var hasWhileKeyword = forEach(n.getChildren(), c => c.kind === SyntaxKind.WhileKeyword && c);
var hasWhileKeyword = findChildOfKind(n, SyntaxKind.WhileKeyword, sourceFile);
if(hasWhileKeyword) {
return nodeEndsWith(n, SyntaxKind.CloseParenToken, sourceFile);
}
+10 -4
View File
@@ -60,18 +60,24 @@ module ts {
case SyntaxKind.TryBlock:
case SyntaxKind.CatchBlock:
case SyntaxKind.FinallyBlock:
var openBrace = forEach(n.getChildren(), c => c.kind === SyntaxKind.OpenBraceToken && c);
var closeBrace = forEach(n.getChildren(), c => c.kind === SyntaxKind.CloseBraceToken && c);
var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
addOutlineRange(n.parent, openBrace, closeBrace);
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.ObjectLiteral:
var openBrace = forEach(n.getChildren(), c => c.kind === SyntaxKind.OpenBraceToken && c);
var closeBrace = forEach(n.getChildren(), c => c.kind === SyntaxKind.CloseBraceToken && c);
case SyntaxKind.SwitchStatement:
var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
addOutlineRange(n, openBrace, closeBrace);
break;
case SyntaxKind.ArrayLiteral:
var openBracket = findChildOfKind(n, SyntaxKind.OpenBracketToken, sourceFile);
var closeBracket = findChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile);
addOutlineRange(n, openBracket, closeBracket);
break;
}
depth++;
forEachChild(n, walk);
+16 -27
View File
@@ -651,16 +651,18 @@ module ts {
getCompletionsAtPosition(fileName: string, position: number, isMemberCompletion: boolean): CompletionInfo;
getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails;
getTypeAtPosition(fileName: string, position: number): TypeInfo;
getQuickInfoAtPosition(fileName: string, position: number): QuickInfo;
// Obsolete. Use getQuickInfoAtPosition instead.
getTypeAtPosition(fileName: string, position: number): TypeInfo;
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TypeScript.TextSpan;
getBreakpointStatementAtPosition(fileName: string, position: number): TypeScript.TextSpan;
getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems;
getSignatureHelpCurrentArgumentState(fileName: string, position: number, applicableSpanStart: number): SignatureHelpState;
// Obsolete. Use getSignatureHelpItems instead.
getSignatureAtPosition(fileName: string, position: number): SignatureInfo;
getRenameInfo(fileName: string, position: number): RenameInfo;
@@ -861,9 +863,6 @@ module ts {
items: SignatureHelpItem[];
applicableSpan: TypeScript.TextSpan;
selectedItemIndex: number;
}
export interface SignatureHelpState {
argumentIndex: number;
argumentCount: number;
}
@@ -1032,6 +1031,7 @@ module ts {
static none = "";
static publicMemberModifier = "public";
static privateMemberModifier = "private";
static protectedMemberModifier = "protected";
static exportedModifier = "export";
static ambientModifier = "declare";
static staticModifier = "static";
@@ -2354,6 +2354,7 @@ module ts {
var result: string[] = [];
if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier);
if (flags & NodeFlags.Protected) result.push(ScriptElementKindModifier.protectedMemberModifier);
if (flags & NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier);
if (flags & NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
if (flags & NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
@@ -3765,16 +3766,6 @@ module ts {
return SignatureHelp.getSignatureHelpItems(sourceFile, position, typeInfoResolver, cancellationToken);
}
/**
* This is a syntactic operation
*/
function getSignatureHelpCurrentArgumentState(fileName: string, position: number, applicableSpanStart: number): SignatureHelpState {
fileName = TypeScript.switchToForwardSlashes(fileName);
var sourceFile = getCurrentSourceFile(fileName);
return SignatureHelp.getSignatureHelpCurrentArgumentState(sourceFile, position, applicableSpanStart);
}
function getSignatureAtPosition(filename: string, position: number): SignatureInfo {
var signatureHelpItems = getSignatureHelpItems(filename, position);
@@ -3782,7 +3773,7 @@ module ts {
return undefined;
}
var currentArguemntState = getSignatureHelpCurrentArgumentState(filename, position, signatureHelpItems.applicableSpan.start());
var currentArgumentState = { argumentIndex: signatureHelpItems.argumentIndex, argumentCount: signatureHelpItems.argumentCount };
var formalSignatures: FormalSignatureItemInfo[] = [];
forEach(signatureHelpItems.items, signature => {
@@ -3827,7 +3818,7 @@ module ts {
parameterMinChar: signatureHelpItems.applicableSpan.start(),
parameterLimChar: signatureHelpItems.applicableSpan.end(),
currentParameterIsTypeParameter: false,
currentParameter: currentArguemntState.argumentIndex
currentParameter: currentArgumentState.argumentIndex
};
return {
@@ -4465,7 +4456,6 @@ module ts {
getCompletionEntryDetails: getCompletionEntryDetails,
getTypeAtPosition: getTypeAtPosition,
getSignatureHelpItems: getSignatureHelpItems,
getSignatureHelpCurrentArgumentState: getSignatureHelpCurrentArgumentState,
getQuickInfoAtPosition: getQuickInfoAtPosition,
getDefinitionAtPosition: getDefinitionAtPosition,
getReferencesAtPosition: getReferencesAtPosition,
@@ -4550,17 +4540,16 @@ module ts {
do {
token = scanner.scan();
if ((token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) && !noRegexTable[lastNonTriviaToken]) {
if (scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
token = SyntaxKind.RegularExpressionLiteral;
if (!isTrivia(token)) {
if ((token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) && !noRegexTable[lastNonTriviaToken]) {
if (scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
token = SyntaxKind.RegularExpressionLiteral;
}
}
else if (lastNonTriviaToken === SyntaxKind.DotToken && isKeyword(token)) {
token = SyntaxKind.Identifier;
}
}
else if (lastNonTriviaToken === SyntaxKind.DotToken) {
token = SyntaxKind.Identifier;
}
// Only recall the token if it was *not* trivia.
if (!(SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken)) {
lastNonTriviaToken = token;
}
+3 -10
View File
@@ -84,14 +84,16 @@ module ts {
getCompletionEntryDetails(fileName: string, position: number, entryName: string): string;
getQuickInfoAtPosition(fileName: string, position: number): string;
// Obsolete. Use getQuickInfoAtPosition instead.
getTypeAtPosition(fileName: string, position: number): string;
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): string;
getBreakpointStatementAtPosition(fileName: string, position: number): string;
getSignatureHelpItems(fileName: string, position: number): string;
getSignatureHelpCurrentArgumentState(fileName: string, position: number, applicableSpanStart: number): string;
// Obsolete. Use getSignatureHelpItems instead.
getSignatureAtPosition(fileName: string, position: number): string;
/**
@@ -617,15 +619,6 @@ module ts {
});
}
public getSignatureHelpCurrentArgumentState(fileName: string, position: number, applicableSpanStart: number): string {
return this.forwardJSONCall(
"getSignatureHelpCurrentArgumentState('" + fileName + "', " + position + ", " + applicableSpanStart + ")",
() => {
var signatureHelpState = this.languageService.getSignatureHelpCurrentArgumentState(fileName, position, applicableSpanStart);
return signatureHelpState;
});
}
public getSignatureAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getSignatureAtPosition('" + fileName + "', " + position + ")",
+6 -2
View File
@@ -337,15 +337,19 @@ module ts.SignatureHelp {
var applicableSpanStart = argumentListOrTypeArgumentList.getFullStart();
var applicableSpanEnd = skipTrivia(sourceFile.text, argumentListOrTypeArgumentList.end, /*stopAfterLineBreak*/ false);
var applicableSpan = new TypeScript.TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
var state = getSignatureHelpCurrentArgumentState(sourceFile, position, applicableSpanStart);
return {
items: items,
applicableSpan: applicableSpan,
selectedItemIndex: selectedItemIndex
selectedItemIndex: selectedItemIndex,
argumentIndex: state.argumentIndex,
argumentCount: state.argumentCount
};
}
}
export function getSignatureHelpCurrentArgumentState(sourceFile: SourceFile, position: number, applicableSpanStart: number): SignatureHelpState {
function getSignatureHelpCurrentArgumentState(sourceFile: SourceFile, position: number, applicableSpanStart: number): { argumentIndex: number; argumentCount: number } {
var tokenPrecedingSpanStart = findPrecedingToken(applicableSpanStart, sourceFile);
if (!tokenPrecedingSpanStart) {
return undefined;
+4
View File
@@ -16,6 +16,10 @@ module ts {
};
}
export function findChildOfKind(n: Node, kind: SyntaxKind, sourceFile?: SourceFile): Node {
return forEach(n.getChildren(sourceFile), c => c.kind === kind && c);
}
export function findContainingList(node: Node): Node {
// The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will
// be parented by the container of the SyntaxList, not the SyntaxList itself.
@@ -25,6 +25,14 @@
////
//// }|]
////}|]
////switch(1)[| {
//// case 1: break;
////}|]
////
////var array =[| [
//// 1,
//// 2
////]|]
////
////// modules
////module m1[| {
@@ -189,6 +189,21 @@ describe('Colorization', function () {
identifier("var"));
});
it("correctly classifies a string literal after a dot", function () {
test("a.\"var\"",
ts.EndOfLineState.Start,
stringLiteral("\"var\""));
});
it("correctly classifies a keyword after a dot separated by comment trivia", function () {
test("a./*hello world*/ var",
ts.EndOfLineState.Start,
identifier("a"),
punctuation("."),
comment("/*hello world*/"),
identifier("var"));
});
it("classifies a property access with whitespace around the dot", function () {
test(" x .\tfoo ()",
ts.EndOfLineState.Start,