Merge branch 'master' into master-14217

# Conflicts:
#	tests/baselines/reference/classOrder2.errors.txt
#	tests/baselines/reference/es5ExportDefaultClassDeclaration3.symbols
#	tests/baselines/reference/es5ExportDefaultClassDeclaration3.types
#	tests/baselines/reference/mappedTypeRelationships.errors.txt
#	tests/baselines/reference/privacyClassExtendsClauseDeclFile.errors.txt
This commit is contained in:
Kanchalai Tanglertsampan 2017-03-29 08:51:39 -07:00
commit 42f398076d
524 changed files with 7904 additions and 5514 deletions

View file

@ -1024,7 +1024,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are:
const fileMatcher = cmdLineOptions["files"];
const files = fileMatcher
? `src/**/${fileMatcher}`
: "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts' --exclude 'src/harness/unittests/services/**/*.ts'";
: "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'";
const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`;
console.log("Linting: " + cmd);
child_process.execSync(cmd, { stdio: [0, 1, 2] });

View file

@ -29,7 +29,8 @@ var thirdParty = "ThirdPartyNoticeText.txt";
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
if (process.env.path !== undefined) {
process.env.path = nodeModulesPathPrefix + process.env.path;
} else if (process.env.PATH !== undefined) {
}
else if (process.env.PATH !== undefined) {
process.env.PATH = nodeModulesPathPrefix + process.env.PATH;
}
@ -312,13 +313,15 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
if (useDebugMode) {
if (opts.inlineSourceMap) {
options += " --inlineSourceMap --inlineSources";
} else {
}
else {
options += " -sourcemap";
if (!opts.noMapRoot) {
options += " -mapRoot file:///" + path.resolve(path.dirname(outFile));
}
}
} else {
}
else {
options += " --newLine LF";
}
@ -748,7 +751,8 @@ function exec(cmd, completeHandler, errorHandler) {
ex.addListener("error", function (e, status) {
if (errorHandler) {
errorHandler(e, status);
} else {
}
else {
fail("Process exited with code " + status);
}
});
@ -942,7 +946,7 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
// Browser tests
var nodeServerOutFile = "tests/webTestServer.js";
var nodeServerInFile = "tests/webTestServer.ts";
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true });
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true, lib: "es6" });
desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
@ -1006,21 +1010,32 @@ task("baseline-accept", function () {
function acceptBaseline(sourceFolder, targetFolder) {
console.log('Accept baselines from ' + sourceFolder + ' to ' + targetFolder);
var files = fs.readdirSync(sourceFolder);
var deleteEnding = '.delete';
for (var i in files) {
var filename = files[i];
var fullLocalPath = path.join(sourceFolder, filename);
if (fs.statSync(fullLocalPath).isFile()) {
if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) {
filename = filename.substr(0, filename.length - deleteEnding.length);
fs.unlinkSync(path.join(targetFolder, filename));
} else {
var target = path.join(targetFolder, filename);
if (fs.existsSync(target)) {
fs.unlinkSync(target);
acceptBaselineFolder(sourceFolder, targetFolder);
function acceptBaselineFolder(sourceFolder, targetFolder) {
var files = fs.readdirSync(sourceFolder);
for (var i in files) {
var filename = files[i];
var fullLocalPath = path.join(sourceFolder, filename);
var stat = fs.statSync(fullLocalPath);
if (stat.isFile()) {
if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) {
filename = filename.substr(0, filename.length - deleteEnding.length);
fs.unlinkSync(path.join(targetFolder, filename));
}
fs.renameSync(path.join(sourceFolder, filename), target);
else {
var target = path.join(targetFolder, filename);
if (fs.existsSync(target)) {
fs.unlinkSync(target);
}
fs.renameSync(path.join(sourceFolder, filename), target);
}
}
else if (stat.isDirectory()) {
acceptBaselineFolder(fullLocalPath, path.join(targetFolder, filename));
}
}
}
@ -1182,7 +1197,7 @@ task("lint", ["build-rules"], () => {
const fileMatcher = process.env.f || process.env.file || process.env.files;
const files = fileMatcher
? `src/**/${fileMatcher}`
: "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts' --exclude 'src/harness/unittests/services/**/*.ts'";
: "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'";
const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`;
console.log("Linting: " + cmd);
jake.exec([cmd], { interactive: true }, () => {

View file

@ -53977,7 +53977,7 @@ var ts;
var padding = makePadding(marginLength);
output.push(getDiagnosticText(ts.Diagnostics.Examples_Colon_0, makePadding(marginLength - examplesLength) + "tsc hello.ts") + ts.sys.newLine);
output.push(padding + "tsc --outFile file.js file.ts" + ts.sys.newLine);
output.push(padding + "tsc @args.txt" + ts.sys.newLine);
output.push(padding + "tsc --project tsconfig.json" + ts.sys.newLine);
output.push(ts.sys.newLine);
output.push(getDiagnosticText(ts.Diagnostics.Options_Colon) + ts.sys.newLine);
var optsList = ts.filter(ts.optionDeclarations.slice(), function (v) { return !v.experimental; });

View file

@ -259,7 +259,7 @@ namespace ts {
case SyntaxKind.ExportAssignment:
return (<ExportAssignment>node).isExportEquals ? "export=" : "default";
case SyntaxKind.BinaryExpression:
switch (getSpecialPropertyAssignmentKind(node)) {
switch (getSpecialPropertyAssignmentKind(node as BinaryExpression)) {
case SpecialPropertyAssignmentKind.ModuleExports:
// module.exports = ...
return "export=";
@ -2017,30 +2017,28 @@ namespace ts {
}
break;
case SyntaxKind.BinaryExpression:
if (isInJavaScriptFile(node)) {
const specialKind = getSpecialPropertyAssignmentKind(node);
switch (specialKind) {
case SpecialPropertyAssignmentKind.ExportsProperty:
bindExportsPropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.ModuleExports:
bindModuleExportsAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.PrototypeProperty:
bindPrototypePropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.ThisProperty:
bindThisPropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.Property:
bindStaticPropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.None:
// Nothing to do
break;
default:
Debug.fail("Unknown special property assignment kind");
}
const specialKind = getSpecialPropertyAssignmentKind(node as BinaryExpression);
switch (specialKind) {
case SpecialPropertyAssignmentKind.ExportsProperty:
bindExportsPropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.ModuleExports:
bindModuleExportsAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.PrototypeProperty:
bindPrototypePropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.ThisProperty:
bindThisPropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.Property:
bindStaticPropertyAssignment(<BinaryExpression>node);
break;
case SpecialPropertyAssignmentKind.None:
// Nothing to do
break;
default:
Debug.fail("Unknown special property assignment kind");
}
return checkStrictModeBinaryExpression(<BinaryExpression>node);
case SyntaxKind.CatchClause:

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2360,4 +2360,8 @@ namespace ts {
return Extension.Jsx;
}
}
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
}
}

View file

@ -1,4 +1,4 @@
{
{
"Unterminated string literal.": {
"category": "Error",
"code": 1002
@ -1435,6 +1435,14 @@
"category": "Error",
"code": 2448
},
"Class '{0}' used before its declaration.": {
"category": "Error",
"code": 2449
},
"Enum '{0}' used before its declaration.": {
"category": "Error",
"code": 2450
},
"Cannot redeclare block-scoped variable '{0}'.": {
"category": "Error",
"code": 2451
@ -2019,10 +2027,6 @@
"category": "Error",
"code": 2689
},
"A class must be declared after its base class.": {
"category": "Error",
"code": 2690
},
"An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": {
"category": "Error",
"code": 2691
@ -2781,7 +2785,7 @@
"category": "Message",
"code": 6083
},
"Specify the object invoked for createElement and __spread when targeting 'react' JSX emit.": {
"[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit": {
"category": "Message",
"code": 6084
},
@ -3037,14 +3041,139 @@
"category": "Message",
"code": 6148
},
"Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3.": {
"Show diagnostic information.": {
"category": "Message",
"code": 6149
},
"Enable all strict type checks.": {
"Show verbose diagnostic information.": {
"category": "Message",
"code": 6150
},
"Emit a single file with source maps instead of having a separate file.": {
"category": "Message",
"code": 6151
},
"Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set.": {
"category": "Message",
"code": 6152
},
"Transpile each file as a separate module (similar to 'ts.transpileModule').": {
"category": "Message",
"code": 6153
},
"Print names of generated files part of the compilation.": {
"category": "Message",
"code": 6154
},
"Print names of files part of the compilation.": {
"category": "Message",
"code": 6155
},
"The locale used when displaying messages to the user (e.g. 'en-us')": {
"category": "Message",
"code": 6156
},
"Do not generate custom helper functions like '__extends' in compiled output.": {
"category": "Message",
"code": 6157
},
"Do not include the default library file (lib.d.ts).": {
"category": "Message",
"code": 6158
},
"Do not add triple-slash references or imported modules to the list of compiled files.": {
"category": "Message",
"code": 6159
},
"[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files.": {
"category": "Message",
"code": 6160
},
"List of folders to include type definitions from.": {
"category": "Message",
"code": 6161
},
"Disable size limitations on JavaScript projects.": {
"category": "Message",
"code": 6162
},
"The character set of the input files.": {
"category": "Message",
"code": 6163
},
"Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.": {
"category": "Message",
"code": 6164
},
"Do not truncate error messages.": {
"category": "Message",
"code": 6165
},
"Output directory for generated declaration files.": {
"category": "Message",
"code": 6166
},
"A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.": {
"category": "Message",
"code": 6167
},
"List of root folders whose combined content represents the structure of the project at runtime.": {
"category": "Message",
"code": 6168
},
"Show all compiler options.": {
"category": "Message",
"code": 6169
},
"[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file": {
"category": "Message",
"code": 6170
},
"Command-line Options": {
"category": "Message",
"code": 6171
},
"Basic Options": {
"category": "Message",
"code": 6172
},
"Strict Type-Checking Options": {
"category": "Message",
"code": 6173
},
"Module Resolution Options": {
"category": "Message",
"code": 6174
},
"Source Map Options": {
"category": "Message",
"code": 6175
},
"Additional Checks": {
"category": "Message",
"code": 6176
},
"Experimental Options": {
"category": "Message",
"code": 6177
},
"Advanced Options": {
"category": "Message",
"code": 6178
},
"Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'.": {
"category": "Message",
"code": 6179
},
"Enable all strict type-checking options.": {
"category": "Message",
"code": 6180
},
"List of language service plugins.": {
"category": "Message",
"code": 6181
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
@ -3351,6 +3480,24 @@
"category": "Message",
"code": 90017
},
"Disable checking for this file.": {
"category": "Message",
"code": 90018
},
"Ignore this error message.": {
"category": "Message",
"code": 90019
},
"Initialize property '{0}' in the constructor.": {
"category": "Message",
"code": 90020
},
"Initialize static property '{0}'.": {
"category": "Message",
"code": 90021
},
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
"category": "Error",
"code": 8017
@ -3358,5 +3505,9 @@
"Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.": {
"category": "Error",
"code": 8018
},
"Report errors in .js files.": {
"category": "Message",
"code": 8019
}
}

View file

@ -45,7 +45,7 @@ namespace ts {
* Creates a shallow, memberwise clone of a node with no source map location.
*/
/* @internal */
export function getSynthesizedClone<T extends Node>(node: T): T {
export function getSynthesizedClone<T extends Node>(node: T | undefined): T {
// We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
// the original node. We also need to exclude specific properties and only include own-
// properties (to skip members already defined on the shared prototype).
@ -166,23 +166,23 @@ namespace ts {
// Reserved words
export function createSuper() {
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.SuperKeyword);
return <SuperExpression>createSynthesizedNode(SyntaxKind.SuperKeyword);
}
export function createThis() {
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.ThisKeyword);
return <ThisExpression & Token<SyntaxKind.ThisKeyword>>createSynthesizedNode(SyntaxKind.ThisKeyword);
}
export function createNull() {
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.NullKeyword);
return <NullLiteral & Token<SyntaxKind.NullKeyword>>createSynthesizedNode(SyntaxKind.NullKeyword);
}
export function createTrue() {
return <BooleanLiteral>createSynthesizedNode(SyntaxKind.TrueKeyword);
return <BooleanLiteral & Token<SyntaxKind.TrueKeyword>>createSynthesizedNode(SyntaxKind.TrueKeyword);
}
export function createFalse() {
return <BooleanLiteral>createSynthesizedNode(SyntaxKind.FalseKeyword);
return <BooleanLiteral & Token<SyntaxKind.FalseKeyword>>createSynthesizedNode(SyntaxKind.FalseKeyword);
}
// Names
@ -213,6 +213,284 @@ namespace ts {
: node;
}
// Type Elements
export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration;
signatureDeclaration.typeParameters = asNodeArray(typeParameters);
signatureDeclaration.parameters = asNodeArray(parameters);
signatureDeclaration.type = type;
return signatureDeclaration;
}
function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
: node;
}
export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode;
}
export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <FunctionTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode;
}
export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <ConstructorTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration;
}
export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <CallSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration;
}
export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <ConstructSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) {
const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature;
methodSignature.name = asName(name);
methodSignature.questionToken = questionToken;
return methodSignature;
}
export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
|| node.name !== name
|| node.questionToken !== questionToken
? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
: node;
}
// Types
export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]) {
return <KeywordTypeNode>createSynthesizedNode(kind);
}
export function createThisTypeNode() {
return <ThisTypeNode>createSynthesizedNode(SyntaxKind.ThisType);
}
export function createLiteralTypeNode(literal: Expression) {
const literalTypeNode = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode;
literalTypeNode.literal = literal;
return literalTypeNode;
}
export function updateLiteralTypeNode(node: LiteralTypeNode, literal: Expression) {
return node.literal !== literal
? updateNode(createLiteralTypeNode(literal), node)
: node;
}
export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: TypeNode[] | undefined) {
const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode;
typeReference.typeName = asName(typeName);
typeReference.typeArguments = asNodeArray(typeArguments);
return typeReference;
}
export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray<TypeNode> | undefined) {
return node.typeName !== typeName
|| node.typeArguments !== typeArguments
? updateNode(createTypeReferenceNode(typeName, typeArguments), node)
: node;
}
export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode) {
const typePredicateNode = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode;
typePredicateNode.parameterName = asName(parameterName);
typePredicateNode.type = type;
return typePredicateNode;
}
export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) {
return node.parameterName !== parameterName
|| node.type !== type
? updateNode(createTypePredicateNode(parameterName, type), node)
: node;
}
export function createTypeQueryNode(exprName: EntityName) {
const typeQueryNode = createSynthesizedNode(SyntaxKind.TypeQuery) as TypeQueryNode;
typeQueryNode.exprName = exprName;
return typeQueryNode;
}
export function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) {
return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName), node) : node;
}
export function createArrayTypeNode(elementType: TypeNode) {
const arrayTypeNode = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode;
arrayTypeNode.elementType = elementType;
return arrayTypeNode;
}
export function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode {
return node.elementType !== elementType
? updateNode(createArrayTypeNode(elementType), node)
: node;
}
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType, types: TypeNode[]): UnionTypeNode;
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.IntersectionType, types: TypeNode[]): IntersectionTypeNode;
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode;
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]) {
const unionTypeNode = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode;
unionTypeNode.types = createNodeArray(types);
return unionTypeNode;
}
export function updateUnionOrIntersectionTypeNode(node: UnionOrIntersectionTypeNode, types: NodeArray<TypeNode>) {
return node.types !== types
? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node)
: node;
}
export function createTypeLiteralNode(members: TypeElement[]) {
const typeLiteralNode = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode;
typeLiteralNode.members = createNodeArray(members);
return typeLiteralNode;
}
export function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray<TypeElement>) {
return node.members !== members
? updateNode(createTypeLiteralNode(members), node)
: node;
}
export function createTupleTypeNode(elementTypes: TypeNode[]) {
const tupleTypeNode = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode;
tupleTypeNode.elementTypes = createNodeArray(elementTypes);
return tupleTypeNode;
}
export function updateTypleTypeNode(node: TupleTypeNode, elementTypes: TypeNode[]) {
return node.elementTypes !== elementTypes
? updateNode(createTupleTypeNode(elementTypes), node)
: node;
}
export function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode {
const mappedTypeNode = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode;
mappedTypeNode.readonlyToken = readonlyToken;
mappedTypeNode.typeParameter = typeParameter;
mappedTypeNode.questionToken = questionToken;
mappedTypeNode.type = type;
return mappedTypeNode;
}
export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode {
return node.readonlyToken !== readonlyToken
|| node.typeParameter !== typeParameter
|| node.questionToken !== questionToken
|| node.type !== type
? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
: node;
}
export function createTypeOperatorNode(type: TypeNode) {
const typeOperatorNode = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode;
typeOperatorNode.operator = SyntaxKind.KeyOfKeyword;
typeOperatorNode.type = type;
return typeOperatorNode;
}
export function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) {
return node.type !== type ? updateNode(createTypeOperatorNode(type), node) : node;
}
export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) {
const indexedAccessTypeNode = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode;
indexedAccessTypeNode.objectType = objectType;
indexedAccessTypeNode.indexType = indexType;
return indexedAccessTypeNode;
}
export function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) {
return node.objectType !== objectType
|| node.indexType !== indexType
? updateNode(createIndexedAccessTypeNode(objectType, indexType), node)
: node;
}
// Type Declarations
export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) {
const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration;
typeParameter.name = asName(name);
typeParameter.constraint = constraint;
typeParameter.default = defaultType;
return typeParameter;
}
export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) {
return node.name !== name
|| node.constraint !== constraint
|| node.default !== defaultType
? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node)
: node;
}
// Signature elements
export function createPropertySignature(name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature {
const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature;
propertySignature.name = asName(name);
propertySignature.questionToken = questionToken;
propertySignature.type = type;
propertySignature.initializer = initializer;
return propertySignature;
}
export function updatePropertySignature(node: PropertySignature, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) {
return node.name !== name
|| node.questionToken !== questionToken
|| node.type !== type
|| node.initializer !== initializer
? updateNode(createPropertySignature(name, questionToken, type, initializer), node)
: node;
}
export function createIndexSignatureDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration {
const indexSignature = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration;
indexSignature.decorators = asNodeArray(decorators);
indexSignature.modifiers = asNodeArray(modifiers);
indexSignature.parameters = createNodeArray(parameters);
indexSignature.type = type;
return indexSignature;
}
export function updateIndexSignatureDeclaration(node: IndexSignatureDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode) {
return node.parameters !== parameters
|| node.type !== type
|| node.decorators !== decorators
|| node.modifiers !== modifiers
? updateNode(createIndexSignatureDeclaration(decorators, modifiers, parameters, type), node)
: node;
}
// Signature elements
export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) {
@ -227,11 +505,12 @@ namespace ts {
return node;
}
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) {
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) {
return node.decorators !== decorators
|| node.modifiers !== modifiers
|| node.dotDotDotToken !== dotDotDotToken
|| node.name !== name
|| node.questionToken !== questionToken
|| node.type !== type
|| node.initializer !== initializer
? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node)
@ -273,12 +552,13 @@ namespace ts {
: node;
}
export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
export function createMethodDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
const node = <MethodDeclaration>createSynthesizedNode(SyntaxKind.MethodDeclaration);
node.decorators = asNodeArray(decorators);
node.modifiers = asNodeArray(modifiers);
node.asteriskToken = asteriskToken;
node.name = asName(name);
node.questionToken = questionToken;
node.typeParameters = asNodeArray(typeParameters);
node.parameters = createNodeArray(parameters);
node.type = type;
@ -286,7 +566,7 @@ namespace ts {
return node;
}
export function updateMethod(node: MethodDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
export function updateMethod(node: MethodDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
return node.decorators !== decorators
|| node.modifiers !== modifiers
|| node.asteriskToken !== asteriskToken
@ -295,7 +575,7 @@ namespace ts {
|| node.parameters !== parameters
|| node.type !== type
|| node.body !== body
? updateNode(createMethod(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
? updateNode(createMethodDeclaration(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
: node;
}
@ -1099,10 +1379,6 @@ namespace ts {
: node;
}
export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode {
return <KeywordTypeNode>createSynthesizedNode(kind);
}
export function createFunctionDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
const node = <FunctionDeclaration>createSynthesizedNode(SyntaxKind.FunctionDeclaration);
node.decorators = asNodeArray(decorators);
@ -1486,7 +1762,7 @@ namespace ts {
// Clauses
export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[]) {
export function createHeritageClause(token: HeritageClause["token"], types: ExpressionWithTypeArguments[]) {
const node = <HeritageClause>createSynthesizedNode(SyntaxKind.HeritageClause);
node.token = token;
node.types = createNodeArray(types);
@ -1793,7 +2069,9 @@ namespace ts {
function asName(name: string | Identifier): Identifier;
function asName(name: string | BindingName): BindingName;
function asName(name: string | PropertyName): PropertyName;
function asName(name: string | Identifier | BindingName | PropertyName) {
function asName(name: string | EntityName): EntityName;
function asName(name: string | Identifier | ThisTypeNode): Identifier | ThisTypeNode;
function asName(name: string | Identifier | BindingName | PropertyName | QualifiedName | ThisTypeNode) {
return typeof name === "string" ? createIdentifier(name) : name;
}

View file

@ -5437,9 +5437,10 @@ namespace ts {
}
function parseHeritageClause(): HeritageClause | undefined {
if (token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword) {
const tok = token();
if (tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword) {
const node = <HeritageClause>createNode(SyntaxKind.HeritageClause);
node.token = token();
node.token = tok;
nextToken();
node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments);
return finishNode(node);
@ -5821,6 +5822,7 @@ namespace ts {
const typeReferenceDirectives: FileReference[] = [];
const amdDependencies: { path: string; name: string }[] = [];
let amdModuleName: string;
let checkJsDirective: CheckJsDirective = undefined;
// Keep scanning all the leading trivia in the file until we get to something that
// isn't trivia. Any single line comment will be analyzed to see if it is a
@ -5882,6 +5884,16 @@ namespace ts {
amdDependencies.push(amdDependency);
}
}
const checkJsDirectiveRegEx = /^\/\/\/?\s*(@ts-check|@ts-nocheck)\s*$/gim;
const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment);
if (checkJsDirectiveMatchResult) {
checkJsDirective = {
enabled: compareStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true) === Comparison.EqualTo,
end: range.end,
pos: range.pos
};
}
}
}
@ -5889,6 +5901,7 @@ namespace ts {
sourceFile.typeReferenceDirectives = typeReferenceDirectives;
sourceFile.amdDependencies = amdDependencies;
sourceFile.moduleName = amdModuleName;
sourceFile.checkJsDirective = checkJsDirective;
}
function setExternalModuleIndicator(sourceFile: SourceFile) {

View file

@ -4,6 +4,7 @@
namespace ts {
const emptyArray: any[] = [];
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
while (true) {
@ -911,17 +912,42 @@ namespace ts {
Debug.assert(!!sourceFile.bindDiagnostics);
const bindDiagnostics = sourceFile.bindDiagnostics;
// For JavaScript files, we don't want to report semantic errors.
// Instead, we'll report errors for using TypeScript-only constructs from within a
// JavaScript file when we get syntactic diagnostics for the file.
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken);
// For JavaScript files, we don't want to report semantic errors unless explicitly requested.
const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || isCheckJsEnabledForFile(sourceFile, options);
const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : [];
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
const diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
return isSourceFileJavaScript(sourceFile)
? filter(diagnostics, shouldReportDiagnostic)
: diagnostics;
});
}
/**
* Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines
*/
function shouldReportDiagnostic(diagnostic: Diagnostic) {
const { file, start } = diagnostic;
const lineStarts = getLineStarts(file);
let { line } = computeLineAndCharacterOfPosition(lineStarts, start);
while (line > 0) {
const previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]);
const result = ignoreDiagnosticCommentRegEx.exec(previousLineText);
if (!result) {
// non-empty line
return true;
}
if (result[3]) {
// @ts-ignore
return false;
}
line--;
}
return true;
}
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
return runWithCancellationToken(() => {
const diagnostics: Diagnostic[] = [];
@ -1722,6 +1748,10 @@ namespace ts {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"));
}
if (options.checkJs && !options.allowJs) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
}
if (options.emitDecoratorMetadata &&
!options.experimentalDecorators) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));

View file

@ -125,6 +125,7 @@ namespace ts {
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
/*questionToken*/ undefined,
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,

View file

@ -475,6 +475,7 @@ namespace ts {
/*modifiers*/ undefined,
node.dotDotDotToken,
getGeneratedNameForNode(node),
/*questionToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor, isExpression)
);
@ -540,6 +541,7 @@ namespace ts {
? undefined
: node.asteriskToken,
visitNode(node.name, visitor, isPropertyName),
visitNode(/*questionToken*/ undefined, visitor, isToken),
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,

View file

@ -2049,6 +2049,7 @@ namespace ts {
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
visitPropertyNameOfClassElement(node),
/*questionToken*/ undefined,
/*typeParameters*/ undefined,
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,

View file

@ -225,9 +225,9 @@ namespace ts {
return sys.exit(ExitStatus.Success);
}
if (commandLine.options.help) {
if (commandLine.options.help || commandLine.options.all) {
printVersion();
printHelp();
printHelp(commandLine.options.all);
return sys.exit(ExitStatus.Success);
}
@ -264,7 +264,7 @@ namespace ts {
if (commandLine.fileNames.length === 0 && !configFileName) {
printVersion();
printHelp();
printHelp(commandLine.options.all);
return sys.exit(ExitStatus.Success);
}
@ -618,7 +618,7 @@ namespace ts {
sys.write(getDiagnosticText(Diagnostics.Version_0, ts.version) + sys.newLine);
}
function printHelp() {
function printHelp(showAllOptions: boolean) {
const output: string[] = [];
// We want to align our "syntax" and "examples" commands to a certain margin.
@ -643,8 +643,9 @@ namespace ts {
output.push(getDiagnosticText(Diagnostics.Options_Colon) + sys.newLine);
// Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch")
const optsList = filter(optionDeclarations.slice(), v => !v.experimental);
optsList.sort((a, b) => compareValues<string>(a.name.toLowerCase(), b.name.toLowerCase()));
const optsList = showAllOptions ?
optionDeclarations.slice().sort((a, b) => compareValues<string>(a.name.toLowerCase(), b.name.toLowerCase())) :
filter(optionDeclarations.slice(), v => v.showInSimplifiedHelpView);
// We want our descriptions to align at the same column in our output,
// so we keep track of the longest option usage string.
@ -738,7 +739,7 @@ namespace ts {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* host */ undefined);
}
else {
sys.writeFile(file, JSON.stringify(generateTSConfig(options, fileNames), undefined, 4));
sys.writeFile(file, generateTSConfig(options, fileNames));
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file), /* host */ undefined);
}

View file

@ -815,18 +815,21 @@ namespace ts {
export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement {
kind: SyntaxKind.Constructor;
parent?: ClassDeclaration | ClassExpression;
body?: FunctionBody;
}
// For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.
/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.*/
export interface SemicolonClassElement extends ClassElement {
kind: SyntaxKind.SemicolonClassElement;
parent?: ClassDeclaration | ClassExpression;
}
// See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
// ClassElement and an ObjectLiteralElement.
export interface GetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
kind: SyntaxKind.GetAccessor;
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
name: PropertyName;
body: FunctionBody;
}
@ -835,6 +838,7 @@ namespace ts {
// ClassElement and an ObjectLiteralElement.
export interface SetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
kind: SyntaxKind.SetAccessor;
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
name: PropertyName;
body: FunctionBody;
}
@ -843,6 +847,7 @@ namespace ts {
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
kind: SyntaxKind.IndexSignature;
parent?: ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode;
}
export interface TypeNode extends Node {
@ -856,22 +861,24 @@ namespace ts {
| SyntaxKind.BooleanKeyword
| SyntaxKind.StringKeyword
| SyntaxKind.SymbolKeyword
| SyntaxKind.VoidKeyword;
| SyntaxKind.ThisKeyword
| SyntaxKind.VoidKeyword
| SyntaxKind.UndefinedKeyword
| SyntaxKind.NullKeyword
| SyntaxKind.NeverKeyword;
}
export interface ThisTypeNode extends TypeNode {
kind: SyntaxKind.ThisType;
}
export interface FunctionOrConstructorTypeNode extends TypeNode, SignatureDeclaration {
kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType;
}
export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode;
export interface FunctionTypeNode extends FunctionOrConstructorTypeNode {
export interface FunctionTypeNode extends TypeNode, SignatureDeclaration {
kind: SyntaxKind.FunctionType;
}
export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode {
export interface ConstructorTypeNode extends TypeNode, SignatureDeclaration {
kind: SyntaxKind.ConstructorType;
}
@ -908,17 +915,16 @@ namespace ts {
elementTypes: NodeArray<TypeNode>;
}
export interface UnionOrIntersectionTypeNode extends TypeNode {
kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType;
export type UnionOrIntersectionTypeNode = UnionTypeNode | IntersectionTypeNode;
export interface UnionTypeNode extends TypeNode {
kind: SyntaxKind.UnionType;
types: NodeArray<TypeNode>;
}
export interface UnionTypeNode extends UnionOrIntersectionTypeNode {
kind: SyntaxKind.UnionType;
}
export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode {
export interface IntersectionTypeNode extends TypeNode {
kind: SyntaxKind.IntersectionType;
types: NodeArray<TypeNode>;
}
export interface ParenthesizedTypeNode extends TypeNode {
@ -940,6 +946,7 @@ namespace ts {
export interface MappedTypeNode extends TypeNode, Declaration {
kind: SyntaxKind.MappedType;
parent?: TypeAliasDeclaration;
readonlyToken?: ReadonlyToken;
typeParameter: TypeParameterDeclaration;
questionToken?: QuestionToken;
@ -1027,15 +1034,15 @@ namespace ts {
_primaryExpressionBrand: any;
}
export interface NullLiteral extends PrimaryExpression {
export interface NullLiteral extends PrimaryExpression, TypeNode {
kind: SyntaxKind.NullKeyword;
}
export interface BooleanLiteral extends PrimaryExpression {
export interface BooleanLiteral extends PrimaryExpression, TypeNode {
kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword;
}
export interface ThisExpression extends PrimaryExpression {
export interface ThisExpression extends PrimaryExpression, KeywordTypeNode {
kind: SyntaxKind.ThisKeyword;
}
@ -1453,7 +1460,7 @@ namespace ts {
kind: SyntaxKind.NewExpression;
expression: LeftHandSideExpression;
typeArguments?: NodeArray<TypeNode>;
arguments: NodeArray<Expression>;
arguments?: NodeArray<Expression>;
}
export interface TaggedTemplateExpression extends MemberExpression {
@ -1507,6 +1514,7 @@ namespace ts {
export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression;
export interface JsxAttributes extends ObjectLiteralExpressionBase<JsxAttributeLike> {
parent?: JsxOpeningLikeElement;
}
/// The opening element of a <Tag>...</Tag> JsxElement
@ -1526,7 +1534,7 @@ namespace ts {
export interface JsxAttribute extends ObjectLiteralElement {
kind: SyntaxKind.JsxAttribute;
parent?: JsxOpeningLikeElement;
parent?: JsxAttributes;
name: Identifier;
/// JSX attribute initializers are optional; <X y /> is sugar for <X y={true} />
initializer?: StringLiteral | JsxExpression;
@ -1534,7 +1542,7 @@ namespace ts {
export interface JsxSpreadAttribute extends ObjectLiteralElement {
kind: SyntaxKind.JsxSpreadAttribute;
parent?: JsxOpeningLikeElement;
parent?: JsxAttributes;
expression: Expression;
}
@ -1779,8 +1787,8 @@ namespace ts {
export interface HeritageClause extends Node {
kind: SyntaxKind.HeritageClause;
parent?: InterfaceDeclaration | ClassDeclaration | ClassExpression;
token: SyntaxKind;
types?: NodeArray<ExpressionWithTypeArguments>;
token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword;
types: NodeArray<ExpressionWithTypeArguments>;
}
export interface TypeAliasDeclaration extends DeclarationStatement {
@ -1944,6 +1952,10 @@ namespace ts {
fileName: string;
}
export interface CheckJsDirective extends TextRange {
enabled: boolean;
}
export type CommentKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia;
export interface CommentRange extends TextRange {
@ -2286,6 +2298,7 @@ namespace ts {
/* @internal */ moduleAugmentations: LiteralExpression[];
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
/* @internal */ ambientModuleNames: string[];
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
}
export interface Bundle extends Node {
@ -2468,6 +2481,14 @@ namespace ts {
/* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type;
getNonNullableType(type: Type): Type;
/** Note that the resulting nodes cannot be checked. */
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode;
/** Note that the resulting nodes cannot be checked. */
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration;
/** Note that the resulting nodes cannot be checked. */
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration;
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
getSymbolAtLocation(node: Node): Symbol;
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];
@ -2519,6 +2540,16 @@ namespace ts {
/* @internal */ getTypeCount(): number;
}
export enum NodeBuilderFlags {
None = 0,
allowThisInObjectLiteral = 1 << 0,
allowQualifedNameInPlaceOfIdentifier = 1 << 1,
allowTypeParameterInQualifiedName = 1 << 2,
allowAnonymousIdentifier = 1 << 3,
allowEmptyUnionOrIntersection = 1 << 4,
allowEmptyTuple = 1 << 5
}
export interface SymbolDisplayBuilder {
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
@ -3010,7 +3041,6 @@ namespace ts {
ObjectLiteral = 1 << 7, // Originates in an object literal
EvolvingArray = 1 << 8, // Evolving array type
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
NonPrimitive = 1 << 10, // NonPrimitive object type
ClassOrInterface = Class | Interface
}
@ -3321,6 +3351,7 @@ namespace ts {
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[];
export interface CompilerOptions {
/*@internal*/ all?: boolean;
allowJs?: boolean;
/*@internal*/ allowNonTsExtensions?: boolean;
allowSyntheticDefaultImports?: boolean;
@ -3329,6 +3360,7 @@ namespace ts {
alwaysStrict?: boolean; // Always combine with strict property
baseUrl?: string;
charset?: string;
checkJs?: boolean;
/* @internal */ configFilePath?: string;
declaration?: boolean;
declarationDir?: string;
@ -3513,8 +3545,10 @@ namespace ts {
shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help'
description?: DiagnosticMessage; // The message describing what the command line switch does
paramType?: DiagnosticMessage; // The name to be used for a non-boolean option's parameter
experimental?: boolean;
isTSConfigOnly?: boolean; // True if option can only be specified via tsconfig.json file
isCommandLineOnly?: boolean;
showInSimplifiedHelpView?: boolean;
category?: DiagnosticMessage;
}
/* @internal */
@ -4067,7 +4101,7 @@ namespace ts {
export type Transformer<T extends Node> = (node: T) => T;
/**
* A function that accepts and possible transforms a node.
* A function that accepts and possibly transforms a node.
*/
export type Visitor = (node: Node) => VisitResult<Node>;

View file

@ -525,6 +525,10 @@ namespace ts {
return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
}
export function getNameFromIndexInfo(info: IndexInfo) {
return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
}
export function getTextOfPropertyName(name: PropertyName): string {
switch (name.kind) {
case SyntaxKind.Identifier:
@ -740,8 +744,8 @@ namespace ts {
//
// let a: A.B.C;
//
// Calling isPartOfTypeNode would consider the qualified name A.B a type node. Only C or
// A.B.C is a type node.
// Calling isPartOfTypeNode would consider the qualified name A.B a type node.
// Only C and A.B.C are type nodes.
if (SyntaxKind.FirstTypeNode <= parent.kind && parent.kind <= SyntaxKind.LastTypeNode) {
return true;
}
@ -1446,13 +1450,10 @@ namespace ts {
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
/// assignments we treat as special in the binder
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {
export function getSpecialPropertyAssignmentKind(expression: ts.BinaryExpression): SpecialPropertyAssignmentKind {
if (!isInJavaScriptFile(expression)) {
return SpecialPropertyAssignmentKind.None;
}
if (expression.kind !== SyntaxKind.BinaryExpression) {
return SpecialPropertyAssignmentKind.None;
}
const expr = <BinaryExpression>expression;
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || expr.left.kind !== SyntaxKind.PropertyAccessExpression) {
return SpecialPropertyAssignmentKind.None;
@ -2675,7 +2676,7 @@ namespace ts {
if (sourceFiles.length) {
const jsFilePath = options.outFile || options.out;
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : "";
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
}
}
@ -3713,10 +3714,14 @@ namespace ts {
return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode)
|| kind === SyntaxKind.AnyKeyword
|| kind === SyntaxKind.NumberKeyword
|| kind === SyntaxKind.ObjectKeyword
|| kind === SyntaxKind.BooleanKeyword
|| kind === SyntaxKind.StringKeyword
|| kind === SyntaxKind.SymbolKeyword
|| kind === SyntaxKind.ThisKeyword
|| kind === SyntaxKind.VoidKeyword
|| kind === SyntaxKind.UndefinedKeyword
|| kind === SyntaxKind.NullKeyword
|| kind === SyntaxKind.NeverKeyword
|| kind === SyntaxKind.ExpressionWithTypeArguments;
}

View file

@ -204,21 +204,17 @@ namespace ts {
* @param visitor The callback used to visit each child.
* @param context A lexical environment context for the visitor.
*/
export function visitEachChild<T extends Node>(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes): T | undefined;
export function visitEachChild<T extends Node>(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined;
export function visitEachChild(node: Node, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes): Node {
export function visitEachChild(node: Node, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor): Node {
if (node === undefined) {
return undefined;
}
const kind = node.kind;
// No need to visit nodes with no children.
if ((kind > SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken)) {
return node;
}
// We do not yet support types.
if ((kind >= SyntaxKind.TypePredicate && kind <= SyntaxKind.LiteralType)) {
// No need to visit nodes with no children.
if ((kind > SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken) || kind === SyntaxKind.ThisType) {
return node;
}
@ -227,6 +223,8 @@ namespace ts {
case SyntaxKind.EmptyStatement:
case SyntaxKind.OmittedExpression:
case SyntaxKind.DebuggerStatement:
case SyntaxKind.EndOfDeclarationMarker:
case SyntaxKind.MissingDeclaration:
// No need to visit nodes with no children.
return node;
@ -240,13 +238,53 @@ namespace ts {
return updateComputedPropertyName(<ComputedPropertyName>node,
visitNode((<ComputedPropertyName>node).expression, visitor, isExpression));
// Signature elements
// Signatures and Signature Elements
case SyntaxKind.FunctionType:
return updateFunctionTypeNode(<FunctionTypeNode>node,
nodesVisitor((<FunctionTypeNode>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<FunctionTypeNode>node).parameters, visitor, context, nodesVisitor),
visitNode((<FunctionTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.ConstructorType:
return updateConstructorTypeNode(<ConstructorTypeNode>node,
nodesVisitor((<ConstructorTypeNode>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<ConstructorTypeNode>node).parameters, visitor, context, nodesVisitor),
visitNode((<ConstructorTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.CallSignature:
return updateCallSignatureDeclaration(<CallSignatureDeclaration>node,
nodesVisitor((<CallSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<CallSignatureDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<CallSignatureDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.ConstructSignature:
return updateConstructSignatureDeclaration(<ConstructSignatureDeclaration>node,
nodesVisitor((<ConstructSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<ConstructSignatureDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<ConstructSignatureDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.MethodSignature:
return updateMethodSignature(<MethodSignature>node,
nodesVisitor((<MethodSignature>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<MethodSignature>node).parameters, visitor, context, nodesVisitor),
visitNode((<MethodSignature>node).type, visitor, isTypeNode),
visitNode((<MethodSignature>node).name, visitor, isPropertyName),
visitNode((<MethodSignature>node).questionToken, tokenVisitor, isToken));
case SyntaxKind.IndexSignature:
return updateIndexSignatureDeclaration(<IndexSignatureDeclaration>node,
nodesVisitor((<IndexSignatureDeclaration>node).decorators, visitor, isDecorator),
nodesVisitor((<IndexSignatureDeclaration>node).modifiers, visitor, isModifier),
visitParameterList((<IndexSignatureDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<IndexSignatureDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.Parameter:
return updateParameter(<ParameterDeclaration>node,
nodesVisitor((<ParameterDeclaration>node).decorators, visitor, isDecorator),
nodesVisitor((<ParameterDeclaration>node).modifiers, visitor, isModifier),
(<ParameterDeclaration>node).dotDotDotToken,
visitNode((<ParameterDeclaration>node).dotDotDotToken, tokenVisitor, isToken),
visitNode((<ParameterDeclaration>node).name, visitor, isBindingName),
visitNode((<ParameterDeclaration>node).questionToken, tokenVisitor, isToken),
visitNode((<ParameterDeclaration>node).type, visitor, isTypeNode),
visitNode((<ParameterDeclaration>node).initializer, visitor, isExpression));
@ -254,7 +292,74 @@ namespace ts {
return updateDecorator(<Decorator>node,
visitNode((<Decorator>node).expression, visitor, isExpression));
// Type member
// Types
case SyntaxKind.TypeReference:
return updateTypeReferenceNode(<TypeReferenceNode>node,
visitNode((<TypeReferenceNode>node).typeName, visitor, isEntityName),
nodesVisitor((<TypeReferenceNode>node).typeArguments, visitor, isTypeNode));
case SyntaxKind.TypePredicate:
return updateTypePredicateNode(<TypePredicateNode>node,
visitNode((<TypePredicateNode>node).parameterName, visitor),
visitNode((<TypePredicateNode>node).type, visitor, isTypeNode));
case SyntaxKind.TypeQuery:
return updateTypeQueryNode((<TypeQueryNode>node), visitNode((<TypeQueryNode>node).exprName, visitor, isEntityName));
case SyntaxKind.TypeLiteral:
return updateTypeLiteralNode((<TypeLiteralNode>node), nodesVisitor((<TypeLiteralNode>node).members, visitor));
case SyntaxKind.ArrayType:
return updateArrayTypeNode(<ArrayTypeNode>node, visitNode((<ArrayTypeNode>node).elementType, visitor, isTypeNode));
case SyntaxKind.TupleType:
return updateTypleTypeNode((<TupleTypeNode>node), nodesVisitor((<TupleTypeNode>node).elementTypes, visitor, isTypeNode));
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
return updateUnionOrIntersectionTypeNode(<UnionOrIntersectionTypeNode>node,
nodesVisitor((<UnionOrIntersectionTypeNode>node).types, visitor, isTypeNode));
case SyntaxKind.ParenthesizedType:
Debug.fail("not implemented.");
case SyntaxKind.TypeOperator:
return updateTypeOperatorNode(<TypeOperatorNode>node, visitNode((<TypeOperatorNode>node).type, visitor, isTypeNode));
case SyntaxKind.IndexedAccessType:
return updateIndexedAccessTypeNode((<IndexedAccessTypeNode>node),
visitNode((<IndexedAccessTypeNode>node).objectType, visitor, isTypeNode),
visitNode((<IndexedAccessTypeNode>node).indexType, visitor, isTypeNode));
case SyntaxKind.MappedType:
return updateMappedTypeNode((<MappedTypeNode>node),
visitNode((<MappedTypeNode>node).readonlyToken, tokenVisitor, isToken),
visitNode((<MappedTypeNode>node).typeParameter, visitor, isTypeParameter),
visitNode((<MappedTypeNode>node).questionToken, tokenVisitor, isToken),
visitNode((<MappedTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.LiteralType:
return updateLiteralTypeNode(<LiteralTypeNode>node,
visitNode((<LiteralTypeNode>node).literal, visitor, isExpression));
// Type Declarations
case SyntaxKind.TypeParameter:
return updateTypeParameterDeclaration(<TypeParameterDeclaration>node,
visitNode((<TypeParameterDeclaration>node).name, visitor, isIdentifier),
visitNode((<TypeParameterDeclaration>node).constraint, visitor, isTypeNode),
visitNode((<TypeParameterDeclaration>node).default, visitor, isTypeNode));
// Type members
case SyntaxKind.PropertySignature:
return updatePropertySignature((<PropertySignature>node),
visitNode((<PropertySignature>node).name, visitor, isPropertyName),
visitNode((<PropertySignature>node).questionToken, tokenVisitor, isToken),
visitNode((<PropertySignature>node).type, visitor, isTypeNode),
visitNode((<PropertySignature>node).initializer, visitor, isExpression));
case SyntaxKind.PropertyDeclaration:
return updateProperty(<PropertyDeclaration>node,
nodesVisitor((<PropertyDeclaration>node).decorators, visitor, isDecorator),
@ -267,8 +372,9 @@ namespace ts {
return updateMethod(<MethodDeclaration>node,
nodesVisitor((<MethodDeclaration>node).decorators, visitor, isDecorator),
nodesVisitor((<MethodDeclaration>node).modifiers, visitor, isModifier),
(<MethodDeclaration>node).asteriskToken,
visitNode((<MethodDeclaration>node).asteriskToken, tokenVisitor, isToken),
visitNode((<MethodDeclaration>node).name, visitor, isPropertyName),
visitNode((<MethodDeclaration>node).questionToken, tokenVisitor, isToken),
nodesVisitor((<MethodDeclaration>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<MethodDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<MethodDeclaration>node).type, visitor, isTypeNode),
@ -309,7 +415,7 @@ namespace ts {
case SyntaxKind.BindingElement:
return updateBindingElement(<BindingElement>node,
(<BindingElement>node).dotDotDotToken,
visitNode((<BindingElement>node).dotDotDotToken, tokenVisitor, isToken),
visitNode((<BindingElement>node).propertyName, visitor, isPropertyName),
visitNode((<BindingElement>node).name, visitor, isBindingName),
visitNode((<BindingElement>node).initializer, visitor, isExpression));
@ -362,7 +468,7 @@ namespace ts {
case SyntaxKind.FunctionExpression:
return updateFunctionExpression(<FunctionExpression>node,
nodesVisitor((<FunctionExpression>node).modifiers, visitor, isModifier),
(<FunctionExpression>node).asteriskToken,
visitNode((<FunctionExpression>node).asteriskToken, tokenVisitor, isToken),
visitNode((<FunctionExpression>node).name, visitor, isIdentifier),
nodesVisitor((<FunctionExpression>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<FunctionExpression>node).parameters, visitor, context, nodesVisitor),
@ -419,7 +525,7 @@ namespace ts {
case SyntaxKind.YieldExpression:
return updateYield(<YieldExpression>node,
(<YieldExpression>node).asteriskToken,
visitNode((<YieldExpression>node).asteriskToken, tokenVisitor, isToken),
visitNode((<YieldExpression>node).expression, visitor, isExpression));
case SyntaxKind.SpreadElement:
@ -555,7 +661,7 @@ namespace ts {
return updateFunctionDeclaration(<FunctionDeclaration>node,
nodesVisitor((<FunctionDeclaration>node).decorators, visitor, isDecorator),
nodesVisitor((<FunctionDeclaration>node).modifiers, visitor, isModifier),
(<FunctionDeclaration>node).asteriskToken,
visitNode((<FunctionDeclaration>node).asteriskToken, tokenVisitor, isToken),
visitNode((<FunctionDeclaration>node).name, visitor, isIdentifier),
nodesVisitor((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameter),
visitParameterList((<FunctionDeclaration>node).parameters, visitor, context, nodesVisitor),

View file

@ -2584,6 +2584,11 @@ namespace FourSlash {
}
}
public printAvailableCodeFixes() {
const codeFixes = this.getCodeFixActions(this.activeFile.fileName);
Harness.IO.log(stringify(codeFixes));
}
// Get the text of the entire line the caret is currently at
private getCurrentLineContent() {
const text = this.getFileContent(this.activeFile.fileName);
@ -3772,6 +3777,10 @@ namespace FourSlashInterface {
this.state.printCompletionListMembers();
}
public printAvailableCodeFixes() {
this.state.printAvailableCodeFixes();
}
public printBreakpointLocation(pos: number) {
this.state.printBreakpointLocation(pos);
}

View file

@ -191,7 +191,7 @@ namespace Utils {
for (const childName in node) {
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator" ||
// for now ignore jsdoc comments
childName === "jsDocComment") {
childName === "jsDocComment" || childName === "checkJsDirective") {
continue;
}
const child = (<any>node)[childName];

View file

@ -1,4 +1,4 @@
{
{
"extends": "../tsconfig-base",
"compilerOptions": {
"removeComments": false,
@ -81,6 +81,7 @@
"../services/codefixes/helpers.ts",
"../services/codefixes/importFixes.ts",
"../services/codefixes/unusedIdentifierFixes.ts",
"../services/codefixes/disableJsDiagnostics.ts",
"harness.ts",
"sourceMapRecorder.ts",

View file

@ -12,7 +12,8 @@ namespace ts {
it(`Correct output for ${outputFileName}`, () => {
Harness.Baseline.runBaseline(outputFileName, () => {
if (initResult) {
return JSON.stringify(initResult, undefined, 4);
// normalize line endings
return initResult.replace(new RegExp(sys.newLine, "g"), "\n");
}
else {
// This can happen if compiler recieve invalid compiler-options

View file

@ -1,80 +0,0 @@
{ input: "function foo () {}", rules: [ ], span: { start: 0, length: 20 }, expected: "function foo() { }" },
{ input: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 349 }, expected: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}" },
{ input: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 379 }, expected: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}" },
{ input: "this . alert( \"Hello, World!\" );", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 32 }, expected: "this.alert( \"Hello, World!\" );" },
{ input: "a\r\n;b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a\r\n; b;" },
{ input: "a\r\n; b;", rules: [ ], span: { start: 0, length: 8 }, expected: "a\r\n; b;" },
{ input: "var a , b;\r\nf(a , b);", rules: [ ], span: { start: 0, length: 40 }, expected: "var a, b;\r\nf(a, b);" },
{ input: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}", rules: [ "SpaceAfterKeywordInControl" ], span: { start: 0, length: 171 }, expected: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}" },
{ input: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}", rules: [ "NoSpaceAfterKeywordInControl" ], span: { start: 0, length: 177 }, expected: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}" },
{ input: "{\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 10 }, expected: "{\r\n (a);\r\n}" },
{ input: "var a=[1,2];\r\nvar b=8>>2 ;\r\nvar c=1+2;", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 14, length: 12 }, expected: "var a=[1,2];\r\nvar b = 8 >> 2;\r\nvar c=1+2;" },
{ input: "if (true) {\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 20 }, expected: "if (true) {\r\n (a);\r\n}" },
{ input: " // var a=[1,2];\r\n /*var a=[3,4];*/\r\n /*\r\n var a=[5,6];\r\n */", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 62 }, expected: "// var a=[1,2];\r\n/*var a=[3,4];*/\r\n/*\r\n var a=[5,6];\r\n */" },
{ input: "f ();", rules: [ ], span: { start: 0, length: 14 }, expected: "f();" },
{ input: "var a = { b: 1 , c: 2 };\r\nvar d = [1 , 2];", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 44 }, expected: "var a = { b: 1, c: 2 };\r\nvar d = [1, 2];" },
{ input: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();", rules: [ ], span: { start: 0, length: 124 }, expected: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();" },
{ input: "function a() { };", rules: [ ], span: { start: 0, length: 20 }, expected: "function a() { };" },
{ input: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 123 }, expected: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];" },
{ input: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 136 }, expected: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];" },
{ input: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 215 }, expected: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}" },
{ input: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 228 }, expected: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}" },
{ input: "function Sum(a, b, c) {\r\nvar d = 1;\r\n}", rules: [ ], span: { start: 0, length: 38 }, expected: "function Sum(a, b, c) {\r\n var d = 1;\r\n}" },
{ input: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };", rules: [ "SpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 76 }, expected: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };" },
{ input: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };", rules: [ "NoSpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 79 }, expected: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };" },
{ input: "function a() {\r\n}b;", rules: [ ], span: { start: 0, length: 19 }, expected: "function a() {\r\n} b;" },
{ input: "function a() {\r\n} b;", rules: [ ], span: { start: 0, length: 21 }, expected: "function a() {\r\n} b;" },
{ input: "function a(){return 0;}\r\nfunction b(){toString();return 0;}", rules: [ ], span: { start: 0, length: 59 }, expected: "function a() { return 0; }\r\nfunction b() { toString(); return 0; }" },
{ input: "for (var i = 0;i < 10;++i) { }", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (var i = 0; i < 10; ++i) { }" },
{ input: "for (var i = 0; i < 10; ++i) { }", rules: [ "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var i = 0;i < 10;++i) { }" },
{ input: "function f() {\r\nif (1)\r\n{\r\nvar a=0;\r\n}\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 41 }, expected: "function f()\n{\r\n if (1) {\r\n var a=0;\r\n }\r\n}" },
{ input: "function a(b) {\r\n a({\r\n});\r\n}", rules: [ ], span: { start: 0, length: 32 }, expected: "function a(b) {\r\n a({\r\n });\r\n}" },
{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 3, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" },
{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 21, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" },
{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 6, length: 15 }, expected: "eval(\"var a=b[1,2+3];\");" },
{ input: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 404 }, expected: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);" },
{ input: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 356 }, expected: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);" },
{ input: "for (var a = 0; a < 2; ++a) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a)\n{\r\n}" },
{ input: "for (var a = 0; a < 2; ++a)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a) {\r\n}" },
{ input: "function foo(a, b, c) { a = b + c;\n}", rules: [ "NewLineBeforeOpenCurlyInFunction", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 36 }, expected: "function foo(a, b, c)\n{\n a = b + c;\n}" },
{ input: "function a() {\r\n // comment\r\n}", rules: [ ], span: { start: 0, length: 33 }, expected: "function a() {\r\n // comment\r\n}" },
{ input: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}" },
{ input: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}" },
{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = ( 0 );\r\nvar b = ( 1 );\r\nvar c = ( 1 + 2 );\r\nvar d = ( ( 1 + 2 ) - ( 3 + 4 ) );\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );" },
{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 24 }, expected: "eval(\"var a=b[1,2+3];\");" },
{ input: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b)\r\n\r\n{\r\ni++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 53 }, expected: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b) {\r\n i++;\n}" },
{ input: "for (a in b) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b)\n{\r\n}" },
{ input: "for (a in b)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b) {\r\n}" },
{ input: " var a = { } ; \r\nvar b = { c : d, e : { } };\r\n ", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 59 }, expected: "var a = {};\r\nvar b = { c: d, e: {} };\r\n" },
{ input: "while (true) { }", rules: [ ], span: { start: 0, length: 19 }, expected: "while (true) { }" },
{ input: "for (a in b){ i++; }\r\n\r\nfor (a in b){ i++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 44 }, expected: "for (a in b) { i++; }\r\n\r\nfor (a in b) { i++; }" },
{ input: "function a() {\r\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a()\n{\r\n}" },
{ input: "function a()\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a() {\r\n}" },
{ input: "a;\r\nb;c;\r\nd;", rules: [ ], span: { start: 0, length: 12 }, expected: "a;\r\nb; c;\r\nd;" },
{ input: "a;\r\nb; c;\r\nd;", rules: [ ], span: { start: 0, length: 14 }, expected: "a;\r\nb; c;\r\nd;" },
{ input: " var a = 0;\r\n function b() {\r\n var c = 0;\r\n }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 61 }, expected: "var a = 0;\r\nfunction b() {\r\n var c = 0;\r\n}" },
{ input: "a;b;", rules: [ ], span: { start: 0, length: 4 }, expected: "a; b;" },
{ input: "a; b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a; b;" },
{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2) - (3 + 4));\r\n\r\nvar e = (0);\r\nvar f = (1);\r\nvar g = (1 + 2);\r\nvar h = ((1 + 2) - (3 + 4));" },
{ input: "function a() {\r\n(b);\r\n}", rules: [ ], span: { start: 0, length: 23 }, expected: "function a() {\r\n (b);\r\n}" },
{ input: "function test(a) {\n var i;\n for (i = 0;i < 1; i++){ //select\n a++;//select\n }\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "NewLineBeforeOpenCurlyInFunction", "SpaceAfterSemicolonInFor" ], span: { start: 30, length: 50 }, expected: "function test(a) {\n var i;\n for (i = 0; i < 1; i++)\n { //select\n a++;//select\n }\n}" },
{ input: "function a(){ return 1; }", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function a() { return 1; }" },
{ input: "do {\r\n} while (true);", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do\n{\r\n} while (true);" },
{ input: "do\n{\r\n} while (true);", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do {\r\n} while (true);" },
{ input: "for (;;) { a = b + c; b = 2;\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator", "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (;;)\n{\n a = b + c; b = 2;\n}" },
{ input: "var a =0;\r\n\r\n+ 1;\r\n+ a;\r\n+ (1);\r\n+ (+ 1);\r\n+ [1];\r\n+ [+ 1];\r\n+ this.a;\r\n+ new Number(+ 1);\r\n\r\n- 1;\r\n- a;\r\n- (1);\r\n- (- 1);\r\n- [1];\r\n- [- 1];\r\n- this.a;\r\n- new Number(- 1);\r\n\r\n~ 1;\r\n~ a;\r\n~ (1);\r\n~ (~ 1);\r\n~ [1];\r\n~ [~ 1];\r\n~ this.a;\r\n~ new Number(~ 1);\r\n\r\n! 1;\r\n! a;\r\n! (1);\r\n! (! 1);\r\n! [1];\r\n! [! 1];\r\n! this.a;\r\n! new Number(! 1);\r\n\r\n++ a;\r\n++ (a);\r\n++ this.a;\r\n++ new f().a;\r\n\r\n-- a;\r\n-- (a);\r\n-- this.a;\r\n-- new f().a;\r\n\r\na ++;\r\n(a) ++;\r\nthis.a ++;\r\nnew f().a ++;\r\n\r\na --;\r\n(a) --;\r\nthis.a --;\r\nnew f().a --;", rules: [ ], span: { start: 0, length: 513 }, expected: "var a =0;\r\n\r\n+1;\r\n+a;\r\n+(1);\r\n+(+1);\r\n+[1];\r\n+[+1];\r\n+this.a;\r\n+new Number(+1);\r\n\r\n-1;\r\n-a;\r\n-(1);\r\n-(-1);\r\n-[1];\r\n-[-1];\r\n-this.a;\r\n-new Number(-1);\r\n\r\n~1;\r\n~a;\r\n~(1);\r\n~(~1);\r\n~[1];\r\n~[~1];\r\n~this.a;\r\n~new Number(~1);\r\n\r\n!1;\r\n!a;\r\n!(1);\r\n!(!1);\r\n![1];\r\n![!1];\r\n!this.a;\r\n!new Number(!1);\r\n\r\n++a;\r\n++(a);\r\n++this.a;\r\n++new f().a;\r\n\r\n--a;\r\n--(a);\r\n--this.a;\r\n--new f().a;\r\n\r\na++;\r\n(a)++;\r\nthis.a++;\r\nnew f().a++;\r\n\r\na--;\r\n(a)--;\r\nthis.a--;\r\nnew f().a--;" },
{ input: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" },
{ input: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" },
{ input: "function a()\r\n\r\n\r\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 22 }, expected: "function a() {\r\n}" },
{ input: "try {\r\n} catch (e) {\r\n} finally {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}" },
{ input: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try {\r\n} catch (e) {\r\n} finally {\r\n}" },
{ input: "with (a) {\r\n b = 0;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a)\n{\r\n b = 0;\r\n}" },
{ input: "with (a)\n{\r\n b = 0;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a) {\r\n b = 0;\r\n}" },
{ input: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b<a?a:b;\r\nc=true&&false||true;\r\nc=a==b;\r\nc=a===b;\r\nc=a!=b;\r\nc=a!==b;\r\nc=a<=b;\r\nc=a>=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 366 }, expected: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }" },
{ input: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 480 }, expected: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b<a?a:b;\r\nc=true&&false||true;\r\nc=a==b;\r\nc=a===b;\r\nc=a!=b;\r\nc=a!==b;\r\nc=a<=b;\r\nc=a>=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }" },
{ input: "function foo()\n\n{ a = 1\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function foo()\n{\n a = 1\n}" },
{ input: "while (true) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true)\n{\r\n}" },
{ input: "while (true)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true) {\r\n}" },
{ input: "var z = 1;\r\n for (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\nfor (k = 0; k < 10; ++k)\r\n{\r\nz++;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 117 }, expected: "var z = 1;\r\nfor (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\n for (k = 0; k < 10; ++k) {\r\n z++;\r\n }" },
{ input: "a++;b++;\nfor (; ; ) {\nx++;m++;\n}", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "a++; b++;\nfor (; ; ) {\n x++; m++;\n}" },
{ input: "var a;\r\n $(document).ready(function() {\r\n alert('hello');\r\n});\r\n", rules: [ ], span: { start: 0, length: 117 }, expected: "var a;\r\n$(document).ready(function () {\r\n alert('hello');\r\n});\r\n" }

View file

@ -1,66 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.code
{
font-family: Lucida Console;
font-size: 80%;
}
table
{
border: solid black 1px;
margin-bottom: 2em;
background: #F5F5F5;
padding: 0.5em;
}
th
{
text-align: left;
padding-left: 1em;
}
td
{
vertical-align: top;
padding: 0.75em;
margin: 0.25em;
}
td.test-input
{
background: #DDE;
}
td.test-output
{
background: #FEE;
}
td.test-expected
{
background: #EFE;
}
td.test-operation
{
font-family: inherit;
padding: 0.1em;
}
</style>
<script type="text/javascript">
function copy(code) {
if (window.clipboardData) {
window.clipboardData.setData('Text', decodeURIComponent(code));
} else {
alert(code);
}
}
</script>
</head>
<body>

View file

@ -1,88 +0,0 @@
///<reference path='_project.ts'/>
describe('getFormattingEditsForRange', function() {
//
// Verify that formatting the typescript file "sourceFileName" results in the
// baseline file "baselineFileName".
//
function getFormattingEditsForRange(sourceFileName: string) {
var baselineFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + "BaseLine.ts";
sourceFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + ".ts";
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addDefaultLibrary();
typescriptLS.addFile(sourceFileName);
var ls = typescriptLS.getLanguageService();
var script = ls.languageService.getScriptAST(sourceFileName);
assert.notNull(script);
var edits = ls.languageService.getFormattingEditsForRange(sourceFileName, 0, script.limChar, new Services.FormatCodeOptions());
typescriptLS.checkEdits(sourceFileName, baselineFileName, edits);
}
describe('test cases for formatting engine', function() {
it("formats typescript constructs properly", function() {
getFormattingEditsForRange('typescriptConstructs');
});
it("formats document ready function properly", function() {
getFormattingEditsForRange('documentReadyFunction');
});
it("formats on closing bracket properly", function() {
getFormattingEditsForRange('onClosingBracket');
});
it("formats various javascript constructs", function() {
getFormattingEditsForRange('various');
});
it("formats main javascript program", function() {
getFormattingEditsForRange('main');
});
it("formats on semicolon properly", function() {
getFormattingEditsForRange('onSemiColon');
});
it("formats enum with trailling tab characters properly", function() {
getFormattingEditsForRange('tabAfterCloseCurly');
});
it("formats object literal", function() {
getFormattingEditsForRange('objectLiteral');
});
it("formats with statements", function() {
getFormattingEditsForRange('withStatement');
});
it("formats ':' and '?' in parameters", function() {
getFormattingEditsForRange('colonAndQMark');
});
it("formats 'import' declaration", function() {
getFormattingEditsForRange('importDeclaration');
});
it("formats exported class with implicit module", function() {
//TODO: this is to force generation of implicit module in AST
var svGenTarget = TypeScript.moduleGenTarget;
try {
TypeScript.moduleGenTarget = TypeScript.ModuleGenTarget.Asynchronous;
getFormattingEditsForRange('implicitModule');
}
finally {
TypeScript.moduleGenTarget = svGenTarget;
}
});
it("formats constructor statements correctelly", function() {
getFormattingEditsForRange('spaceAfterConstructor');
});
it("formats classes and interfaces correctelly", function() {
getFormattingEditsForRange('classes');
});
it("formats modules correctly", function() {
getFormattingEditsForRange('modules');
});
it("formats fat arrow expressions correctelly", function() {
getFormattingEditsForRange('fatArrowFunctions');
});
it("formats empty object/interface literals correctelly", function() {
getFormattingEditsForRange('emptyInterfaceLiteral');
});
it("formats variable declaration lists", function() {
getFormattingEditsForRange('formatVariableDeclarationList');
});
});
});

View file

@ -1,410 +0,0 @@
///<reference path='_project.ts'/>
describe('getSmartIndentAtLineNumber', function() {
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addDefaultLibrary();
var fileName = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber.ts';
var fileName2 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber2.ts';
var fileName3 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber3.ts';
typescriptLS.addFile(fileName);
typescriptLS.addFile(fileName2);
typescriptLS.addFile(fileName3);
var ls = typescriptLS.getLanguageService();
//
// line is 1-based
//
function getSmartIndent(fileName: string, line: number): number {
assert.is(line >= 1);
var options = new Services.EditorOptions();
var position = typescriptLS.lineColToPosition(fileName, line, 1);
return ls.languageService.getSmartIndentAtLineNumber(fileName, position, options);
}
describe("test cases for smart indent", function() {
it("smart indent inside module", function() {
var result = getSmartIndent(fileName, 2);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside class", function() {
var result = getSmartIndent(fileName, 4);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after property in class", function() {
var result = getSmartIndent(fileName, 6);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent inside method in class ", function() {
var result = getSmartIndent(fileName, 9);
assert.notNull(result);
assert.equal(12, result);
});
it("smart indent after after method in class", function() {
var result = getSmartIndent(fileName, 12);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after class", function() {
var result = getSmartIndent(fileName, 17);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent in interface", function() {
var result = getSmartIndent(fileName, 19);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after property in interface", function() {
var result = getSmartIndent(fileName, 21);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after method in interface", function() {
var result = getSmartIndent(fileName, 23);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after interface", function() {
var result = getSmartIndent(fileName, 25);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent in nested module", function() {
var result = getSmartIndent(fileName, 27);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after function in nested module", function() {
var result = getSmartIndent(fileName, 30);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after variable in nested module", function() {
var result = getSmartIndent(fileName, 32);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after nested module", function() {
var result = getSmartIndent(fileName, 34);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent in enum", function() {
var result = getSmartIndent(fileName, 36);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after variable in enum", function() {
var result = getSmartIndent(fileName, 38);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 2nd variable in enum", function() {
var result = getSmartIndent(fileName, 40);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after enum", function() {
var result = getSmartIndent(fileName, 42);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent after module", function() {
var result = getSmartIndent(fileName, 44);
assert.notNull(result);
assert.equal(0, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent after an aligned function argument", function() {
var result = getSmartIndent(fileName, 47);
assert.notNull(result);
assert.equal(13, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent inside a 'for' statement", function() {
var result = getSmartIndent(fileName, 53);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'for' statement", function() {
var result = getSmartIndent(fileName, 55);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'for in' statement", function() {
var result = getSmartIndent(fileName, 57);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'for in' statement", function() {
var result = getSmartIndent(fileName, 59);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'with' statement", function() {
var result = getSmartIndent(fileName, 61);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'with' statement", function() {
var result = getSmartIndent(fileName, 63);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'switch' statement", function() {
var result = getSmartIndent(fileName, 65);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'switch' statement", function() {
var result = getSmartIndent(fileName, 67);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside a 'break' statement", function() {
var result = getSmartIndent(fileName, 69);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after a 'break' statement", function() {
var result = getSmartIndent(fileName, 71);
assert.notNull(result);
assert.equal(12, result);
});
it("smart indent after a 'break' statement", function() {
var result = getSmartIndent(fileName, 73);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after last 'switch' statement", function() {
var result = getSmartIndent(fileName, 75);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent before 'try' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 79);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent insde 'try' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 81);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'catch' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 83);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'catch' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 85);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 'catch' in 'try/catch' statement", function() {
var result = getSmartIndent(fileName, 87);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent before 'try' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 92);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent insde 'try' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 94);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'finally' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 96);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'finally' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 98);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 'finally' in 'try/finally' statement", function() {
var result = getSmartIndent(fileName, 100);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent before 'try' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 104);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent insde 'try' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 106);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'catch' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 108);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'catch' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 110);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent before 'finally' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 112);
assert.notNull(result);
assert.equal(4, result);
});
it("smart indent inside 'finally' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 114);
assert.notNull(result);
assert.equal(8, result);
});
it("smart indent after 'finally' in 'try/catch/finally' statement", function() {
var result = getSmartIndent(fileName, 116);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent inside a block inside case", function() {
var result = getSmartIndent(fileName, 127);
assert.notNull(result);
assert.equal(20, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent works for a non terminated argument list at the end of a file", function() {
var result = getSmartIndent(fileName2, 8);
assert.notNull(result);
assert.equal(4, result);
});
///////////////////////////////////////////////////////////////////////
it("smart indent works for a non terminated if statement at the end of a file", function() {
var result = getSmartIndent(fileName3, 7);
assert.notNull(result);
assert.equal(4, result);
});
});
});

View file

@ -1,212 +0,0 @@
/// <reference path='..\..\..\..\src\harness\harness.ts'/>
/// <reference path="..\..\..\..\src\services\formatting\formatting.ts"/>
interface DocumentTestJson {
input: string;
rules: string[];
span: { start: number; length: number; };
expected: string;
}
interface FormatOperationTestJson {
input: string;
operations: {
operation: string;
point: { position: number; };
span: { start: number; length: number; };
}[];
expected: string;
}
function markupCodeForHtml(code: string) {
var formatted = code.replace(/</g, '&lt;').replace(/ /g, '&#183;').replace(/\t/g, '&nbsp;&rarr;&nbsp;').replace(/\n/g,'&#8629;<br>');
var escaped = encodeURIComponent(code).replace(/'/g, '%27');
return formatted + '<br><a href="javascript:;" onclick="copy(\'' + escaped + '\');">Copy</a>';
}
describe('importedJavaScriptFormatting - formatting rules', function() {
var documentTests: DocumentTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/documentFormattingTests.json').contents() + ']');
var outputFile = 'diff-1.html';
IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false);
var checkTest = function(test: DocumentTestJson) {
var filename = 'temp.ts';
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addScript(filename, test.input);
var ls = typescriptLS.getLanguageService().languageService;
var unsupportedRules = [];
var ruleMap = {
'SpaceAfterSemicolonInFor': 'InsertSpaceAfterSemicolonInForStatements',
'SpaceAfterComma': 'InsertSpaceAfterCommaDelimiter',
'NewLineBeforeOpenCurlyInControl': 'PlaceOpenBraceOnNewLineForControlBlocks',
'NewLineBeforeOpenCurlyInFunction': 'PlaceOpenBraceOnNewLineForFunctions'
};
var options = new Services.FormatCodeOptions();
if (test.rules.indexOf('SpaceBeforeBinaryOperator') >= 0 && test.rules.indexOf('SpaceAfterBinaryOperator') >= 0) {
test.rules.splice(test.rules.indexOf('SpaceBeforeBinaryOperator'), 1);
test.rules.splice(test.rules.indexOf('SpaceAfterBinaryOperator'), 1);
options.InsertSpaceBeforeAndAfterBinaryOperators = true;
}
test.rules.forEach(ruleName => {
if (options[ruleName] !== undefined) {
// The options struct has a matching property, just set it directly
options[ruleName] = true;
} else {
if (ruleMap[ruleName] !== undefined) {
// We have a remapping of this name, use that instead
options[ruleMap[ruleName]] = true;
} else {
if (ruleName.indexOf('No') === 0) {
// This is a 'NoFoo', set 'Foo' to false
options[ruleMap[ruleName.substr(2)]] = false;
} else {
// ??
IO.printLine('Unsupported rule name ' + ruleName);
return;
}
}
}
});
var edits = ls.getFormattingEditsForRange(filename, test.span.start, test.span.start + test.span.length, options);
var output = typescriptLS.applyEdits(test.input, edits);
// Normalize line endings
output = output.replace(/\r\n/g, '\n');
test.expected = test.expected.replace(/\r\n/g, '\n');
if (output != test.expected) {
var outputHtml = '';
outputHtml += '<table class="test-table">';
outputHtml += '<tr class="test-header-row">';
outputHtml += '<th>Input</th><th>Output</th><th>Expected</th>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-results-row">';
outputHtml += '<td class="test-input code">' + markupCodeForHtml(test.input) + '</td>';
outputHtml += '<td class="test-output code">' + markupCodeForHtml(output) + '</td>';
outputHtml += '<td class="test-expected code">' + markupCodeForHtml(test.expected) + '</td>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-operations-row">';
outputHtml += '<td colspan="3">Format from character ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules: ' + test.rules.join(', ') + '</td>';
outputHtml += '</tr>';
outputHtml += '</table>'; // test-table
IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false);
// TODO: Uncomment when things are working
// throw new Error("Formatting failed - refer to diff-1.html");
}
}
var i = 0;
for (var i = 0; i < documentTests.length; i++) {
var test = documentTests[i];
var msg = 'formats the code (index ' + i + ') from ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules = [' + test.rules.join(', ') + '] correctly';
it(msg, function(t) {
return function() {
checkTest(t);
}
}(test));
}
});
describe('importedJavaScriptFormatting - formatting operations', function() {
var outputFile = 'diff-2.html';
IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false);
var checkTest = function(test: FormatOperationTestJson) {
var filename = 'temp.ts';
var typescriptLS = new Harness.TypeScriptLS();
typescriptLS.addScript(filename, test.input);
var ls = typescriptLS.getLanguageService();
var operationsText = '';
var markedUpInput = test.input;
var output = test.input;
for (var i = 0; i < test.operations.length; i++) {
var options = new Services.FormatCodeOptions();
var op = test.operations[i];
var edits: Services.TextEdit[];
if (op.operation === 'CloseBrace') {
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '}', options);
operationsText += 'Format for } at position ' + op.point.position.toString();
markedUpInput = markedUpInput.substring(0, op.point.position) + '&#10026;' + markedUpInput.substring(op.point.position);
} else if (op.operation === 'Enter') {
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '\n', options);
operationsText += 'Format for [enter] at position ' + op.point.position.toString();
markedUpInput = markedUpInput.substring(0, op.point.position) + '&#10026;' + markedUpInput.substring(op.point.position);
} else if (op.operation === 'Semicolon') {
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, ';', options);
operationsText += 'Format for ; at position ' + op.point.position.toString();
markedUpInput = markedUpInput.substring(0, op.point.position) + '&#10026;' + markedUpInput.substring(op.point.position);
} else if (op.operation === 'Document') {
edits = ls.languageService.getFormattingEditsForRange(filename, 0, output.length, options);
operationsText += 'Format Document';
} else if (op.operation === 'Selection') {
edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options);
operationsText += 'Format selection from ' + op.span.start + ', length = ' + op.span.length;
} else if (op.operation === 'Paste') {
edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options);
operationsText += 'Format pasted content from ' + op.span.start + ', length = ' + op.span.length;
} else {
throw new Error('Unknown operation: ' + op.operation);
}
output = typescriptLS.applyEdits(test.input, edits);
typescriptLS.updateScript(filename, output);
}
// Normalize line endings
output = output.replace(/\r\n/g, '\n');
test.expected = test.expected.replace(/\r\n/g, '\n');
var outputHtml = '';
outputHtml += '<table class="test-table">';
outputHtml += '<tr class="test-header-row">';
outputHtml += '<th>Input</th><th>Output</th><th>Expected</th>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-results-row">';
outputHtml += '<td class="test-input code">' + markupCodeForHtml(markedUpInput) + '</td>';
outputHtml += '<td class="test-output code">' + markupCodeForHtml(output) + '</td>';
outputHtml += '<td class="test-expected code">' + markupCodeForHtml(test.expected) + '</td>';
outputHtml += '</tr>';
outputHtml += '<tr class="test-operations-row">';
outputHtml += '<td colspan="3">' + operationsText + '</td>';
outputHtml += '</tr>';
outputHtml += '</table>'; // test-table
if (test.expected == output) {
// Pass
} else {
IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false);
// TODO: Uncomment when things are working
// throw new Error('Format test failed - refer to ' + outputFile);
}
}
var operationsTests: FormatOperationTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/ruleFormattingTests.json').contents() + ']');
for (var i = 0; i < operationsTests.length; i++) {
var test = operationsTests[i];
var msg = 'formats the text correctly, line = ' + i;
it(msg, function(t) {
return function() {
checkTest(t);
}
}(test));
}
});

View file

@ -1,284 +0,0 @@
{ input: "function a() {\r\nvar b = 0;//}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//}\r\n}" },
{ input: "function foo() {\n do {\n } while (y < 10)\n\n}", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "function foo() {\n do {\n } while (y < 10)\n\n}" },
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n}\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 87 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n\r\n}" },
{ input: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 76 } } ], expected: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}" },
{ input: " if ( a[\";\"])\r\nb++;", operations: [ { operation: "Semicolon", point: { position: 10 } } ], expected: " if ( a[\";\"])\r\nb++;" },
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" },
{ input: "var obj={a:{b:2,c:{d:{e:{\r\n}}}}}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d: {\n e: {\r\n }\n }\n }\n }\n}" },
{ input: "if(1)if(1)if(1)if(1)x+=2;", operations: [ { operation: "Semicolon", point: { position: 25 } } ], expected: "if (1) if (1) if (1) if (1) x += 2;" },
{ input: "\r\nvar webclass = [\r\n { 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]", operations: [ { operation: "Document" } ], expected: "\r\nvar webclass = [\r\n {\n 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]" },
{ input: "function f(x){ return x }\nwhile (f(true))\n y++;\n", operations: [ { operation: "Enter", point: { position: 51 } } ], expected: "function f(x){ return x }\nwhile (f(true))\n y++;\n" },
{ input: "throw e;", operations: [ { operation: "Document" } ], expected: "throw e;" },
{ input: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}", operations: [ { operation: "Document" } ], expected: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}" },
{ input: "return 1;", operations: [ { operation: "Document" } ], expected: "return 1;" },
{ input: "var x = [\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n 1,\n 2,\n 3\n]" },
{ input: "switch \r\n( a ){\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "switch\r\n(a) {\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\n test;\r\n" },
{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 16 } } ], expected: "do{\r\ndo{\r\n do {\r\n } while (a !== b)\r\n}while(a!==b)\r\n}while(a!==b)" },
{ input: "label1:\r\nvar a;\r\nvar b;", operations: [ { operation: "Document" } ], expected: "label1:\r\n var a;\r\nvar b;" },
{ input: "\r\nfunction a() {\r\nfunction test() // test\r\n{\r\nif (test) // test\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() // test\r\n {\r\n if (test) // test\r\n {\r\n }\r\n }\r\n}" },
{ input: "var obj = {\r\na:{\r\nb:2,c:{\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() +f();\r\n}\r\n}\r\n}\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 94 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\r\n};" },
{ input: "function f() {\r\n do{\r\nx++ }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n do{\r\n x++\n }\r\n\r\n}" },
{ input: "function foo (a, b, c)", operations: [ { operation: "Document" } ], expected: "function foo(a, b, c)" },
{ input: "{ var b;\n}", operations: [ { operation: "Document" } ], expected: "{\n var b;\n}" },
{ input: "var z = {\na: 1};", operations: [ { operation: "Document" } ], expected: "var z = {\n a: 1\n};" },
{ input: "for (var i = 0; i < 10; i++)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) {\n var a\n}" },
{ input: "if (1)\n {\nvar a }", operations: [ { operation: "Document" } ], expected: "if (1) {\n var a\n}" },
{ input: "while (1)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "while (1) {\n var a\n}" },
{ input: "do\n { var a\n} while (1)", operations: [ { operation: "Document" } ], expected: "do {\n var a\n} while (1)" },
{ input: "for (var a in b)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var a in b) {\n var a\n}" },
{ input: "with (x)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "with (x) {\n var a\n}" },
{ input: "try\n { var a\n} \ncatch (e)\n { var a\n} \nfinally\n {\n}", operations: [ { operation: "Document" } ], expected: "try {\n var a\n}\ncatch (e) {\n var a\n}\nfinally {\n}" },
{ input: "switch (x)\n { case 1: { var a }\n}", operations: [ { operation: "Document" } ], expected: "switch (x) {\n case 1: { var a }\n}" },
{ input: "function f()\n { var x\n}", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" },
{ input: "if(1)if(1)if(1)if(1){x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 28 } } ], expected: "if (1) if (1) if (1) if (1) {\n x += 2\r\n}" },
{ input: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i=0;i<10;i++)\r\ni --;\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 84 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i = 0; i < 10; i++)\r\n i--;\r\n}\r\n" },
{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 42 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1);" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++)\r\n{j-=i}}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++)\r\n { j -= i }\n}" },
{ input: "function f() {\r\nstring='string\\r\n line2' + 'other part'}", operations: [ { operation: "CloseBrace", point: { position: 63 } } ], expected: "function f() {\r\n string = 'string\\r\n line2' + 'other part'\n}" },
{ input: "x =\r\n function ()\r\n{\r\n var a\r\n}", operations: [ { operation: "Document" } ], expected: "x =\r\n function () {\r\n var a\r\n }" },
{ input: "if (a instanceof b) { }", operations: [ { operation: "Document" } ], expected: "if (a instanceof b) { }" },
{ input: "do a++; while (0)", operations: [ { operation: "Document" } ], expected: "do a++; while (0)" },
{ input: "foo\r\n(1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo\r\n(1, 2, 3)" },
{ input: "if(1) //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "if (1) //comment\r\n{\r\n}\r\n" },
{ input: "var x =\n [\n1\n]", operations: [ { operation: "Document" } ], expected: "var x =\n [\n1\n ]" },
{ input: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}" },
{ input: "\r\ndefine(null,\r\n function test() {\r\nvar a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\ndefine(null,\r\n function test() {\r\n var a;\r\n }\r\n" },
{ input: "x = [\r\n 1,\r\n\r\n]", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "x = [\r\n 1,\r\n\r\n]" },
{ input: "var x =\n {\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x =\n {\n a: 1\n }" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" },
{ input: "function f()\n{\n for (a in b)\n a++;\n}", operations: [ { operation: "Semicolon", point: { position: 40 } } ], expected: "function f()\n{\n for (a in b)\n a++;\n}" },
{ input: "if(x!=1^y===2) \r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 25 } } ], expected: "if(x!=1^y===2) \r\n x += 2\r\n" },
{ input: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\nelse\r\n x+=2\r\n", operations: [ { operation: "Enter", point: { position: 81 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\n else\r\n x += 2\r\n" },
{ input: "switch (a){\r\ncase 1 : x+=2 ; break;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 44 } } ], expected: "switch (a){\r\n case 1: x += 2; break;\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "{ { {\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 19 } } ], expected: "{ { {\r\n {\r\n test\r\n }\r\n}\r\n}\r\n}" },
{ input: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n} while (a !== b)\r\n} while (a !== b)", operations: [ { operation: "Enter", point: { position: 55 } } ], expected: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n } while (a !== b)\r\n} while (a !== b)" },
{ input: "\r\nswitch (t) {\r\n case 1:\r\n{\r\ntest\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (t) {\r\n case 1:\r\n {\r\n test\r\n }\r\n}\r\n" },
{ input: "if (true) {\r\n \r\n}", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n\r\n}" },
{ input: "for(var j=0;j<10;j++)\r\nj-=i;", operations: [ { operation: "Semicolon", point: { position: 28 } } ], expected: "for (var j = 0; j < 10; j++)\r\n j -= i;" },
{ input: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}" },
{ input: "if(1)if(1)if(1)if(1)x+=2\r\n", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) x += 2\r\n" },
{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b)\r\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b)\r\n" },
{ input: "foo(\r\n)", operations: [ { operation: "Document" } ], expected: "foo(\r\n)" },
{ input: "function f() {\r\n'use strict';\r\n}", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict';\r\n}" },
{ input: "var x = function() {\n//comment\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x = function () {\n //comment\n return 1;\n}" },
{ input: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }", operations: [ { operation: "Selection", span: { start: 62, length: 120 } } ], expected: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }" },
{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 46 } } ], expected: "do {\r\n do {\r\n do {\r\n } while (a !== b)\r\n } while (a !== b)\r\n} while (a !== b)" },
{ input: "if (true)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "if (true)\n // test\n test;" },
{ input: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}" },
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 56 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\n}" },
{ input: " var a = 0 ;", operations: [ { operation: "Semicolon", point: { position: 14 } } ], expected: "var a = 0;" },
{ input: "var obj={a:{b:2,c:{d:\r\n{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d:\r\n { e: {} }\n }\n }\n}" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 74 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n}" },
{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n}\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 96 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\n}" },
{ input: "if (x!=1^y===2){ x+=2}", operations: [ { operation: "CloseBrace", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) { x += 2 }" },
{ input: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n", operations: [ { operation: "Enter", point: { position: 58 } } ], expected: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){\r\nj-=i}}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}" },
{ input: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n }\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 67 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" },
{ input: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}" },
{ input: "{ { {\r\n{\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 13 } } ], expected: "{ { {\r\n {\r\n }\r\n}\r\n}\r\n}" },
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\nj -= i}}\r\n", operations: [ { operation: "Enter", point: { position: 78 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}\r\n" },
{ input: "var a = {\r\n}", operations: [ { operation: "Document" } ], expected: "var a = {\r\n}" },
{ input: "\r\n switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 2 } } ], expected: "\r\nswitch (a) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "function a() {\r\nvar b = 0;//;\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//;\r\n}" },
{ input: "for (a in b) { }", operations: [ { operation: "Document" } ], expected: "for (a in b) { }" },
{ input: "\r\n{\r\nfunction test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n// test\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n function test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n // test\r\n }\r\n}\r\n" },
{ input: " //\r\n", operations: [ { operation: "Enter", point: { position: 8 } } ], expected: "//\r\n" },
{ input: " if ( a[\"}\"])\r\nb++;", operations: [ { operation: "CloseBrace", point: { position: 10 } } ], expected: " if ( a[\"}\"])\r\nb++;" },
{ input: "$ ( document ) . ready ( function ( ) { \n alert ( \"i am ready\" ) ;\n } );", operations: [ { operation: "Semicolon", point: { position: 138 } } ], expected: "$(document).ready(function () {\n alert(\"i am ready\");\n});" },
{ input: "function f() {\r\nvar s=\"string\";\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function f() {\r\n var s = \"string\";\r\n}" },
{ input: "do{for(var i=0;i<10;i++)i-=2\r\n}while(1!==1)", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "do {\n for (var i = 0; i < 10; i++) i -= 2\r\n} while (1 !== 1)" },
{ input: "do{\r\ndo{\r\n\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 12 } } ], expected: "do{\r\ndo{\r\n\r\n do {\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 49 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i }}" },
{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n } \r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 99 } } ], expected: "var obj = {\r\na: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n}\r\n}" },
{ input: "var a = 0 ;var b=0;var c = 0 ;", operations: [ { operation: "Paste", span: { start: 13, length: 7 } } ], expected: "var a = 0; var b = 0; var c = 0;" },
{ input: "function a()\r\n{\r\n}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "function a()\r\n{\r\n}" },
{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 25 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n test\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" },
{ input: " \r\nfunction a() { \r\n return; \r\n} \r\n ", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n return;\r\n}\r\n" },
{ input: "foo(\r\n1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(\r\n1, 2, 3)" },
{ input: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}" },
{ input: "\r\n //function start\r\n function abc() { }\r\n //function end\r\n", operations: [ { operation: "Document" } ], expected: "\r\n//function start\r\nfunction abc() { }\r\n//function end\r\n" },
{ input: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n\r\n}\r\n}" },
{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n" },
{ input: "x = {\r\n a: function() {\r\n},\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n a: function() {\r\n },\r\n\r\n}" },
{ input: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\n x += 2\r\n" },
{ input: "for (a in b) {\nx++;}\n", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "for (a in b) {\n x++;\n}\n" },
{ input: "if(1)if(1)if(1)if(1){x+=2}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) { x += 2 }" },
{ input: "if (x!=1^y===2){ x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (x != 1 ^ y === 2) {\n x += 2\r\n}" },
{ input: "var d = new Date ()", operations: [ { operation: "Document" } ], expected: "var d = new Date()" },
{ input: "do {\r\n} while (1 == 10);", operations: [ { operation: "Document" } ], expected: "do {\r\n} while (1 == 10);" },
{ input: "string='string+=2';", operations: [ { operation: "Semicolon", point: { position: 19 } } ], expected: "string = 'string+=2';" },
{ input: "function foo() {\r\n try {\r\n }\r\ncatch(e){\r\n } finally {\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function foo() {\r\n try {\r\n }\r\n catch (e) {\r\n } finally {\r\n }\r\n}" },
{ input: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n" },
{ input: "function f() {\r\n /**/ var x;\r\n}", operations: [ { operation: "Semicolon", point: { position: 39 } } ], expected: "function f() {\r\n /**/ var x;\r\n}" },
{ input: "if (a)\r\ntest;\r\nelse if (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse if (b)\r\n test;" },
{ input: "foo(1, 2, 3\r\n)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3\r\n)" },
{ input: "\r\nswitch (a){\r\n case 1: x++;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (a) {\r\n case 1: x++;\r\n}\r\n" },
{ input: "x = {\r\n a: function () {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "x = {\r\n a: function () {\r\n\r\n }\r\n}" },
{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" },
{ input: "string='string+=2;'", operations: [ { operation: "Semicolon", point: { position: 18 } } ], expected: "string='string+=2;'" },
{ input: "function test() {\r\n function foo() {\r\n var a;\r\n// some\r\ncomment\r\n", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "function test() {\r\n function foo() {\r\n var a;\r\n // some\r\n comment\r\n" },
{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;}\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 89 } } ], expected: "switch (a) {\r\n case 1: x += 2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\n }\r\n }\r\n}" },
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2;\r\n}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 33 } } ], expected: "do{\r\n for (var i = 0; i < 10; i++)\r\n i -= 2;\r\n}while(1!==1)" },
{ input: "\r\nfunction foo() {\r\n try{ } catch (e) { } finally { }\r\n\r\n\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "\r\nfunction foo() {\r\n try { } catch (e) { } finally { }\r\n\r\n\r\n}\r\n" },
{ input: "do{for(var i=0;i<10;i++)\r\ni-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "do {\n for (var i = 0; i < 10; i++)\r\n i -= 2\n} while (1 !== 1)" },
{ input: "\r\n fun(\r\n {\r\n a: 1\r\n });\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfun(\r\n {\r\n a: 1\r\n });\r\n" },
{ input: "function f () //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "function f() //comment\r\n{\r\n}\r\n" },
{ input: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 94 } } ], expected: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}" },
{ input: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 34 } } ], expected: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}" },
{ input: " \r\n do{\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "\r\ndo {\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" },
{ input: "function test() {\r\n label1:\r\nvar a\r\n\r\n var b;\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "function test() {\r\n label1:\r\n var a\r\n\r\n var b;\r\n}" },
{ input: "var x = {\n//comment\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x = {\n //comment\n a: 1\n}" },
{ input: "for(var i=0;i<10;i++){\r\n\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "for(var i=0;i<10;i++){\r\n\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n}\r\n}" },
{ input: "if (true) {\r\n//\r\n} else if (false) {\r\n//\r\n} else\r\n if (true)\r\n//", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n //\r\n} else if (false) {\r\n //\r\n} else\r\n if (true)\r\n //" },
{ input: "x = [\n 1,\n 1\n +\n // test\n 2\n]", operations: [ { operation: "Document" } ], expected: "x = [\n 1,\n 1\n +\n // test\n 2\n]" },
{ input: "var x =\n function() {\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x =\n function () {\n return 1;\n }" },
{ input: "function f() {\n var x }", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" },
{ input: "switch (a) {\r\n case 1: b++;\r\n break ;\r\n\r\n default: a++;\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\r\n case 1: b++;\r\n break;\r\n\r\n default: a++;\r\n break;\r\n}" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}" },
{ input: "function f(a, b\n , c){\n}", operations: [ { operation: "CloseBrace", point: { position: 39 } } ], expected: "function f(a, b\n , c) {\n}" },
{ input: "function add(a, b) { return a + b}", operations: [ { operation: "Document" } ], expected: "function add(a, b) { return a + b }" },
{ input: "var a = 0 ;\r\n", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "var a = 0;\r\n" },
{ input: "var a = function (b) {\r\nb = 0;\r\n}", operations: [ { operation: "CloseBrace", point: { position: 33 } } ], expected: "var a = function (b) {\r\n b = 0;\r\n}" },
{ input: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n" },
{ input: " var a = 0 ;\r\n var b = { } ;\r\n var c = false ;", operations: [ { operation: "Selection", span: { start: 18, length: 34 } } ], expected: " var a = 0 ;\r\n var b = {};\r\n var c = false ;" },
{ input: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 93 } } ], expected: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}" },
{ input: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}" },
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();", operations: [ { operation: "Document" } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();" },
{ input: "function a() {\r\n /**/ }", operations: [ { operation: "Document" } ], expected: "function a() {\r\n /**/\n}" },
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\nj=i;\r\n }\r\n}", operations: [ { operation: "Semicolon", point: { position: 64 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\n j = i;\r\n }\r\n}" },
{ input: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}" },
{ input: "foo (1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3)" },
{ input: "if (typeof a == null);", operations: [ { operation: "Document" } ], expected: "if (typeof a == null);" },
{ input: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}" },
{ input: "void x;", operations: [ { operation: "Document" } ], expected: "void x;" },
{ input: "function f() {\r\n string='string'\r\n }\r\n", operations: [ { operation: "Enter", point: { position: 44 } } ], expected: "function f() {\r\n string='string'\r\n}\r\n" },
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 48 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n} while (1 !== 1);" },
{ input: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}" },
{ input: "for(var i=0;i<10;i++)\r\n{for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (var i = 0; i < 10; i++)\r\n{ for (var j = 0; j < 10; j++) { j -= i } }" },
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) { j -= i }\n}" },
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1)\r\n", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n} while (1 !== 1)\r\n" },
{ input: "if(1===1\r\n&& 2===2)x+=2", operations: [ { operation: "Enter", point: { position: 10 } } ], expected: "if (1 === 1\r\n&& 2 === 2) x += 2" },
{ input: "\r\n{\r\n\r\n/* test\r\n test2\r\n test3 */\r\nvar a,\r\n // test\r\n // test\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n}\r\n\r\na(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n/* test\r\n test2\r\n test3 */\r\nfunction foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n /* test\r\n test2\r\n test3 */\r\n var a,\r\n // test\r\n // test\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n }\r\n\r\n a(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n /* test\r\n test2\r\n test3 */\r\n function foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n }\r\n\r\n}\r\n" },
{ input: "\r\n for (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n }\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfor (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n}\r\n" },
{ input: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;" },
{ input: "x = {\n get foo () {\n },\n set foo (val) {\n }\n};", operations: [ { operation: "Document" } ], expected: "x = {\n get foo() {\n },\n set foo(val) {\n }\n};" },
{ input: "function foo\r\n(a, b, c) {\r\n}", operations: [ { operation: "Document" } ], expected: "function foo\r\n(a, b, c) {\r\n}" },
{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;\r\n }}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 80 } } ], expected: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\r\n }\n }\r\n}" },
{ input: "function f() {\r\n'use strict'}", operations: [ { operation: "CloseBrace", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict'\n}" },
{ input: "foo(1\r\n, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1\r\n, 2, 3)" },
{ input: "do{\r\ndo\r\n{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "do{\r\n do\r\n {\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" },
{ input: "function Sum(a,b,c) {\r\n for(i=0,j=1,k=0,fib=1;i<5;i++,fib=j+k,k=j,j=fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 49, length: 3 } } ], expected: "function Sum(a,b,c) {\r\n for (i = 0, j = 1, k = 0, fib = 1; i < 5; i++, fib = j + k, k = j, j = fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}" },
{ input: "function a() {\r\n function b() {\r\n\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "function a() {\r\n function b() {\r\n\r\n }\r\n}" },
{ input: "", operations: [ { operation: "Document" } ], expected: "" },
{ input: "function a() {\r\nvar b=\"c\"\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function a() {\r\n var b = \"c\"\r\n\r\n}" },
{ input: " if ( a[\"\r\n\"])\r\nb++;", operations: [ { operation: "Enter", point: { position: 11 } } ], expected: "if ( a[\"\r\n\"])\r\nb++;" },
{ input: "/* \r\n \r\n*/ ", operations: [ { operation: "Document" } ], expected: "/* \r\n \r\n*/" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 75 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n};" },
{ input: "if (1) if (1) a++;", operations: [ { operation: "Document" } ], expected: "if (1) if (1) a++;" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 53 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\n catch (e) {\r\n x += 2\r\n }finally {\r\nx+=2\r\n}\r\n}" },
{ input: "function f() {\r\n'use strict'\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "function f() {\r\n 'use strict'\r\n\r\n}" },
{ input: " \r\n ", operations: [ { operation: "Document" } ], expected: " \r\n " },
{ input: "{ var b; }", operations: [ { operation: "Document" } ], expected: "{ var b; }" },
{ input: "var z = {a: 1};", operations: [ { operation: "Document" } ], expected: "var z = { a: 1 };" },
{ input: "var z =\n {a: 1};", operations: [ { operation: "Document" } ], expected: "var z =\n { a: 1 };" },
{ input: "for (var i = 0; i < 10; i++) { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) { var a }" },
{ input: "for (var i = 0; i < 10; i++)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++)\n{ var a }" },
{ input: "if (1) { var a }", operations: [ { operation: "Document" } ], expected: "if (1) { var a }" },
{ input: "if (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "if (1)\n{ var a }" },
{ input: "while (1) { var a }", operations: [ { operation: "Document" } ], expected: "while (1) { var a }" },
{ input: "while (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "while (1)\n{ var a }" },
{ input: "do { var a } while (1)", operations: [ { operation: "Document" } ], expected: "do { var a } while (1)" },
{ input: "do\n { var a }\n while (1)", operations: [ { operation: "Document" } ], expected: "do\n{ var a }\nwhile (1)" },
{ input: "for (var a in b) { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b) { var a }" },
{ input: "for (var a in b)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b)\n{ var a }" },
{ input: "with (x) { var a }", operations: [ { operation: "Document" } ], expected: "with (x) { var a }" },
{ input: "with (x)\n { var a }", operations: [ { operation: "Document" } ], expected: "with (x)\n{ var a }" },
{ input: "try { var a } \ncatch (e) { var a } \nfinally { }", operations: [ { operation: "Document" } ], expected: "try { var a }\ncatch (e) { var a }\nfinally { }" },
{ input: "try\n { var a } \ncatch (e)\n { var a } \nfinally\n { }", operations: [ { operation: "Document" } ], expected: "try\n{ var a }\ncatch (e)\n{ var a }\nfinally\n{ }" },
{ input: "switch (x) { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x) { case 1: { var a } }" },
{ input: "switch (x)\n { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x)\n{ case 1: { var a } }" },
{ input: "function f() { var x }", operations: [ { operation: "Document" } ], expected: "function f() { var x }" },
{ input: "function f()\n\n { var x }", operations: [ { operation: "Document" } ], expected: "function f()\n\n{ var x }" },
{ input: "function test() {\r\nlabel1:\r\nvar a;\r\nvar b;\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n label1:\r\n var a;\r\n var b;\r\n}" },
{ input: "{\n x =\nfunction () {\n };\n}", operations: [ { operation: "Document" } ], expected: "{\n x =\nfunction () {\n};\n}" },
{ input: "switch (a){\r\n case 1: x+=2;\r\ncase 2 : { \r\nx+=2}\r\n}", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: {\r\n x += 2\n }\r\n}" },
{ input: " // ;", operations: [ { operation: "Semicolon", point: { position: 7 } } ], expected: " // ;" },
{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 115 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n" },
{ input: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 46, length: 33 } } ], expected: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}" },
{ input: "if (a in b) { }", operations: [ { operation: "Document" } ], expected: "if (a in b) { }" },
{ input: "\r\nfunction f() {\r\nlabel0:\r\nfor (var i = 0; i < 10; i++) {\r\nlabel1: {\r\nfor (var i = 0; i < 10; i++)\r\nx = 2;\r\nlabel2:\r\nfor (var i = 0; i < 10; i++) {\r\nbreak label2\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction f() {\r\n label0:\r\n for (var i = 0; i < 10; i++) {\r\n label1: {\r\n for (var i = 0; i < 10; i++)\r\n x = 2;\r\n label2:\r\n for (var i = 0; i < 10; i++) {\r\n break label2\r\n }\r\n }\r\n }\r\n}" },
{ input: "function f() {\r\nstring='string'}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function f() {\r\n string = 'string'\n}" },
{ input: "\r\nfunction a() {\r\nfunction test() /* test */\r\n{\r\nif (test) /* test */\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() /* test */ {\r\n if (test) /* test */ {\r\n }\r\n }\r\n}" },
{ input: "that = {\r\n method: function () {\r\n return this.datum;\r\n } , \r\n\r\n datum: 0\r\n};", operations: [ { operation: "Enter", point: { position: 98 } } ], expected: "that = {\r\n method: function () {\r\n return this.datum;\r\n },\r\n\r\n datum: 0\r\n};" },
{ input: "for (; ;)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "for (; ;)\n // test\n test;" },
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" },
{ input: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}", operations: [ { operation: "Enter", point: { position: 70 } } ], expected: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}" },
{ input: "var obj={a:{b:2,c:{d:{e:{}}}}};", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } };" },
{ input: "if (1)\r\n x++;\r\nelse x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse x--;" },
{ input: "do{\r\nfor(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++) i -= 2\n} while (1 !== 1)" },
{ input: "switch (a){\r\n case 1,2,3:\r\n break;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "switch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}\r\n" },
{ input: " foo(function (file) {\r\n return 0\r\n })\r\n .then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n})\r\n .then(function (doc) {\r\n return 1\r\n });" },
{ input: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n" },
{ input: "do{for(var i=0;i<10;i++)i-=2}\r\nwhile(1!==1)", operations: [ { operation: "Enter", point: { position: 31 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 }\r\nwhile (1 !== 1)" },
{ input: " function a( b,c ) \r\n {\r\n var d=0 ;\r\n }", operations: [ { operation: "Document" } ], expected: "function a(b, c) {\r\n var d = 0;\r\n}" },
{ input: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}" },
{ input: "if (x!=1^y===2) x+=2\r\n", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) x += 2\r\n" },
{ input: "function f() {\n }", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "function f() {\n}" },
{ input: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n }" },
{ input: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];", operations: [ { operation: "Document" } ], expected: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];" },
{ input: "if (x!=1^y===2) x+=2;", operations: [ { operation: "Semicolon", point: { position: 23 } } ], expected: "if (x != 1 ^ y === 2) x += 2;" },
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 71 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\n x += 2\r\n}\r\n}" },
{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" },
{ input: "function test() { }\r\n", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function test() { }\r\n" },
{ input: "delete x;", operations: [ { operation: "Document" } ], expected: "delete x;" },
{ input: "\r\n{\r\n\r\nvar a,\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n 2\r\n}\r\n\r\na(1,\r\n 2).\r\n test();\r\n\r\nfunction foo(a, b,\r\n c) {\r\n}\r\n\r\nfor (i = 0;\r\n i < 1;\r\n i++) {\r\n}\r\n\r\nfor (a\r\n in b) {\r\n}\r\n\r\nwhile (i +\r\n 2) {\r\n}\r\n\r\nswitch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n}\r\n\r\ntry {\r\n}\r\ncatch (\r\n e) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n var a,\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n 2\r\n }\r\n\r\n a(1,\r\n 2).\r\n test();\r\n\r\n function foo(a, b,\r\n c) {\r\n }\r\n\r\n for (i = 0;\r\n i < 1;\r\n i++) {\r\n }\r\n\r\n for (a\r\n in b) {\r\n }\r\n\r\n while (i +\r\n 2) {\r\n }\r\n\r\n switch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n }\r\n\r\n try {\r\n }\r\n catch (\r\n e) {\r\n }\r\n\r\n}\r\n" },
{ input: "function f() {\r\n do{\r\nx++ }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 30 } } ], expected: "function f() {\r\n do {\r\n x++\n }\r\n}" },
{ input: "do\r\n{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 4 } } ], expected: "do\r\n{ for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1)" },
{ input: "switch (a){\r\n case 1 :\r\n x+=2\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 28 } } ], expected: "switch (a){\r\n case 1:\r\n x += 2\r\n case 2:{\r\n }\r\n}\r\n" },
{ input: "var x = [\n //comment\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n //comment\n 1,\n 2,\n 3\n]" },
{ input: "switch (a){\r\n case 1: x += 2;\r\n\r\ncase 1 : x+=2;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n\r\n case 1: x += 2;\r\n}\r\n" },
{ input: " foo(function (file) {\r\n return 0\r\n }).then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n}).then(function (doc) {\r\n return 1\r\n});" },
{ input: "function f() {\r\nvar s=1 /**/;\r\n}", operations: [ { operation: "Semicolon", point: { position: 30 } } ], expected: "function f() {\r\n var s = 1 /**/;\r\n}" },
{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n \r\n}", operations: [ { operation: "Enter", point: { position: 61 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n\r\n}" },
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2\r\n\r\n\r\n\r\n;", operations: [ { operation: "Semicolon", point: { position: 57 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2\r\n\r\n\r\n\r\n;" },
{ input: "function a() {\r\nvar b = 0;//\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function a() {\r\n var b = 0;//\r\n\r\n}" },
{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse\r\n if (b)\r\n test;" },
{ input: "for(var j=0;j<10;j++)j-=i;", operations: [ { operation: "Semicolon", point: { position: 26 } } ], expected: "for (var j = 0; j < 10; j++) j -= i;" },
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2;", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2;" },
{ input: "function test() {\r\n var a\r\n }", operations: [ { operation: "Document" } ], expected: "function test() {\r\n var a\r\n}" },
{ input: "if (1) {\r\n} else { }", operations: [ { operation: "Document" } ], expected: "if (1) {\r\n} else { }" },
{ input: "function f() {\r\n /*\r\n\r\n */\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n /*\r\n\r\n */\r\n}" },
{ input: "if (x!=1^y===2) \r\n x+=2", operations: [ { operation: "Enter", point: { position: 18 } } ], expected: "if (x != 1 ^ y === 2)\r\n x += 2" },
{ input: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) {}}}}\n", operations: [ { operation: "Enter", point: { position: 88 } } ], expected: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) { }\n }\n }\n}\n" },
{ input: "a=a+\nb+\n c+\n d +\ne +\nm+f;", operations: [ { operation: "Semicolon", point: { position: 100 } } ], expected: "a = a +\nb +\n c +\n d +\ne +\nm + f;" },
{ input: "x = {\r\n get a() {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n get a() {\r\n\r\n }\r\n}" },
{ input: "if(1)\r\n;", operations: [ { operation: "Enter", point: { position: 7 } } ], expected: "if (1)\r\n ;" },
{ input: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}" },
{ input: "string='string+=2\\r\n'", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2\\r\n'" },
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\n{if(1)\r\nx+=2\r\nelse\r\nx+=2}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "if(1)\r\n if (1)\r\n x++\r\n else {\n if (1)\r\n x += 2\r\n else\r\n x += 2\n }" },
{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 19 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" },
{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2 : { x+=2;}\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 53 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: { x += 2;}\r\n}\r\n" },
{ input: "// ", operations: [ { operation: "Document" } ], expected: "// " },
{ input: "for(var i=0;\r\ni<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "for (var i = 0;\r\ni < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" },
{ input: "if (a) if (b) if (c) if (d)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a) if (b) if (c) if (d)\r\n test;" },
{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 15 } } ], expected: "do { for (var i = 0;i<10;i++)i-=2}while(1!==1)" },
{ input: "$ ( '#TextBox1' ) . unbind ( ) ;", operations: [ { operation: "Document" } ], expected: "$('#TextBox1').unbind();" },
{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b);", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b);" },
{ input: "do{for(var i=0;i<10;i++)i-=2;}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2;}while(1!==1)" },
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 55 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n}" },
{ input: "function a() {\r\nfunction b() {\r\nfunction c() {\r\n}}}", operations: [ { operation: "CloseBrace", point: { position: 51 } } ], expected: "function a() {\r\n function b() {\r\n function c() {\r\n }\n }\n}" },
{ input: " do do do do\r\n test;\r\n while (0)\r\n while (0)\r\n while (0)\r\n while (0)", operations: [ { operation: "Document" } ], expected: "do do do do\r\n test;\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)" },
{ input: "/**/ ", operations: [ { operation: "Document" } ], expected: "/**/" },
{ input: "function a()\n{ var a\n}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "function a()\n{\n var a\n}" },
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;\r\nj++){j-=i}}", operations: [ { operation: "Enter", point: { position: 41 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10;\r\n j++) { j -= i }\n}" },
{ input: "function a() {\r\n if (true) {\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 40 } } ], expected: "function a() {\r\n if (true) {\r\n }\r\n\r\n}" },
{ input: "string='string+=2'\r\n", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2'\r\n" },
{ input: "for (a in b) {\r\nx++;}\r\n", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (a in b) {\r\n x++;\n}\r\n" },
{ input: "var obj={a:{b:2,c:{\r\nd:{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\r\n d: { e: {} }\n }\n }\n}" },
{ input: "\r\n// test\r\n\r\n{\r\n// test\r\n}\r\n\r\nfunction foo() {\r\n// test\r\n\r\nswitch (a) {\r\n// test\r\ncase 1:\r\n// test\r\ndefault:\r\n// test\r\n}\r\n\r\nif (false)\r\n// test\r\nifblock;\r\n\r\nif (false) {\r\n//test\r\n}\r\n\r\nif (false) test;\r\nelse\r\n// test\r\ntest;\r\n\r\nif (false) test;\r\nelse {\r\n// test\r\ntest;\r\n}\r\n\r\nfor (; ;)\r\n// test\r\ntest;\r\n\r\nfor (; ;) {\r\n// test\r\nforblock;\r\n}\r\n\r\nfor (a in b)\r\n// test\r\ntest;\r\n\r\nfor (a in b) {\r\n// test\r\ntest\r\n}\r\n\r\nwhile (false)\r\n// test\r\ntest;\r\n\r\nwhile (false) {\r\n// test\r\ntest;\r\n}\r\n\r\nwith (a) {\r\n// test\r\n}\r\n\r\ndo\r\n// test\r\ntestl\r\nwhile (false)\r\n\r\ndo {\r\n// test\r\ntest;\r\n} while (false)\r\n\r\ntry {\r\n// test\r\n} catch (e) {\r\n// test\r\n} finally {\r\n// test\r\n}\r\n\r\n(function () {\r\nvar a = function () {\r\nreturn 1;\r\n},\r\n// This is a comment inline with a multiline statement\r\nb = 2,\r\nc = 3;\r\n})();\r\n\r\n\r\nvar a = {\r\n// test\r\nx: 1,\r\ny: 2 +\r\n// test\r\n3 +\r\n4,\r\n}\r\n\r\n\r\nvar a,\r\n// test\r\nb;\r\n\r\nvar a = [\r\n// test\r\n1,\r\n2,\r\n3\r\n];\r\n\r\na = 1 +\r\n// test\r\n2;\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n// test\r\n\r\n{\r\n // test\r\n}\r\n\r\nfunction foo() {\r\n // test\r\n\r\n switch (a) {\r\n // test\r\n case 1:\r\n // test\r\n default:\r\n // test\r\n }\r\n\r\n if (false)\r\n // test\r\n ifblock;\r\n\r\n if (false) {\r\n //test\r\n }\r\n\r\n if (false) test;\r\n else\r\n // test\r\n test;\r\n\r\n if (false) test;\r\n else {\r\n // test\r\n test;\r\n }\r\n\r\n for (; ;)\r\n // test\r\n test;\r\n\r\n for (; ;) {\r\n // test\r\n forblock;\r\n }\r\n\r\n for (a in b)\r\n // test\r\n test;\r\n\r\n for (a in b) {\r\n // test\r\n test\r\n }\r\n\r\n while (false)\r\n // test\r\n test;\r\n\r\n while (false) {\r\n // test\r\n test;\r\n }\r\n\r\n with (a) {\r\n // test\r\n }\r\n\r\n do\r\n // test\r\n testl\r\n while (false)\r\n\r\n do {\r\n // test\r\n test;\r\n } while (false)\r\n\r\n try {\r\n // test\r\n } catch (e) {\r\n // test\r\n } finally {\r\n // test\r\n }\r\n\r\n (function () {\r\n var a = function () {\r\n return 1;\r\n },\r\n // This is a comment inline with a multiline statement\r\n b = 2,\r\n c = 3;\r\n })();\r\n\r\n\r\n var a = {\r\n // test\r\n x: 1,\r\n y: 2 +\r\n // test\r\n 3 +\r\n 4,\r\n }\r\n\r\n\r\n var a,\r\n // test\r\n b;\r\n\r\n var a = [\r\n // test\r\n 1,\r\n 2,\r\n 3\r\n ];\r\n\r\n a = 1 +\r\n // test\r\n 2;\r\n\r\n}\r\n" },
{ input: " \r\n /* \r\n\r\n a \r\n a\r\n a \r\n a \r\na \r\n \r\n\r\n */ \r\n ", operations: [ { operation: "Document" } ], expected: "\r\n/* \r\n\r\n a \r\n a\r\n a \r\na \r\na \r\n\r\n\r\n*/\r\n" },
{ input: "string='{string +=2}'", operations: [ { operation: "CloseBrace", point: { position: 20 } } ], expected: "string='{string +=2}'" },
{ input: "var obj={a:{b:2,c:{d:{e:{}}}}}\r\n", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } }\r\n" },
{ input: "string='string\\r\n line2'+'other part'\r\n", operations: [ { operation: "Enter", point: { position: 47 } } ], expected: "string='string\\r\n line2' + 'other part'\r\n" },
{ input: " switch( a)\r\n{case 1 :x+=2 ;break\r\n case 2:{\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 13 } } ], expected: "switch (a)\r\n{\n case 1: x += 2; break\r\n case 2:{\r\n }\r\n}" }

View file

@ -1,79 +0,0 @@
class a {
constructor ( n : number ) ;
constructor ( s : string ) ;
constructor ( ns : any ) {
}
public pgF ( ) { } ;
public pv ;
public get d ( ) {
return 30 ;
}
public set d ( ) {
}
public static get p2 ( ) {
return { x : 30 , y : 40 } ;
}
private static d2 ( ) {
}
private static get p3 ( ) {
return "string" ;
}
private pv3 ;
private foo ( n : number ) : string ;
private foo ( s : string ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor ( n : number ) ;
constructor ( s : string ) ;
public pgF ( ) : void ;
public pv ;
public d : number ;
static p2 : { x : number ; y : number ; } ;
static d2 ( ) ;
static p3 ;
private pv3 ;
private foo ( s ) ;
}
class d {
private foo ( n : number ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
}
class e {
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
private foo ( n : number ) : string ;
}

View file

@ -1,79 +0,0 @@
class a {
constructor(n: number);
constructor(s: string);
constructor(ns: any) {
}
public pgF() { };
public pv;
public get d() {
return 30;
}
public set d() {
}
public static get p2() {
return { x: 30, y: 40 };
}
private static d2() {
}
private static get p3() {
return "string";
}
private pv3;
private foo(n: number): string;
private foo(s: string): string;
private foo(ns: any) {
return ns.toString();
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor(n: number);
constructor(s: string);
public pgF(): void;
public pv;
public d: number;
static p2: { x: number; y: number; };
static d2();
static p3;
private pv3;
private foo(s);
}
class d {
private foo(n: number): string;
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
}
class e {
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
private foo(n: number): string;
}

View file

@ -1,4 +0,0 @@
class foo {
constructor (n?: number, m? = 5, o?: string = "") { }
x:number = 1?2:3;
}

View file

@ -1,4 +0,0 @@
class foo {
constructor(n?: number, m? = 5, o?: string = "") { }
x: number = 1 ? 2 : 3;
}

View file

@ -1,3 +0,0 @@
$ ( document ) . ready ( function ( ) {
alert ( 'i am ready' ) ;
} );

View file

@ -1,3 +0,0 @@
$(document).ready(function() {
alert('i am ready');
});

View file

@ -1,10 +0,0 @@
function foo ( x : { } ) { }
foo ( { } ) ;
interface bar {
x : { } ;
y : ( ) => { } ;
}

View file

@ -1,10 +0,0 @@
function foo(x: {}) { }
foo({});
interface bar {
x: {};
y: () => {};
}

View file

@ -1,112 +0,0 @@
// valid
( ) => 1 ;
( arg ) => 2 ;
arg => 2 ;
( arg = 1 ) => 3 ;
( arg ? ) => 4 ;
( arg : number ) => 5 ;
( arg : number = 0 ) => 6 ;
( arg ? : number ) => 7 ;
( ... arg : number [ ] ) => 8 ;
( arg1 , arg2 ) => 12 ;
( arg1 = 1 , arg2 =3 ) => 13 ;
( arg1 ? , arg2 ? ) => 14 ;
( arg1 : number , arg2 : number ) => 15 ;
( arg1 : number = 0 , arg2 : number = 1 ) => 16 ;
( arg1 ? : number , arg2 ? : number ) => 17 ;
( arg1 , ... arg2 : number [ ] ) => 18 ;
( arg1 , arg2 ? : number ) => 19 ;
// in paren
( ( ) => 21 ) ;
( ( arg ) => 22 ) ;
( ( arg = 1 ) => 23 ) ;
( ( arg ? ) => 24 ) ;
( ( arg : number ) => 25 ) ;
( ( arg : number = 0 ) => 26 ) ;
( ( arg ? : number ) => 27 ) ;
( ( ... arg : number [ ] ) => 28 ) ;
// in multiple paren
( ( ( ( ( arg ) => { return 32 ; } ) ) ) ) ;
// in ternary exression
false ? ( ) => 41 : null ;
false ? ( arg ) => 42 : null ;
false ? ( arg = 1 ) => 43 : null ;
false ? ( arg ? ) => 44 : null ;
false ? ( arg : number ) => 45 : null ;
false ? ( arg ? : number ) => 46 : null ;
false ? ( arg ? : number = 0 ) => 47 : null ;
false ? ( ... arg : number [ ] ) => 48 : null ;
// in ternary exression within paren
false ? ( ( ) => 51 ) : null ;
false ? ( ( arg ) => 52 ) : null ;
false ? ( ( arg = 1 ) => 53 ) : null ;
false ? ( ( arg ? ) => 54 ) : null ;
false ? ( ( arg : number ) => 55 ) : null ;
false ? ( ( arg ? : number ) => 56 ) : null ;
false ? ( ( arg ? : number = 0 ) => 57 ) : null ;
false ? ( ( ... arg : number [ ] ) => 58 ) : null ;
// ternary exression's else clause
false ? null : ( ) => 61 ;
false ? null : ( arg ) => 62 ;
false ? null : ( arg = 1 ) => 63 ;
false ? null : ( arg ? ) => 64 ;
false ? null : ( arg : number ) => 65 ;
false ? null : ( arg ? : number ) => 66 ;
false ? null : ( arg ? : number = 0 ) => 67 ;
false ? null : ( ... arg : number [ ] ) => 68 ;
// nested ternary expressions
( a ? ) => { return a ; } ? ( b ? ) => { return b ; } : ( c ? ) => { return c ; } ;
//multiple levels
( a ? ) => { return a ; } ? ( b ) => ( c ) => 81 : ( c ) => ( d ) => 82 ;
// In Expressions
( ( arg ) => 90 ) instanceof Function ;
( ( arg = 1 ) => 91 ) instanceof Function ;
( ( arg ? ) => 92 ) instanceof Function ;
( ( arg : number ) => 93 ) instanceof Function ;
( ( arg : number = 1 ) => 94 ) instanceof Function ;
( ( arg ? : number ) => 95 ) instanceof Function ;
( ( ... arg : number [ ] ) => 96 ) instanceof Function ;
'' + ( arg ) => 100 ;
( ( arg ) => 0 ) + '' + ( arg ) => 101 ;
( ( arg = 1 ) => 0 ) + '' + ( arg = 2 ) => 102 ;
( ( arg ? ) => 0 ) + '' + ( arg ? ) => 103 ;
( ( arg : number ) => 0 ) + '' + ( arg : number ) => 104 ;
( ( arg : number = 1 ) => 0 ) + '' + ( arg : number = 2 ) => 105 ;
( ( arg ? : number = 1 ) => 0 ) + '' + ( arg ? : number = 2 ) => 106 ;
( ( ... arg : number [ ] ) => 0 ) + '' + ( ... arg : number [ ] ) => 107 ;
( ( arg1 , arg2 ? ) => 0 ) + '' + ( arg1 , arg2 ? ) => 108 ;
( ( arg1 , ... arg2 : number [ ] ) => 0 ) + '' + ( arg1 , ... arg2 : number [ ] ) => 108 ;
// Function Parameters
function foo ( ... arg : any [ ] ) { }
foo (
( a ) => 110 ,
( ( a ) => 111 ) ,
( a ) => {
return 112 ;
} ,
( a ? ) => 113 ,
( a , b ? ) => 114 ,
( a : number ) => 115 ,
( a : number = 0 ) => 116 ,
( a = 0 ) => 117 ,
( a ? : number = 0 ) => 118 ,
( a ? , b ? : number = 0 ) => 118 ,
( ... a : number [ ] ) => 119 ,
( a , b ? = 0 , ... c : number [ ] ) => 120 ,
( a ) => ( b ) => ( c ) => 121 ,
false ? ( a ) => 0 : ( b ) => 122
) ;

View file

@ -1,112 +0,0 @@
// valid
() => 1;
(arg) => 2;
arg => 2;
(arg = 1) => 3;
(arg?) => 4;
(arg: number) => 5;
(arg: number = 0) => 6;
(arg?: number) => 7;
(...arg: number[]) => 8;
(arg1, arg2) => 12;
(arg1 = 1, arg2 = 3) => 13;
(arg1?, arg2?) => 14;
(arg1: number, arg2: number) => 15;
(arg1: number = 0, arg2: number = 1) => 16;
(arg1?: number, arg2?: number) => 17;
(arg1, ...arg2: number[]) => 18;
(arg1, arg2?: number) => 19;
// in paren
(() => 21);
((arg) => 22);
((arg = 1) => 23);
((arg?) => 24);
((arg: number) => 25);
((arg: number = 0) => 26);
((arg?: number) => 27);
((...arg: number[]) => 28);
// in multiple paren
(((((arg) => { return 32; }))));
// in ternary exression
false ? () => 41 : null;
false ? (arg) => 42 : null;
false ? (arg = 1) => 43 : null;
false ? (arg?) => 44 : null;
false ? (arg: number) => 45 : null;
false ? (arg?: number) => 46 : null;
false ? (arg?: number = 0) => 47 : null;
false ? (...arg: number[]) => 48 : null;
// in ternary exression within paren
false ? (() => 51) : null;
false ? ((arg) => 52) : null;
false ? ((arg = 1) => 53) : null;
false ? ((arg?) => 54) : null;
false ? ((arg: number) => 55) : null;
false ? ((arg?: number) => 56) : null;
false ? ((arg?: number = 0) => 57) : null;
false ? ((...arg: number[]) => 58) : null;
// ternary exression's else clause
false ? null : () => 61;
false ? null : (arg) => 62;
false ? null : (arg = 1) => 63;
false ? null : (arg?) => 64;
false ? null : (arg: number) => 65;
false ? null : (arg?: number) => 66;
false ? null : (arg?: number = 0) => 67;
false ? null : (...arg: number[]) => 68;
// nested ternary expressions
(a?) => { return a; } ? (b?) => { return b; } : (c?) => { return c; };
//multiple levels
(a?) => { return a; } ? (b) => (c) => 81 : (c) => (d) => 82;
// In Expressions
((arg) => 90) instanceof Function;
((arg = 1) => 91) instanceof Function;
((arg?) => 92) instanceof Function;
((arg: number) => 93) instanceof Function;
((arg: number = 1) => 94) instanceof Function;
((arg?: number) => 95) instanceof Function;
((...arg: number[]) => 96) instanceof Function;
'' + (arg) => 100;
((arg) => 0) + '' + (arg) => 101;
((arg = 1) => 0) + '' + (arg = 2) => 102;
((arg?) => 0) + '' + (arg?) => 103;
((arg: number) => 0) + '' + (arg: number) => 104;
((arg: number = 1) => 0) + '' + (arg: number = 2) => 105;
((arg?: number = 1) => 0) + '' + (arg?: number = 2) => 106;
((...arg: number[]) => 0) + '' + (...arg: number[]) => 107;
((arg1, arg2?) => 0) + '' + (arg1, arg2?) => 108;
((arg1, ...arg2: number[]) => 0) + '' + (arg1, ...arg2: number[]) => 108;
// Function Parameters
function foo(...arg: any[]) { }
foo(
(a) => 110,
((a) => 111),
(a) => {
return 112;
},
(a?) => 113,
(a, b?) => 114,
(a: number) => 115,
(a: number = 0) => 116,
(a = 0) => 117,
(a?: number = 0) => 118,
(a?, b?: number = 0) => 118,
(...a: number[]) => 119,
(a, b? = 0, ...c: number[]) => 120,
(a) => (b) => (c) => 121,
false ? (a) => 0 : (b) => 122
);

View file

@ -1,2 +0,0 @@
if(false){debugger;}
if ( false ) { debugger ; }

View file

@ -1,2 +0,0 @@
if (false) { debugger; }
if (false) { debugger; }

View file

@ -1,13 +0,0 @@
var fun1 = function ( ) {
var x = 'foo' ,
z = 'bar' ;
return x ;
},
fun2 = ( function ( f ) {
var fun = function ( ) {
console . log ( f ( ) ) ;
},
x = 'Foo' ;
return fun ;
} ( fun1 ) ) ;

View file

@ -1,13 +0,0 @@
var fun1 = function() {
var x = 'foo',
z = 'bar';
return x;
},
fun2 = (function(f) {
var fun = function() {
console.log(f());
},
x = 'Foo';
return fun;
} (fun1));

View file

@ -1,6 +0,0 @@
module Foo {
}
import bar = Foo;
import bar2=Foo;

View file

@ -1,6 +0,0 @@
module Foo {
}
import bar = Foo;
import bar2 = Foo;

View file

@ -1,95 +0,0 @@
var a;var c , b;var $d
var $e
var f
a++;b++;
function f ( ) {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m (a[b[c][d]])];
break;
switch ( variable){
case 1: abc += 425;
break;
case 404 : a [x--/2]%=3 ;
break ;
case vari : v[--x ] *=++y*( m + n / k[z]);
for (a in b){
for (a = 0; a < 10; ++a) {
a++;--a;
if (a == b) {
a++;b--;
}
else
if (a == c){
++a;
(--c)+=d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--;++b;
a++
}
}
}
for (x in y) {
m-=m;
k=1+2+3+4;
}
}
break;
}
}
var a ={b:function(){}};
return {a:1,b:2}
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready ();
function pageLoad() {
$('#TextBox1' ) . unbind ( ) ;
$('#TextBox1' ) . datepicker ( ) ;
}
function pageLoad ( ) {
var webclass=[
{ 'student' :
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
} ,
{ 'student':
{'id':'2','name':'Adam Davidson','legacySkill':'Cobol,MainFrame'}
} ,
{ 'student':
{ 'id':'3','name':'Charles Boyer' ,'legacySkill':'HTML, XML'}
}
];
$create(Sys.UI.DataView,{data:webclass},null,null,$get('SList'));
}
$( document ).ready(function(){
alert('hello');
} ) ;

View file

@ -1,98 +0,0 @@
var a; var c, b; var $d
var $e
var f
a++; b++;
function f() {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m(a[b[c][d]])];
break;
switch (variable) {
case 1: abc += 425;
break;
case 404: a[x-- / 2] %= 3;
break;
case vari: v[--x] *= ++y * (m + n / k[z]);
for (a in b) {
for (a = 0; a < 10; ++a) {
a++; --a;
if (a == b) {
a++; b--;
}
else
if (a == c) {
++a;
(--c) += d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--; ++b;
a++
}
}
}
for (x in y) {
m -= m;
k = 1 + 2 + 3 + 4;
}
}
break;
}
}
var a = { b: function() { } };
return { a: 1, b: 2 }
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready();
function pageLoad() {
$('#TextBox1').unbind();
$('#TextBox1').datepicker();
}
function pageLoad() {
var webclass = [
{
'student':
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
},
{
'student':
{ 'id': '2', 'name': 'Adam Davidson', 'legacySkill': 'Cobol,MainFrame' }
},
{
'student':
{ 'id': '3', 'name': 'Charles Boyer', 'legacySkill': 'HTML, XML' }
}
];
$create(Sys.UI.DataView, { data: webclass }, null, null, $get('SList'));
}
$(document).ready(function() {
alert('hello');
});

View file

@ -1,3 +0,0 @@
module Foo {
export module A . B . C { }
}

View file

@ -1,3 +0,0 @@
module Foo {
export module A.B.C { }
}

View file

@ -1,76 +0,0 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
} ;
var x : d ;
export function foo ( ) : d ;
}
import m4 = module ( "m4" ) ;
export var x4 = m4.x ;
export var d4 = m4.d ;
export var f4 = m4.foo ( ) ;
export module m1 {
declare export module "m2" {
export class d {
} ;
var x: d ;
export function foo ( ) : d ;
}
import m2 = module ( "m2" ) ;
import m3 = module ( "m4" ) ;
export var x2 = m2.x ;
export var d2 = m2.d ;
export var f2 = m2.foo ( ) ;
export var x3 = m3.x ;
export var d3 = m3.d ;
export var f3 = m3.foo ( ) ;
}
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
export module m5 {
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
}

View file

@ -1,76 +0,0 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
};
var x: d;
export function foo(): d;
}
import m4 = module("m4");
export var x4 = m4.x;
export var d4 = m4.d;
export var f4 = m4.foo();
export module m1 {
declare export module "m2" {
export class d {
};
var x: d;
export function foo(): d;
}
import m2 = module("m2");
import m3 = module("m4");
export var x2 = m2.x;
export var d2 = m2.d;
export var f2 = m2.foo();
export var x3 = m3.x;
export var d3 = m3.d;
export var f3 = m3.foo();
}
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
export module m5 {
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
}

View file

@ -1,27 +0,0 @@
var x = {foo: 1,
bar: "tt",
boo: 1 + 5};
var x2 = {foo: 1,
bar: "tt",boo:1+5};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b : 2}
};
var x={ };
var y = {};

View file

@ -1,31 +0,0 @@
var x = {
foo: 1,
bar: "tt",
boo: 1 + 5
};
var x2 = {
foo: 1,
bar: "tt", boo: 1 + 5
};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b: 2 }
};
var x = {};
var y = {};

View file

@ -1,32 +0,0 @@
function f( ) {
var x = 3;
var z = 2 ;
a = z ++ - 2 * x ;
for ( ; ; ) {
a+=(g +g)*a%t;
b -- ;
}
switch ( a )
{
case 1 : {
a ++ ;
b--;
if(a===a)
return;
else
{
for(a in b)
if(a!=a)
{
for(a in b)
{
a++;
}
}
}
}
default:
break;
}
}

View file

@ -1,28 +0,0 @@
function f() {
var x = 3;
var z = 2;
a = z++ - 2 * x;
for (; ;) {
a += (g + g) * a % t;
b--;
}
switch (a) {
case 1: {
a++;
b--;
if (a === a)
return;
else {
for (a in b)
if (a != a) {
for (a in b) {
a++;
}
}
}
}
default:
break;
}
}

View file

@ -1 +0,0 @@
var a = b + c ^ d - e * ++f;

View file

@ -1 +0,0 @@
class test { constructor () { } }

View file

@ -1,10 +0,0 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob
{
Blah=1, Bleah=2
}
}

View file

@ -1,9 +0,0 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob {
Blah = 1, Bleah = 2
}
}

View file

@ -1,65 +0,0 @@
module MyModule
{
module A.B.C {
module F {
}
}
interface Blah
{
boo: string;
}
class Foo
{
}
class Foo2 {
public foo():number {
return 5 * 6;
}
public foo2() {
if (1 === 2)
{
var y : number= 76;
return y;
}
while (2 == 3) {
if ( y == null ) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a:number, b:number):number
{
return 0;
}
function bar(a:number, b:number) :number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}

View file

@ -1,58 +0,0 @@
module MyModule {
module A.B.C {
module F {
}
}
interface Blah {
boo: string;
}
class Foo {
}
class Foo2 {
public foo(): number {
return 5 * 6;
}
public foo2() {
if (1 === 2) {
var y: number = 76;
return y;
}
while (2 == 3) {
if (y == null) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a: number, b: number): number {
return 0;
}
function bar(a: number, b: number): number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}

View file

@ -1,17 +0,0 @@
function f(a,b,c,d){
for(var i=0;i<10;i++){
var a=0;
var b=a+a+a*a%a/2-1;
b+=a;
++b;
f(a,b,c,d);
if(1===1){
var m=function(e,f){
return e^f;
}
}
}
}
for (var i = 0 ; i < this.foo(); i++) {
}

View file

@ -1,17 +0,0 @@
function f(a, b, c, d) {
for (var i = 0; i < 10; i++) {
var a = 0;
var b = a + a + a * a % a / 2 - 1;
b += a;
++b;
f(a, b, c, d);
if (1 === 1) {
var m = function(e, f) {
return e ^ f;
}
}
}
}
for (var i = 0 ; i < this.foo(); i++) {
}

View file

@ -1,9 +0,0 @@
with (foo.bar)
{
}
with (bar.blah)
{
}

View file

@ -1,6 +0,0 @@
with (foo.bar) {
}
with (bar.blah) {
}

View file

@ -176,11 +176,11 @@ namespace ts.projectSystem {
}
};
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken) {
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken, throttleWaitMilliseconds?: number) {
if (typingsInstaller === undefined) {
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
}
return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler, throttleWaitMilliseconds);
}
export interface CreateProjectServiceParameters {
@ -547,6 +547,49 @@ namespace ts.projectSystem {
readonly getEnvironmentVariable = notImplemented;
}
/**
* Test server cancellation token used to mock host token cancellation requests.
* The cancelAfterRequest constructor param specifies how many isCancellationRequested() calls
* should be made before canceling the token. The id of the request to cancel should be set with
* setRequestToCancel();
*/
export class TestServerCancellationToken implements server.ServerCancellationToken {
private currentId = -1;
private requestToCancel = -1;
private isCancellationRequestedCount = 0;
constructor(private cancelAfterRequest = 0) {
}
setRequest(requestId: number) {
this.currentId = requestId;
}
setRequestToCancel(requestId: number) {
this.resetToken();
this.requestToCancel = requestId;
}
resetRequest(requestId: number) {
assert.equal(requestId, this.currentId, "unexpected request id in cancellation");
this.currentId = undefined;
}
isCancellationRequested() {
this.isCancellationRequestedCount++;
// If the request id is the request to cancel and isCancellationRequestedCount
// has been met then cancel the request. Ex: cancel the request if it is a
// nav bar request & isCancellationRequested() has already been called three times.
return this.requestToCancel === this.currentId && this.isCancellationRequestedCount >= this.cancelAfterRequest;
}
resetToken() {
this.currentId = -1;
this.isCancellationRequestedCount = 0;
this.requestToCancel = -1;
}
}
export function makeSessionRequest<T>(command: string, args: T) {
const newRequest: protocol.Request = {
seq: 0,
@ -1007,6 +1050,41 @@ namespace ts.projectSystem {
checkProjectRootFiles(projectService.configuredProjects[0], [commonFile1.path, commonFile2.path]);
});
it("should disable features when the files are too large", () => {
const file1 = {
path: "/a/b/f1.js",
content: "let x =1;",
fileSize: 10 * 1024 * 1024
};
const file2 = {
path: "/a/b/f2.js",
content: "let y =1;",
fileSize: 6 * 1024 * 1024
};
const file3 = {
path: "/a/b/f3.js",
content: "let y =1;",
fileSize: 6 * 1024 * 1024
};
const proj1name = "proj1", proj2name = "proj2", proj3name = "proj3";
const host = createServerHost([file1, file2, file3]);
const projectService = createProjectService(host);
projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path]), options: {}, projectFileName: proj1name });
const proj1 = projectService.findProject(proj1name);
assert.isTrue(proj1.languageServiceEnabled);
projectService.openExternalProject({ rootFiles: toExternalFiles([file2.path]), options: {}, projectFileName: proj2name });
const proj2 = projectService.findProject(proj2name);
assert.isTrue(proj2.languageServiceEnabled);
projectService.openExternalProject({ rootFiles: toExternalFiles([file3.path]), options: {}, projectFileName: proj3name });
const proj3 = projectService.findProject(proj3name);
assert.isFalse(proj3.languageServiceEnabled);
});
it("should use only one inferred project if 'useOneInferredProject' is set", () => {
const file1 = {
path: "/a/b/main.ts",
@ -3349,6 +3427,7 @@ namespace ts.projectSystem {
},
resetRequest: noop
};
const session = createSession(host, /*typingsInstaller*/ undefined, /*projectServiceEventHandler*/ undefined, cancellationToken);
expectedRequestId = session.getNextSeq();
@ -3387,22 +3466,7 @@ namespace ts.projectSystem {
})
};
let requestToCancel = -1;
const cancellationToken: server.ServerCancellationToken = (function(){
let currentId: number;
return <server.ServerCancellationToken>{
setRequest(requestId) {
currentId = requestId;
},
resetRequest(requestId) {
assert.equal(requestId, currentId, "unexpected request id in cancellation");
currentId = undefined;
},
isCancellationRequested() {
return requestToCancel === currentId;
}
};
})();
const cancellationToken = new TestServerCancellationToken();
const host = createServerHost([f1, config]);
const session = createSession(host, /*typingsInstaller*/ undefined, () => {}, cancellationToken);
{
@ -3437,13 +3501,13 @@ namespace ts.projectSystem {
host.clearOutput();
// cancel previously issued Geterr
requestToCancel = getErrId;
cancellationToken.setRequestToCancel(getErrId);
host.runQueuedTimeoutCallbacks();
assert.equal(host.getOutput().length, 1, "expect 1 message");
verifyRequestCompleted(getErrId, 0);
requestToCancel = -1;
cancellationToken.resetToken();
}
{
const getErrId = session.getNextSeq();
@ -3460,12 +3524,12 @@ namespace ts.projectSystem {
assert.equal(e1.event, "syntaxDiag");
host.clearOutput();
requestToCancel = getErrId;
cancellationToken.setRequestToCancel(getErrId);
host.runQueuedImmediateCallbacks();
assert.equal(host.getOutput().length, 1, "expect 1 message");
verifyRequestCompleted(getErrId, 0);
requestToCancel = -1;
cancellationToken.resetToken();
}
{
const getErrId = session.getNextSeq();
@ -3488,7 +3552,7 @@ namespace ts.projectSystem {
assert.equal(e2.event, "semanticDiag");
verifyRequestCompleted(getErrId, 1);
requestToCancel = -1;
cancellationToken.resetToken();
}
{
const getErr1 = session.getNextSeq();
@ -3523,6 +3587,68 @@ namespace ts.projectSystem {
return JSON.parse(server.extractMessage(host.getOutput()[n]));
}
});
it("Lower priority tasks are cancellable", () => {
const f1 = {
path: "/a/app.ts",
content: `{ let x = 1; } var foo = "foo"; var bar = "bar"; var fooBar = "fooBar";`
};
const config = {
path: "/a/tsconfig.json",
content: JSON.stringify({
compilerOptions: {}
})
};
const cancellationToken = new TestServerCancellationToken(/*cancelAfterRequest*/ 3);
const host = createServerHost([f1, config]);
const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken, /*throttleWaitMilliseconds*/ 0);
{
session.executeCommandSeq(<protocol.OpenRequest>{
command: "open",
arguments: { file: f1.path }
});
// send navbar request (normal priority)
session.executeCommandSeq(<protocol.NavBarRequest>{
command: "navbar",
arguments: { file: f1.path }
});
// ensure the nav bar request can be canceled
verifyExecuteCommandSeqIsCancellable(<protocol.NavBarRequest>{
command: "navbar",
arguments: { file: f1.path }
});
// send outlining spans request (normal priority)
session.executeCommandSeq(<protocol.OutliningSpansRequest>{
command: "outliningSpans",
arguments: { file: f1.path }
});
// ensure the outlining spans request can be canceled
verifyExecuteCommandSeqIsCancellable(<protocol.OutliningSpansRequest>{
command: "outliningSpans",
arguments: { file: f1.path }
});
}
function verifyExecuteCommandSeqIsCancellable<T extends server.protocol.Request>(request: Partial<T>) {
// Set the next request to be cancellable
// The cancellation token will cancel the request the third time
// isCancellationRequested() is called.
cancellationToken.setRequestToCancel(session.getNextSeq());
let operationCanceledExceptionThrown = false;
try {
session.executeCommandSeq(request);
}
catch (e) {
assert(e instanceof OperationCanceledException);
operationCanceledExceptionThrown = true;
}
assert(operationCanceledExceptionThrown, "Operation Canceled Exception not thrown for request: " + JSON.stringify(request));
}
});
});
describe("occurence highlight on string", () => {

View file

@ -1396,6 +1396,7 @@ interface AudioNode extends EventTarget {
readonly numberOfInputs: number;
readonly numberOfOutputs: number;
connect(destination: AudioNode, output?: number, input?: number): AudioNode;
connect(destination: AudioParam, output?: number): void;
disconnect(output?: number): void;
disconnect(destination: AudioNode, output?: number, input?: number): void;
disconnect(destination: AudioParam, output?: number): void;
@ -2152,7 +2153,9 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods {
createPattern(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, repetition: string): CanvasPattern;
createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
drawFocusIfNeeded(element: Element): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, offsetX: number, offsetY: number, width?: number, height?: number, canvasOffsetX?: number, canvasOffsetY?: number, canvasImageWidth?: number, canvasImageHeight?: number): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, dstX: number, dstY: number): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, dstX: number, dstY: number, dstW: number, dstH: number): void;
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, srcX: number, srcY: number, srcW: number, srcH: number, dstX: number, dstY: number, dstW: number, dstH: number): void;
fill(fillRule?: string): void;
fillRect(x: number, y: number, w: number, h: number): void;
fillText(text: string, x: number, y: number, maxWidth?: number): void;
@ -2449,10 +2452,10 @@ declare var DOMException: {
}
interface DOMImplementation {
createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType): Document;
createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType | null): Document;
createDocumentType(qualifiedName: string, publicId: string, systemId: string): DocumentType;
createHTMLDocument(title: string): Document;
hasFeature(): boolean;
hasFeature(feature: string | null, version: string | null): boolean;
}
declare var DOMImplementation: {
@ -3449,6 +3452,7 @@ declare var Document: {
}
interface DocumentFragment extends Node, NodeSelector, ParentNode {
getElementById(elementId: string): HTMLElement | null;
}
declare var DocumentFragment: {
@ -11837,7 +11841,7 @@ interface URL {
protocol: string;
search: string;
username: string;
readonly searchparams: URLSearchParams;
readonly searchParams: URLSearchParams;
toString(): string;
}
@ -12161,12 +12165,12 @@ interface WebGLRenderingContext {
stencilMaskSeparate(face: number, mask: number): void;
stencilOp(fail: number, zfail: number, zpass: number): void;
stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void;
texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels?: ArrayBufferView): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView | null): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
texParameterf(target: number, pname: number, param: number): void;
texParameteri(target: number, pname: number, param: number): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels?: ArrayBufferView): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView | null): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
uniform1f(location: WebGLUniformLocation | null, x: number): void;
uniform1fv(location: WebGLUniformLocation, v: Float32Array | number[]): void;
uniform1i(location: WebGLUniformLocation | null, x: number): void;
@ -13260,6 +13264,8 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint;
webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint;
webkitRequestAnimationFrame(callback: FrameRequestCallback): number;
createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
scroll(options?: ScrollToOptions): void;
scrollTo(options?: ScrollToOptions): void;
scrollBy(options?: ScrollToOptions): void;
@ -13473,6 +13479,7 @@ interface Body {
blob(): Promise<Blob>;
json(): Promise<any>;
text(): Promise<string>;
formData(): Promise<FormData>;
}
interface CanvasPathMethods {
@ -13835,6 +13842,21 @@ interface Canvas2DContextAttributes {
[attribute: string]: boolean | string | undefined;
}
interface ImageBitmapOptions {
imageOrientation?: "none" | "flipY";
premultiplyAlpha?: "none" | "premultiply" | "default";
colorSpaceConversion?: "none" | "default";
resizeWidth?: number;
resizeHeight?: number;
resizeQuality?: "pixelated" | "low" | "medium" | "high";
}
interface ImageBitmap {
readonly width: number;
readonly height: number;
close(): void;
}
interface URLSearchParams {
/**
* Appends a specified key/value pair as a new search parameter.
@ -13879,6 +13901,7 @@ interface NodeListOf<TNode extends Node> extends NodeList {
interface HTMLCollectionOf<T extends Element> extends HTMLCollection {
item(index: number): T;
namedItem(name: string): T;
[index: number]: T;
}
interface BlobPropertyBag {
@ -14840,6 +14863,8 @@ declare function webkitCancelAnimationFrame(handle: number): void;
declare function webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint;
declare function webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint;
declare function webkitRequestAnimationFrame(callback: FrameRequestCallback): number;
declare function createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function scroll(options?: ScrollToOptions): void;
declare function scrollTo(options?: ScrollToOptions): void;
declare function scrollBy(options?: ScrollToOptions): void;

View file

@ -4,6 +4,23 @@ interface DOMTokenList {
[Symbol.iterator](): IterableIterator<string>;
}
interface FormData {
/**
* Returns an array of key, value pairs for every entry in the list
*/
entries(): IterableIterator<[string, string | File]>;
/**
* Returns a list of keys in the list
*/
keys(): IterableIterator<string>;
/**
* Returns a list of values in the list
*/
values(): IterableIterator<string | File>;
[Symbol.iterator](): IterableIterator<string | File>;
}
interface NodeList {
/**
* Returns an array of key, value pairs for every entry in the list

View file

@ -1,4 +1,29 @@
interface GeneratorFunction extends Function { }
interface Generator extends Iterator<any> { }
interface GeneratorFunction {
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
new (...args: any[]): Generator;
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
(...args: any[]): Generator;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: Generator;
}
interface GeneratorFunctionConstructor {
/**
@ -6,7 +31,22 @@ interface GeneratorFunctionConstructor {
* @param args A list of arguments the function accepts.
*/
new (...args: string[]): GeneratorFunction;
/**
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
(...args: string[]): GeneratorFunction;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: GeneratorFunction;
}
declare var GeneratorFunction: GeneratorFunctionConstructor;

View file

@ -137,7 +137,7 @@ interface Function {
[Symbol.hasInstance](value: any): boolean;
}
interface GeneratorFunction extends Function {
interface GeneratorFunction {
readonly [Symbol.toStringTag]: "GeneratorFunction";
}

View file

@ -1407,6 +1407,8 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
readonly performance: Performance;
readonly self: WorkerGlobalScope;
msWriteProfilerMark(profilerMarkName: string): void;
createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
@ -1467,6 +1469,21 @@ interface ErrorEventInit {
error?: any;
}
interface ImageBitmapOptions {
imageOrientation?: "none" | "flipY";
premultiplyAlpha?: "none" | "premultiply" | "default";
colorSpaceConversion?: "none" | "default";
resizeWidth?: number;
resizeHeight?: number;
resizeQuality?: "pixelated" | "low" | "medium" | "high";
}
interface ImageBitmap {
readonly width: number;
readonly height: number;
close(): void;
}
interface BlobPropertyBag {
type?: string;
endings?: string;
@ -1697,6 +1714,8 @@ declare var onerror: (this: DedicatedWorkerGlobalScope, ev: ErrorEvent) => any;
declare var performance: Performance;
declare var self: WorkerGlobalScope;
declare function msWriteProfilerMark(profilerMarkName: string): void;
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
declare function dispatchEvent(evt: Event): boolean;
declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare var indexedDB: IDBFactory;

View file

@ -254,6 +254,7 @@ namespace ts.server {
private compilerOptionsForInferredProjects: CompilerOptions;
private compileOnSaveForInferredProjects: boolean;
private readonly projectToSizeMap: Map<number> = createMap<number>();
private readonly directoryWatchers: DirectoryWatchers;
private readonly throttledOperations: ThrottledOperations;
@ -270,7 +271,8 @@ namespace ts.server {
public readonly cancellationToken: HostCancellationToken,
public readonly useSingleInferredProject: boolean,
readonly typingsInstaller: ITypingsInstaller = nullTypingsInstaller,
private readonly eventHandler?: ProjectServiceEventHandler) {
private readonly eventHandler?: ProjectServiceEventHandler,
public readonly throttleWaitMilliseconds?: number) {
Debug.assert(!!host.createHash, "'ServerHost.createHash' is required for ProjectService");
@ -563,9 +565,11 @@ namespace ts.server {
switch (project.projectKind) {
case ProjectKind.External:
removeItemFromSet(this.externalProjects, <ExternalProject>project);
this.projectToSizeMap.delete((project as ExternalProject).externalProjectName);
break;
case ProjectKind.Configured:
removeItemFromSet(this.configuredProjects, <ConfiguredProject>project);
this.projectToSizeMap.delete((project as ConfiguredProject).canonicalConfigFilePath);
break;
case ProjectKind.Inferred:
removeItemFromSet(this.inferredProjects, <InferredProject>project);
@ -852,10 +856,15 @@ namespace ts.server {
return { success: true, projectOptions, configFileErrors: errors };
}
private exceededTotalSizeLimitForNonTsFiles<T>(options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>) {
private exceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>) {
if (options && options.disableSizeLimit || !this.host.getFileSize) {
return false;
}
let availableSpace = maxProgramSizeForNonTsFiles;
this.projectToSizeMap.set(name, 0);
this.projectToSizeMap.forEach(val => (availableSpace -= (val || 0)));
let totalNonTsFileSize = 0;
for (const f of fileNames) {
const fileName = propertyReader.getFileName(f);
@ -864,9 +873,16 @@ namespace ts.server {
}
totalNonTsFileSize += this.host.getFileSize(fileName);
if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) {
// Keep the size as zero since it's disabled
return true;
}
}
if (totalNonTsFileSize > availableSpace) {
return true;
}
this.projectToSizeMap.set(name, totalNonTsFileSize);
return false;
}
@ -877,7 +893,7 @@ namespace ts.server {
this,
this.documentRegistry,
compilerOptions,
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader),
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader),
options.compileOnSave === undefined ? true : options.compileOnSave);
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typeAcquisition, /*configFileErrors*/ undefined);
@ -897,7 +913,7 @@ namespace ts.server {
}
private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) {
const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
const project = new ConfiguredProject(
configFileName,
this,
@ -1050,7 +1066,7 @@ namespace ts.server {
return configFileErrors;
}
if (this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) {
if (this.exceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) {
project.setCompilerOptions(projectOptions.compilerOptions);
if (!project.languageServiceEnabled) {
// language service is already disabled
@ -1414,7 +1430,7 @@ namespace ts.server {
if (externalProject) {
if (!tsConfigFiles) {
const compilerOptions = convertCompilerOptions(proj.options);
if (this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
externalProject.disableLanguageService();
}
else {

View file

@ -16,6 +16,7 @@ namespace ts.server {
readonly realpath?: (path: string) => string;
constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) {
this.cancellationToken = new ThrottledCancellationToken(cancellationToken, project.projectService.throttleWaitMilliseconds);
this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
if (host.trace) {

View file

@ -1031,7 +1031,7 @@ namespace ts.server {
export class ExternalProject extends Project {
private typeAcquisition: TypeAcquisition;
constructor(externalProjectName: string,
constructor(public externalProjectName: string,
projectService: ProjectService,
documentRegistry: ts.DocumentRegistry,
compilerOptions: CompilerOptions,

View file

@ -219,6 +219,7 @@ namespace ts.server {
host: ServerHost,
eventPort: number,
readonly globalTypingsCacheLocation: string,
readonly typingSafeListLocation: string,
private newLine: string) {
this.throttledOperations = new ThrottledOperations(host);
if (eventPort) {
@ -260,6 +261,9 @@ namespace ts.server {
if (this.logger.loggingEnabled() && this.logger.getLogFileName()) {
args.push(Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName())), `ti-${process.pid}.log`));
}
if (this.typingSafeListLocation) {
args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation);
}
const execArgv: string[] = [];
{
for (const arg of process.execArgv) {
@ -378,11 +382,12 @@ namespace ts.server {
useSingleInferredProject: boolean,
disableAutomaticTypingAcquisition: boolean,
globalTypingsCacheLocation: string,
typingSafeListLocation: string,
telemetryEnabled: boolean,
logger: server.Logger) {
const typingsInstaller = disableAutomaticTypingAcquisition
? undefined
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, host.newLine);
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, host.newLine);
super(
host,
@ -729,6 +734,8 @@ namespace ts.server {
validateLocaleAndSetLanguage(localeStr, sys);
}
const typingSafeListLocation = findArgument("--typingSafeListLocation");
const useSingleInferredProject = hasArgument("--useSingleInferredProject");
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
@ -741,6 +748,7 @@ namespace ts.server {
useSingleInferredProject,
disableAutomaticTypingAcquisition,
getGlobalTypingsCacheLocation(),
typingSafeListLocation,
telemetryEnabled,
logger);
process.on("uncaughtException", function (err: Error) {

View file

@ -25,8 +25,15 @@ namespace ts.server {
return ((1e9 * seconds) + nanoseconds) / 1000000.0;
}
function shouldSkipSematicCheck(project: Project) {
return (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject();
function shouldSkipSemanticCheck(project: Project) {
if (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) {
return project.isJsOnlyProject();
}
else {
// For configured projects, require that skipLibCheck be set also
const options = project.getCompilerOptions();
return options.skipLibCheck && !options.checkJs && project.isJsOnlyProject();
}
}
interface FileStart {
@ -331,7 +338,8 @@ namespace ts.server {
private hrtime: (start?: number[]) => number[],
protected logger: Logger,
protected readonly canUseEvents: boolean,
eventHandler?: ProjectServiceEventHandler) {
eventHandler?: ProjectServiceEventHandler,
private readonly throttleWaitMilliseconds?: number) {
this.eventHander = canUseEvents
? eventHandler || (event => this.defaultEventHandler(event))
@ -346,7 +354,7 @@ namespace ts.server {
isCancellationRequested: () => cancellationToken.isCancellationRequested()
};
this.errorCheck = new MultistepOperation(multistepOperationHost);
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander);
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander, this.throttleWaitMilliseconds);
this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger);
}
@ -447,7 +455,7 @@ namespace ts.server {
private semanticCheck(file: NormalizedPath, project: Project) {
try {
let diags: Diagnostic[] = [];
if (!shouldSkipSematicCheck(project)) {
if (!shouldSkipSemanticCheck(project)) {
diags = project.getLanguageService().getSemanticDiagnostics(file);
}
@ -555,7 +563,7 @@ namespace ts.server {
private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
const { project, file } = this.getFileAndProject(args);
if (isSemantic && shouldSkipSematicCheck(project)) {
if (isSemantic && shouldSkipSemanticCheck(project)) {
return [];
}
const scriptInfo = project.getScriptInfoForNormalizedPath(file);

View file

@ -11,6 +11,7 @@ namespace ts.server {
export const GlobalCacheLocation = "--globalTypingsCacheLocation";
export const LogFile = "--logFile";
export const EnableTelemetry = "--enableTelemetry";
export const TypingSafeListLocation = "--typingSafeListLocation";
}
export function hasArgument(argumentName: string) {

View file

@ -76,11 +76,11 @@ namespace ts.server.typingsInstaller {
private delayedInitializationError: InitializationFailedResponse;
constructor(globalTypingsCacheLocation: string, throttleLimit: number, log: Log) {
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, throttleLimit: number, log: Log) {
super(
sys,
globalTypingsCacheLocation,
toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
log);
if (this.log.isEnabled()) {
@ -164,6 +164,7 @@ namespace ts.server.typingsInstaller {
const logFilePath = findArgument(server.Arguments.LogFile);
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
const typingSafeListLocation = findArgument(server.Arguments.TypingSafeListLocation);
const log = new FileLog(logFilePath);
if (log.isEnabled()) {
@ -177,6 +178,6 @@ namespace ts.server.typingsInstaller {
}
process.exit(0);
});
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, log);
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, /*throttleLimit*/5, log);
installer.listen();
}

View file

@ -0,0 +1,70 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: getApplicableDiagnosticCodes(),
getCodeActions: getDisableJsDiagnosticsCodeActions
});
function getApplicableDiagnosticCodes(): number[] {
const allDiagnostcs = <MapLike<DiagnosticMessage>>Diagnostics;
return Object.keys(allDiagnostcs)
.filter(d => allDiagnostcs[d] && allDiagnostcs[d].category === DiagnosticCategory.Error)
.map(d => allDiagnostcs[d].code);
}
function getIgnoreCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string) {
const { line } = getLineAndCharacterOfPosition(sourceFile, position);
const lineStartPosition = getStartPositionOfLine(line, sourceFile);
const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
// First try to see if we can put the '// @ts-ignore' on the previous line.
// We need to make sure that we are not in the middle of a string literal or a comment.
// We also want to check if the previous line holds a comment for a node on the next line
// if so, we do not want to separate the node from its comment if we can.
if (!isInComment(sourceFile, startPosition) && !isInString(sourceFile, startPosition) && !isInTemplateString(sourceFile, startPosition)) {
const token = getTouchingToken(sourceFile, startPosition);
const tokenLeadingCommnets = getLeadingCommentRangesOfNode(token, sourceFile);
if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) {
return {
span: { start: startPosition, length: 0 },
newText: `// @ts-ignore${newLineCharacter}`
};
}
}
// If all fails, add an extra new line immediatlly before the error span.
return {
span: { start: position, length: 0 },
newText: `${position === startPosition ? "" : newLineCharacter}// @ts-ignore${newLineCharacter}`
};
}
function getDisableJsDiagnosticsCodeActions(context: CodeFixContext): CodeAction[] | undefined {
const { sourceFile, program, newLineCharacter, span } = context;
if (!isInJavaScriptFile(sourceFile) || !isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
return undefined;
}
return [{
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
changes: [{
fileName: sourceFile.fileName,
textChanges: [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)]
}]
},
{
description: getLocaleSpecificMessage(Diagnostics.Disable_checking_for_this_file),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: {
start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0,
length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0
},
newText: `// @ts-nocheck${newLineCharacter}`
}]
}]
}];
}
}

View file

@ -18,50 +18,121 @@ namespace ts.codefix {
return undefined;
}
const classDeclaration = getContainingClass(token);
if (!classDeclaration) {
if (!isPropertyAccessExpression(token.parent) || token.parent.expression.kind !== SyntaxKind.ThisKeyword) {
return undefined;
}
if (!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) {
const classMemberDeclaration = getThisContainer(token, /*includeArrowFunctions*/ false);
if (!isClassElement(classMemberDeclaration)) {
return undefined;
}
if ((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) {
const classDeclaration = <ClassLikeDeclaration>classMemberDeclaration.parent;
if (!classDeclaration || !isClassLike(classDeclaration)) {
return undefined;
}
let typeString = "any";
const isStatic = hasModifier(classMemberDeclaration, ModifierFlags.Static);
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
const binaryExpression = token.parent.parent as BinaryExpression;
return isInJavaScriptFile(sourceFile) ? getActionsForAddMissingMemberInJavaScriptFile() : getActionsForAddMissingMemberInTypeScriptFile();
const checker = context.program.getTypeChecker();
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
typeString = checker.typeToString(widenedType);
function getActionsForAddMissingMemberInJavaScriptFile(): CodeAction[] | undefined {
const memberName = token.getText();
if (isStatic) {
if (classDeclaration.kind === SyntaxKind.ClassExpression) {
return undefined;
}
const className = classDeclaration.name.getText();
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_static_property_0), [memberName]),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: classDeclaration.getEnd(), length: 0 },
newText: `${context.newLineCharacter}${className}.${memberName} = undefined;${context.newLineCharacter}`
}]
}]
}];
}
else {
const classConstructor = getFirstConstructorWithBody(classDeclaration);
if (!classConstructor) {
return undefined;
}
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_property_0_in_the_constructor), [memberName]),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: classConstructor.body.getEnd() - 1, length: 0 },
newText: `this.${memberName} = undefined;${context.newLineCharacter}`
}]
}]
}];
}
}
const startPos = classDeclaration.members.pos;
function getActionsForAddMissingMemberInTypeScriptFile(): CodeAction[] | undefined {
let typeNode: TypeNode;
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: startPos, length: 0 },
newText: `${token.getFullText(sourceFile)}: ${typeString};`
}]
}]
},
{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: startPos, length: 0 },
newText: `[name: string]: ${typeString};`
}]
}]
}];
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
const binaryExpression = token.parent.parent as BinaryExpression;
const checker = context.program.getTypeChecker();
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
typeNode = checker.typeToTypeNode(widenedType, classDeclaration);
}
typeNode = typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile);
const property = createProperty(
/*decorators*/undefined,
/*modifiers*/ isStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
token.getText(sourceFile),
/*questionToken*/ undefined,
typeNode,
/*initializer*/ undefined);
const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { suffix: context.newLineCharacter });
const actions = [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]),
changes: propertyChangeTracker.getChanges()
}];
if (!isStatic) {
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
const indexingParameter = createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
"x",
/*questionToken*/ undefined,
stringTypeNode,
/*initializer*/ undefined);
const indexSignature = createIndexSignatureDeclaration(
/*decorators*/undefined,
/*modifiers*/ undefined,
[indexingParameter],
typeNode);
const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { suffix: context.newLineCharacter });
actions.push({
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]),
changes: indexSignatureChangeTracker.getChanges()
});
}
return actions;
}
}
}

View file

@ -19,10 +19,9 @@ namespace ts.codefix {
const checker = context.program.getTypeChecker();
if (isClassLike(token.parent)) {
const classDecl = token.parent as ClassLikeDeclaration;
const startPos = classDecl.members.pos;
const classDeclaration = token.parent as ClassLikeDeclaration;
const extendsNode = getClassExtendsHeritageClauseElement(classDecl);
const extendsNode = getClassExtendsHeritageClauseElement(classDeclaration);
const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
// Note that this is ultimately derived from a map indexed by symbol names,
@ -30,18 +29,12 @@ namespace ts.codefix {
const extendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType);
const abstractAndNonPrivateExtendsSymbols = extendsSymbols.filter(symbolPointsToNonPrivateAndAbstractMember);
const insertion = getMissingMembersInsertion(classDecl, abstractAndNonPrivateExtendsSymbols, checker, context.newLineCharacter);
if (insertion.length) {
const newNodes = createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, checker);
const changes = newNodesToChanges(newNodes, getOpenBraceOfClassLike(classDeclaration, sourceFile), context);
if (changes && changes.length > 0) {
return [{
description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: startPos, length: 0 },
newText: insertion
}]
}]
changes
}];
}
}

View file

@ -11,14 +11,14 @@ namespace ts.codefix {
const token = getTokenAtPosition(sourceFile, start);
const checker = context.program.getTypeChecker();
const classDecl = getContainingClass(token);
if (!classDecl) {
const classDeclaration = getContainingClass(token);
if (!classDeclaration) {
return undefined;
}
const startPos: number = classDecl.members.pos;
const classType = checker.getTypeAtLocation(classDecl) as InterfaceType;
const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl);
const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile);
const classType = checker.getTypeAtLocation(classDeclaration) as InterfaceType;
const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDeclaration);
const hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.Number);
const hasStringIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.String);
@ -31,43 +31,36 @@ namespace ts.codefix {
const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
const nonPrivateMembers = implementedTypeSymbols.filter(symbol => !(getModifierFlags(symbol.valueDeclaration) & ModifierFlags.Private));
let insertion = getMissingIndexSignatureInsertion(implementedType, IndexKind.Number, classDecl, hasNumericIndexSignature);
insertion += getMissingIndexSignatureInsertion(implementedType, IndexKind.String, classDecl, hasStringIndexSignature);
insertion += getMissingMembersInsertion(classDecl, nonPrivateMembers, checker, context.newLineCharacter);
let newNodes: Node[] = [];
createAndAddMissingIndexSignatureDeclaration(implementedType, IndexKind.Number, hasNumericIndexSignature, newNodes);
createAndAddMissingIndexSignatureDeclaration(implementedType, IndexKind.String, hasStringIndexSignature, newNodes);
newNodes = newNodes.concat(createMissingMemberNodes(classDeclaration, nonPrivateMembers, checker));
const message = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Implement_interface_0), [implementedTypeNode.getText()]);
if (insertion) {
pushAction(result, insertion, message);
if (newNodes.length > 0) {
pushAction(result, newNodes, message);
}
}
return result;
function getMissingIndexSignatureInsertion(type: InterfaceType, kind: IndexKind, enclosingDeclaration: ClassLikeDeclaration, hasIndexSigOfKind: boolean) {
if (!hasIndexSigOfKind) {
const IndexInfoOfKind = checker.getIndexInfoOfType(type, kind);
if (IndexInfoOfKind) {
const writer = getSingleLineStringWriter();
checker.getSymbolDisplayBuilder().buildIndexSignatureDisplay(IndexInfoOfKind, writer, kind, enclosingDeclaration);
const result = writer.string();
releaseStringWriter(writer);
return result;
}
function createAndAddMissingIndexSignatureDeclaration(type: InterfaceType, kind: IndexKind, hasIndexSigOfKind: boolean, newNodes: Node[]): void {
if (hasIndexSigOfKind) {
return;
}
return "";
const indexInfoOfKind = checker.getIndexInfoOfType(type, kind);
if (!indexInfoOfKind) {
return;
}
const newIndexSignatureDeclaration = checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration);
newNodes.push(newIndexSignatureDeclaration);
}
function pushAction(result: CodeAction[], insertion: string, description: string): void {
function pushAction(result: CodeAction[], newNodes: Node[], description: string): void {
const newAction: CodeAction = {
description: description,
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: startPos, length: 0 },
newText: insertion
}]
}]
changes: newNodesToChanges(newNodes, openBrace, context)
};
result.push(newAction);
}

View file

@ -16,7 +16,7 @@ namespace ts.codefix {
return undefined;
}
// figure out if the this access is actuall inside the supercall
// figure out if the `this` access is actually inside the supercall
// i.e. super(this.a), since in that case we won't suggest a fix
if (superCall.expression && superCall.expression.kind == SyntaxKind.CallExpression) {
const arguments = (<CallExpression>superCall.expression).arguments;

View file

@ -7,4 +7,5 @@
/// <reference path="fixForgottenThisPropertyAccess.ts" />
/// <reference path='unusedIdentifierFixes.ts' />
/// <reference path='importFixes.ts' />
/// <reference path='disableJsDiagnostics.ts' />
/// <reference path='helpers.ts' />

View file

@ -1,47 +1,88 @@
/* @internal */
namespace ts.codefix {
export function newNodesToChanges(newNodes: Node[], insertAfter: Node, context: CodeFixContext) {
const sourceFile = context.sourceFile;
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
for (const newNode of newNodes) {
changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter });
}
const changes = changeTracker.getChanges();
if (!some(changes)) {
return changes;
}
Debug.assert(changes.length === 1);
const consolidatedChanges: FileTextChanges[] = [{
fileName: changes[0].fileName,
textChanges: [{
span: changes[0].textChanges[0].span,
newText: changes[0].textChanges.reduce((prev, cur) => prev + cur.newText, "")
}]
}];
return consolidatedChanges;
}
/**
* Finds members of the resolved type that are missing in the class pointed to by class decl
* and generates source code for the missing members.
* @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
* @returns Empty string iff there are no member insertions.
*/
export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker, newlineChar: string): string {
export function createMissingMemberNodes(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker): Node[] {
const classMembers = classDeclaration.symbol.members;
const missingMembers = possiblyMissingSymbols.filter(symbol => !classMembers.has(symbol.getName()));
let insertion = "";
let newNodes: Node[] = [];
for (const symbol of missingMembers) {
insertion = insertion.concat(getInsertionForMemberSymbol(symbol, classDeclaration, checker, newlineChar));
const newNode = createNewNodeForMemberSymbol(symbol, classDeclaration, checker);
if (newNode) {
if (Array.isArray(newNode)) {
newNodes = newNodes.concat(newNode);
}
else {
newNodes.push(newNode);
}
}
}
return insertion;
return newNodes;
}
/**
* @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
*/
function getInsertionForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker, newlineChar: string): string {
function createNewNodeForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker): Node[] | Node | undefined {
const declarations = symbol.getDeclarations();
if (!(declarations && declarations.length)) {
return "";
return undefined;
}
const declaration = declarations[0] as Declaration;
const name = declaration.name ? declaration.name.getText() : undefined;
const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration));
const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration);
// Clone name to remove leading trivia.
const name = getSynthesizedClone(<PropertyName>declaration.name);
const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration));
const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined;
const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
const optional = !!(symbol.flags & SymbolFlags.Optional);
switch (declaration.kind) {
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyDeclaration:
const typeString = checker.typeToString(type, enclosingDeclaration, TypeFormatFlags.None);
return `${visibility}${name}: ${typeString};${newlineChar}`;
const typeNode = checker.typeToTypeNode(type, enclosingDeclaration);
const property = createProperty(
/*decorators*/undefined,
modifiers,
name,
optional ? createToken(SyntaxKind.QuestionToken) : undefined,
typeNode,
/*initializer*/ undefined);
return property;
case SyntaxKind.MethodSignature:
case SyntaxKind.MethodDeclaration:
// The signature for the implementation appears as an entry in `signatures` iff
@ -52,109 +93,142 @@ namespace ts.codefix {
// (eg: an abstract method or interface declaration), there is a 1-1
// correspondence of declarations and signatures.
const signatures = checker.getSignaturesOfType(type, SignatureKind.Call);
if (!(signatures && signatures.length > 0)) {
return "";
if (!some(signatures)) {
return undefined;
}
if (declarations.length === 1) {
Debug.assert(signatures.length === 1);
const sigString = checker.signatureToString(signatures[0], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call);
return getStubbedMethod(visibility, name, sigString, newlineChar);
const signature = signatures[0];
return signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody());
}
let result = "";
const signatureDeclarations: MethodDeclaration[] = [];
for (let i = 0; i < signatures.length; i++) {
const sigString = checker.signatureToString(signatures[i], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call);
result += `${visibility}${name}${sigString};${newlineChar}`;
const signature = signatures[i];
const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration);
if (methodDeclaration) {
signatureDeclarations.push(methodDeclaration);
}
}
// If there is a declaration with a body, it is the last declaration,
// and it isn't caught by `getSignaturesOfType`.
let bodySig: Signature | undefined = undefined;
if (declarations.length > signatures.length) {
bodySig = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration);
const signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration);
const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody());
if (methodDeclaration) {
signatureDeclarations.push(methodDeclaration);
}
}
else {
Debug.assert(declarations.length === signatures.length);
bodySig = createBodySignatureWithAnyTypes(signatures, enclosingDeclaration, checker);
const methodImplementingSignatures = createMethodImplementingSignatures(signatures, name, optional, modifiers);
signatureDeclarations.push(methodImplementingSignatures);
}
const sigString = checker.signatureToString(bodySig, enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call);
result += getStubbedMethod(visibility, name, sigString, newlineChar);
return result;
return signatureDeclarations;
default:
return "";
return undefined;
}
function signatureToMethodDeclaration(signature: Signature, enclosingDeclaration: Node, body?: Block) {
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration);
if (signatureDeclaration) {
signatureDeclaration.decorators = undefined;
signatureDeclaration.modifiers = modifiers;
signatureDeclaration.name = name;
signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined;
signatureDeclaration.body = body;
}
return signatureDeclaration;
}
}
function createBodySignatureWithAnyTypes(signatures: Signature[], enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker): Signature {
const newSignatureDeclaration = createNode(SyntaxKind.CallSignature) as SignatureDeclaration;
newSignatureDeclaration.parent = enclosingDeclaration;
newSignatureDeclaration.name = signatures[0].getDeclaration().name;
let maxNonRestArgs = -1;
let maxArgsIndex = 0;
function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration {
/** This is *a* signature with the maximal number of arguments,
* such that if there is a "maximal" signature without rest arguments,
* this is one of them.
*/
let maxArgsSignature = signatures[0];
let minArgumentCount = signatures[0].minArgumentCount;
let hasRestParameter = false;
let someSigHasRestParameter = false;
for (let i = 0; i < signatures.length; i++) {
const sig = signatures[i];
minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
hasRestParameter = hasRestParameter || sig.hasRestParameter;
const nonRestLength = sig.parameters.length - (sig.hasRestParameter ? 1 : 0);
if (nonRestLength > maxNonRestArgs) {
maxNonRestArgs = nonRestLength;
maxArgsIndex = i;
if (sig.hasRestParameter) {
someSigHasRestParameter = true;
}
if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) {
maxArgsSignature = sig;
}
}
const maxArgsParameterSymbolNames = signatures[maxArgsIndex].getParameters().map(symbol => symbol.getName());
const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0);
const maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(symbol => symbol.getName());
const optionalToken = createToken(SyntaxKind.QuestionToken);
newSignatureDeclaration.parameters = createNodeArray<ParameterDeclaration>();
const parameters: ParameterDeclaration[] = [];
for (let i = 0; i < maxNonRestArgs; i++) {
const newParameter = createParameterDeclarationWithoutType(i, minArgumentCount, newSignatureDeclaration);
newSignatureDeclaration.parameters.push(newParameter);
const anyType = createKeywordTypeNode(SyntaxKind.AnyKeyword);
const newParameter = createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
maxArgsParameterSymbolNames[i],
/*questionToken*/ i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined,
anyType,
/*initializer*/ undefined);
parameters.push(newParameter);
}
if (hasRestParameter) {
const restParameter = createParameterDeclarationWithoutType(maxNonRestArgs, minArgumentCount, newSignatureDeclaration);
restParameter.dotDotDotToken = createToken(SyntaxKind.DotDotDotToken);
newSignatureDeclaration.parameters.push(restParameter);
if (someSigHasRestParameter) {
const anyArrayType = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword));
const restParameter = createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createToken(SyntaxKind.DotDotDotToken),
maxArgsParameterSymbolNames[maxNonRestArgs] || "rest",
/*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined,
anyArrayType,
/*initializer*/ undefined);
parameters.push(restParameter);
}
return checker.getSignatureFromDeclaration(newSignatureDeclaration);
function createParameterDeclarationWithoutType(index: number, minArgCount: number, enclosingSignatureDeclaration: SignatureDeclaration): ParameterDeclaration {
const newParameter = createNode(SyntaxKind.Parameter) as ParameterDeclaration;
newParameter.symbol = new SymbolConstructor(SymbolFlags.FunctionScopedVariable, maxArgsParameterSymbolNames[index] || "rest");
newParameter.symbol.valueDeclaration = newParameter;
newParameter.symbol.declarations = [newParameter];
newParameter.parent = enclosingSignatureDeclaration;
if (index >= minArgCount) {
newParameter.questionToken = optionalToken;
}
return newParameter;
}
return createStubbedMethod(
modifiers,
name,
optional,
/*typeParameters*/undefined,
parameters,
/*returnType*/ undefined);
}
export function getStubbedMethod(visibility: string, name: string, sigString = "()", newlineChar: string): string {
return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`;
export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) {
return createMethodDeclaration(
/*decorators*/ undefined,
modifiers,
/*asteriskToken*/ undefined,
name,
optional ? createToken(SyntaxKind.QuestionToken) : undefined,
typeParameters,
parameters,
returnType,
createStubbedMethodBody());
}
function getMethodBodyStub(newlineChar: string) {
return ` {${newlineChar}throw new Error('Method not implemented.');${newlineChar}}${newlineChar}`;
function createStubbedMethodBody() {
return createBlock(
[createThrow(
createNew(
createIdentifier("Error"),
/*typeArguments*/undefined,
[createLiteral("Method not implemented.")]))],
/*multiline*/true);
}
function getVisibilityPrefixWithSpace(flags: ModifierFlags): string {
function createVisibilityModifier(flags: ModifierFlags) {
if (flags & ModifierFlags.Public) {
return "public ";
return createToken(SyntaxKind.PublicKeyword);
}
else if (flags & ModifierFlags.Protected) {
return "protected ";
return createToken(SyntaxKind.ProtectedKeyword);
}
return "";
return undefined;
}
const SymbolConstructor = objectAllocator.getSymbolConstructor();
}

View file

@ -2,6 +2,36 @@
/* @internal */
namespace ts.NavigationBar {
/**
* Matches all whitespace characters in a string. Eg:
*
* "app.
*
* onactivated"
*
* matches because of the newline, whereas
*
* "app.onactivated"
*
* does not match.
*/
const whiteSpaceRegex = /\s+/g;
// Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
let curCancellationToken: CancellationToken;
let curSourceFile: SourceFile;
/**
* For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
* `parent` is the current parent and is *not* stored in parentsStack.
* `startNode` sets a new parent and `endNode` returns to the previous parent.
*/
let parentsStack: NavigationBarNode[] = [];
let parent: NavigationBarNode;
// NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
let emptyChildItemArray: NavigationBarItem[] = [];
/**
* Represents a navigation bar item and its children.
* The returned NavigationBarItem is more complicated and doesn't include 'parent', so we use these to do work before converting.
@ -14,22 +44,36 @@ namespace ts.NavigationBar {
indent: number; // # of parents
}
export function getNavigationBarItems(sourceFile: SourceFile): NavigationBarItem[] {
export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarItem[] {
curCancellationToken = cancellationToken;
curSourceFile = sourceFile;
const result = map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
curSourceFile = undefined;
return result;
try {
return map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
}
finally {
reset();
}
}
export function getNavigationTree(sourceFile: SourceFile): NavigationTree {
export function getNavigationTree(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationTree {
curCancellationToken = cancellationToken;
curSourceFile = sourceFile;
const result = convertToTree(rootNavigationBarNode(sourceFile));
curSourceFile = undefined;
return result;
try {
return convertToTree(rootNavigationBarNode(sourceFile));
}
finally {
reset();
}
}
function reset() {
curSourceFile = undefined;
curCancellationToken = undefined;
parentsStack = [];
parent = undefined;
emptyChildItemArray = [];
}
// Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
let curSourceFile: SourceFile;
function nodeText(node: Node): string {
return node.getText(curSourceFile);
}
@ -47,14 +91,6 @@ namespace ts.NavigationBar {
}
}
/*
For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
`parent` is the current parent and is *not* stored in parentsStack.
`startNode` sets a new parent and `endNode` returns to the previous parent.
*/
const parentsStack: NavigationBarNode[] = [];
let parent: NavigationBarNode;
function rootNavigationBarNode(sourceFile: SourceFile): NavigationBarNode {
Debug.assert(!parentsStack.length);
const root: NavigationBarNode = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 };
@ -111,6 +147,8 @@ namespace ts.NavigationBar {
/** Look for navigation bar items in node's subtree, adding them to the current `parent`. */
function addChildrenRecursively(node: Node): void {
curCancellationToken.throwIfCancellationRequested();
if (!node || isToken(node)) {
return;
}
@ -487,9 +525,6 @@ namespace ts.NavigationBar {
}
}
// NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
const emptyChildItemArray: NavigationBarItem[] = [];
function convertToTree(n: NavigationBarNode): NavigationTree {
return {
text: getItemName(n.node),
@ -610,19 +645,4 @@ namespace ts.NavigationBar {
function isFunctionOrClassExpression(node: Node): boolean {
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction || node.kind === SyntaxKind.ClassExpression;
}
/**
* Matches all whitespace characters in a string. Eg:
*
* "app.
*
* onactivated"
*
* matches because of the newline, whereas
*
* "app.onactivated"
*
* does not match.
*/
const whiteSpaceRegex = /\s+/g;
}

View file

@ -1,6 +1,6 @@
/* @internal */
namespace ts.OutliningElementsCollector {
export function collectElements(sourceFile: SourceFile): OutliningSpan[] {
export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] {
const elements: OutliningSpan[] = [];
const collapseText = "...";
@ -38,6 +38,7 @@ namespace ts.OutliningElementsCollector {
let singleLineCommentCount = 0;
for (const currentComment of comments) {
cancellationToken.throwIfCancellationRequested();
// For single line comments, combine consecutive ones (2 or more) into
// a single span from the start of the first till the end of the last
@ -84,6 +85,7 @@ namespace ts.OutliningElementsCollector {
let depth = 0;
const maxDepth = 20;
function walk(n: Node): void {
cancellationToken.throwIfCancellationRequested();
if (depth > maxDepth) {
return;
}

View file

@ -482,6 +482,7 @@ namespace ts {
public moduleAugmentations: LiteralExpression[];
private namedDeclarations: Map<Declaration[]>;
public ambientModuleNames: string[];
public checkJsDirective: CheckJsDirective | undefined;
constructor(kind: SyntaxKind, pos: number, end: number) {
super(kind, pos, end);
@ -981,6 +982,36 @@ namespace ts {
}
}
/* @internal */
/** A cancellation that throttles calls to the host */
export class ThrottledCancellationToken implements CancellationToken {
// Store when we last tried to cancel. Checking cancellation can be expensive (as we have
// to marshall over to the host layer). So we only bother actually checking once enough
// time has passed.
private lastCancellationCheckTime = 0;
constructor(private hostCancellationToken: HostCancellationToken, private readonly throttleWaitMilliseconds = 20) {
}
public isCancellationRequested(): boolean {
const time = timestamp();
const duration = Math.abs(time - this.lastCancellationCheckTime);
if (duration >= this.throttleWaitMilliseconds) {
// Check no more than once every throttle wait milliseconds
this.lastCancellationCheckTime = time;
return this.hostCancellationToken.isCancellationRequested();
}
return false;
}
public throwIfCancellationRequested(): void {
if (this.isCancellationRequested()) {
throw new OperationCanceledException();
}
}
}
export function createLanguageService(host: LanguageServiceHost,
documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService {
@ -1552,11 +1583,11 @@ namespace ts {
}
function getNavigationBarItems(fileName: string): NavigationBarItem[] {
return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName));
return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
}
function getNavigationTree(fileName: string): NavigationTree {
return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName));
return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
}
function isTsOrTsxFile(fileName: string): boolean {
@ -1595,7 +1626,7 @@ namespace ts {
function getOutliningSpans(fileName: string): OutliningSpan[] {
// doesn't use compiler - no need to synchronize with host
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
return OutliningElementsCollector.collectElements(sourceFile);
return OutliningElementsCollector.collectElements(sourceFile, cancellationToken);
}
function getBraceMatchingAtPosition(fileName: string, position: number) {

View file

@ -469,29 +469,6 @@ namespace ts {
}
}
/** A cancellation that throttles calls to the host */
class ThrottledCancellationToken implements HostCancellationToken {
// Store when we last tried to cancel. Checking cancellation can be expensive (as we have
// to marshall over to the host layer). So we only bother actually checking once enough
// time has passed.
private lastCancellationCheckTime = 0;
constructor(private hostCancellationToken: HostCancellationToken) {
}
public isCancellationRequested(): boolean {
const time = timestamp();
const duration = Math.abs(time - this.lastCancellationCheckTime);
if (duration > 10) {
// Check no more than once every 10 ms.
this.lastCancellationCheckTime = time;
return this.hostCancellationToken.isCancellationRequested();
}
return false;
}
}
export class CoreServicesShimHostAdapter implements ParseConfigHost, ModuleResolutionHost {
public directoryExists: (directoryName: string) => boolean;

View file

@ -419,7 +419,7 @@ namespace ts.SymbolDisplay {
if (!documentation) {
documentation = symbol.getDocumentationComment();
if (documentation.length === 0 && symbol.flags & SymbolFlags.Property) {
// For some special property access expressions like `experts.foo = foo` or `module.exports.foo = foo`
// For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo`
// there documentation comments might be attached to the right hand side symbol of their declarations.
// The pattern of such special property access is that the parent symbol is the symbol of the file.
if (symbol.parent && forEach(symbol.parent.declarations, declaration => declaration.kind === SyntaxKind.SourceFile)) {

View file

@ -274,9 +274,9 @@ namespace ts.textChanges {
}
/**
* This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
* i.e. arguments in arguments lists, parameters in parameter lists etc. Statements or class elements are different in sense that
* for them separators are treated as the part of the node.
* This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
* i.e. arguments in arguments lists, parameters in parameter lists etc.
* Note that separators are part of the node in statements and class elements.
*/
public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node) {
const containingList = formatting.SmartIndenter.getContainingList(after, sourceFile);
@ -484,7 +484,7 @@ namespace ts.textChanges {
private static normalize(changes: Change[]) {
// order changes by start position
const normalized = stableSort(changes, (a, b) => a.range.pos - b.range.pos);
// verify that end position of the change is less than start position of the next change
// verify that change intervals do not overlap, except possibly at end points.
for (let i = 0; i < normalized.length - 2; i++) {
Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos);
}
@ -549,7 +549,7 @@ namespace ts.textChanges {
};
function assignPositionsToNode(node: Node): Node {
const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray);
const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode);
// create proxy node for non synthesized nodes
const newNode = nodeIsSynthesized(visited)
? visited

View file

@ -91,6 +91,7 @@
"codefixes/fixes.ts",
"codefixes/helpers.ts",
"codefixes/importFixes.ts",
"codefixes/unusedIdentifierFixes.ts"
"codefixes/unusedIdentifierFixes.ts",
"codefixes/disableJsDiagnostics.ts"
]
}

View file

@ -1380,8 +1380,19 @@ namespace ts {
};
}
export function getFirstNonSpaceCharacterPosition(text: string, position: number) {
while (isWhiteSpace(text.charCodeAt(position))) {
position += 1;
}
return position;
}
export function getOpenBrace(constructor: ConstructorDeclaration, sourceFile: SourceFile) {
// First token is the open curly, this is where we want to put the 'super' call.
return constructor.body.getFirstToken(sourceFile);
}
export function getOpenBraceOfClassLike(declaration: ClassLikeDeclaration, sourceFile: SourceFile) {
return getTokenAtPosition(sourceFile, declaration.members.pos - 1);
}
}

View file

@ -1,11 +1,8 @@
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(1,15): error TS2495: Type 'StringIterator' is not an array type or a string type.
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(11,6): error TS2304: Cannot find name 'Symbol'.
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(10,6): error TS2304: Cannot find name 'Symbol'.
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(15,15): error TS2495: Type 'StringIterator' is not an array type or a string type.
==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts (2 errors) ====
for (var v of new StringIterator) { }
~~~~~~~~~~~~~~~~~~
!!! error TS2495: Type 'StringIterator' is not an array type or a string type.
// In ES3/5, you cannot for...of over an arbitrary iterable.
class StringIterator {
@ -20,4 +17,8 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(11,6
!!! error TS2304: Cannot find name 'Symbol'.
return this;
}
}
}
for (var v of new StringIterator) { }
~~~~~~~~~~~~~~~~~~
!!! error TS2495: Type 'StringIterator' is not an array type or a string type.

View file

@ -1,5 +1,4 @@
//// [ES5For-ofTypeCheck10.ts]
for (var v of new StringIterator) { }
// In ES3/5, you cannot for...of over an arbitrary iterable.
class StringIterator {
@ -12,12 +11,11 @@ class StringIterator {
[Symbol.iterator]() {
return this;
}
}
}
for (var v of new StringIterator) { }
//// [ES5For-ofTypeCheck10.js]
for (var _i = 0, _a = new StringIterator; _i < _a.length; _i++) {
var v = _a[_i];
}
// In ES3/5, you cannot for...of over an arbitrary iterable.
var StringIterator = (function () {
function StringIterator() {
@ -33,3 +31,6 @@ var StringIterator = (function () {
};
return StringIterator;
}());
for (var _i = 0, _a = new StringIterator; _i < _a.length; _i++) {
var v = _a[_i];
}

Some files were not shown because too many files have changed in this diff Show more