Merge branch 'master' into use-common-directory-for-out

This commit is contained in:
Wesley Wigham 2015-11-18 13:10:23 -08:00
commit c7a3bee916
64 changed files with 2239 additions and 1656 deletions

View File

@ -35,7 +35,8 @@
"browserify": "latest",
"istanbul": "latest",
"mocha-fivemat-progress-reporter": "latest",
"tslint": "latest",
"tslint": "next",
"typescript": "next",
"tsd": "latest"
},
"scripts": {

View File

@ -1,6 +1,5 @@
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
import * as Lint from "tslint/lib/lint";
import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING_FACTORY = (name: string, currently: string) => `Tag boolean argument as '${name}' (currently '${currently}')`;
@ -19,7 +18,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
visitCallExpression(node: ts.CallExpression) {
super.visitCallExpression(node);
if (node.arguments) {
if (node.arguments) {
const targetCallSignature = this.checker.getResolvedSignature(node);
if (!!targetCallSignature) {
const targetParameters = targetCallSignature.getParameters();
@ -37,7 +36,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
let triviaContent: string;
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); //+/-2 to remove /**/
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); // +/-2 to remove /**/
}
if (triviaContent !== param.getName()) {
this.addFailure(this.createFailure(arg.getStart(source), arg.getWidth(source), Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent)));
@ -45,6 +44,6 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
}
}
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
import * as Lint from "tslint/lib/lint";
import * as ts from "typescript";
const OPTION_CATCH = "check-catch";
const OPTION_ELSE = "check-else";

View File

@ -1,5 +1,5 @@
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
import * as Lint from "tslint/lib/lint";
import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {

View File

@ -1,5 +1,5 @@
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
import * as Lint from "tslint/lib/lint";
import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {
@ -85,12 +85,12 @@ class PreferConstWalker extends Lint.RuleWalker {
visitBinaryExpression(node: ts.BinaryExpression) {
if (isAssignmentOperator(node.operatorToken.kind)) {
this.visitLHSExpressions(node.left);
this.visitLeftHandSideExpression(node.left);
}
super.visitBinaryExpression(node);
}
private visitLHSExpressions(node: ts.Expression) {
private visitLeftHandSideExpression(node: ts.Expression) {
while (node.kind === ts.SyntaxKind.ParenthesizedExpression) {
node = (node as ts.ParenthesizedExpression).expression;
}
@ -101,23 +101,25 @@ class PreferConstWalker extends Lint.RuleWalker {
this.visitBindingLiteralExpression(node as (ts.ArrayLiteralExpression | ts.ObjectLiteralExpression));
}
}
private visitBindingLiteralExpression(node: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression) {
if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
const pattern = node as ts.ObjectLiteralExpression;
for (const element of pattern.properties) {
if (element.name.kind === ts.SyntaxKind.Identifier) {
this.markAssignment(element.name as ts.Identifier)
const kind = element.kind;
if (kind === ts.SyntaxKind.ShorthandPropertyAssignment) {
this.markAssignment((element as ts.ShorthandPropertyAssignment).name);
}
else if (isBindingPattern(element.name)) {
this.visitBindingPatternIdentifiers(element.name as ts.BindingPattern);
else if (kind === ts.SyntaxKind.PropertyAssignment) {
this.visitLeftHandSideExpression((element as ts.PropertyAssignment).initializer);
}
}
}
else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
const pattern = node as ts.ArrayLiteralExpression;
for (const element of pattern.elements) {
this.visitLHSExpressions(element);
this.visitLeftHandSideExpression(element);
}
}
}
@ -145,7 +147,7 @@ class PreferConstWalker extends Lint.RuleWalker {
private visitAnyUnaryExpression(node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression) {
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) {
this.visitLHSExpressions(node.operand);
this.visitLeftHandSideExpression(node.operand);
}
}
@ -211,12 +213,12 @@ class PreferConstWalker extends Lint.RuleWalker {
}
}
private collectNameIdentifiers(value: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map<DeclarationUsages>) {
private collectNameIdentifiers(declaration: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map<DeclarationUsages>) {
if (node.kind === ts.SyntaxKind.Identifier) {
table[(node as ts.Identifier).text] = {declaration: value, usages: 0};
table[(node as ts.Identifier).text] = { declaration, usages: 0 };
}
else {
this.collectBindingPatternIdentifiers(value, node as ts.BindingPattern, table);
this.collectBindingPatternIdentifiers(declaration, node as ts.BindingPattern, table);
}
}

View File

@ -1,5 +1,5 @@
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
import * as Lint from "tslint/lib/lint";
import * as ts from "typescript";
export class Rule extends Lint.Rules.AbstractRule {

View File

@ -139,6 +139,8 @@ namespace ts {
file.classifiableNames = classifiableNames;
}
file = undefined;
options = undefined;
parent = undefined;
container = undefined;
blockScopeContainer = undefined;

View File

@ -122,8 +122,8 @@ namespace ts {
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
const anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false);
const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false);
const anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
const globals: SymbolTable = {};
@ -476,15 +476,41 @@ namespace ts {
// Locals of a source file are not in scope (because they get merged into the global symbol table)
if (location.locals && !isGlobalSourceFile(location)) {
if (result = getSymbol(location.locals, name, meaning)) {
// Type parameters of a function are in scope in the entire function declaration, including the parameter
// list and return type. However, local types are only in scope in the function body.
if (!(meaning & SymbolFlags.Type) ||
!(result.flags & (SymbolFlags.Type & ~SymbolFlags.TypeParameter)) ||
!isFunctionLike(location) ||
lastLocation === (<FunctionLikeDeclaration>location).body) {
let useResult = true;
if (isFunctionLike(location) && lastLocation && lastLocation !== (<FunctionLikeDeclaration>location).body) {
// symbol lookup restrictions for function-like declarations
// - Type parameters of a function are in scope in the entire function declaration, including the parameter
// list and return type. However, local types are only in scope in the function body.
// - parameters are only in the scope of function body
if (meaning & result.flags & SymbolFlags.Type) {
useResult = result.flags & SymbolFlags.TypeParameter
// type parameters are visible in parameter list, return type and type parameter list
? lastLocation === (<FunctionLikeDeclaration>location).type ||
lastLocation.kind === SyntaxKind.Parameter ||
lastLocation.kind === SyntaxKind.TypeParameter
// local types not visible outside the function body
: false;
}
if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) {
// parameters are visible only inside function body, parameter list and return type
// technically for parameter list case here we might mix parameters and variables declared in function,
// however it is detected separately when checking initializers of parameters
// to make sure that they reference no variables declared after them.
useResult =
lastLocation.kind === SyntaxKind.Parameter ||
(
lastLocation === (<FunctionLikeDeclaration>location).type &&
result.valueDeclaration.kind === SyntaxKind.Parameter
);
}
}
if (useResult) {
break loop;
}
result = undefined;
else {
result = undefined;
}
}
}
switch (location.kind) {
@ -2276,7 +2302,7 @@ namespace ts {
return false;
}
resolutionTargets.push(target);
resolutionResults.push(true);
resolutionResults.push(/*items*/ true);
resolutionPropertyNames.push(propertyName);
return true;
}
@ -3348,7 +3374,7 @@ namespace ts {
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
if (!hasClassBaseType(classType)) {
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)];
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)];
}
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
@ -3829,7 +3855,13 @@ namespace ts {
let minArgumentCount = -1;
for (let i = 0, n = declaration.parameters.length; i < n; i++) {
const param = declaration.parameters[i];
parameters.push(param.symbol);
let paramSymbol = param.symbol;
// Include parameter symbol instead of property symbol in the signature
if (paramSymbol && !!(paramSymbol.flags & SymbolFlags.Property) && !isBindingPattern(param.name)) {
const resolvedSymbol = resolveName(param, paramSymbol.name, SymbolFlags.Value, undefined, undefined);
paramSymbol = resolvedSymbol;
}
parameters.push(paramSymbol);
if (param.type && param.type.kind === SyntaxKind.StringLiteral) {
hasStringLiterals = true;
}
@ -3973,7 +4005,7 @@ namespace ts {
}
function getSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature {
return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), true);
return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
}
function getErasedSignature(signature: Signature): Signature {
@ -3983,7 +4015,7 @@ namespace ts {
signature.erasedSignatureCache = instantiateSignature(getErasedSignature(signature.target), signature.mapper);
}
else {
signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), true);
signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
}
}
return signature.erasedSignatureCache;
@ -5099,7 +5131,7 @@ namespace ts {
let result = Ternary.True;
const sourceTypes = source.types;
for (const sourceType of sourceTypes) {
const related = typeRelatedToSomeType(sourceType, target, false);
const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
if (!related) {
return Ternary.False;
}
@ -5497,7 +5529,7 @@ namespace ts {
const saveErrorInfo = errorInfo;
let related = isRelatedTo(s, t, reportErrors);
if (!related) {
related = isRelatedTo(t, s, false);
related = isRelatedTo(t, s, /*reportErrors*/ false);
if (!related) {
if (reportErrors) {
reportError(Diagnostics.Types_of_parameters_0_and_1_are_incompatible,
@ -5624,7 +5656,7 @@ namespace ts {
let related: Ternary;
if (sourceStringType && sourceNumberType) {
// If we know for sure we're testing both string and numeric index types then only report errors from the second one
related = isRelatedTo(sourceStringType, targetType, false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
related = isRelatedTo(sourceStringType, targetType, /*reportErrors*/ false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
}
else {
related = isRelatedTo(sourceStringType || sourceNumberType, targetType, reportErrors);
@ -9873,7 +9905,7 @@ namespace ts {
return type;
}
function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) {
function checkFunctionExpressionOrObjectLiteralMethodBody(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
const isAsync = isAsyncFunctionLike(node);
@ -11360,12 +11392,14 @@ namespace ts {
const errorNode: Node = (<FunctionLikeDeclaration>subsequentNode).name || subsequentNode;
// TODO(jfreeman): These are methods, so handle computed name case
if (node.name && (<FunctionLikeDeclaration>subsequentNode).name && (<Identifier>node.name).text === (<Identifier>(<FunctionLikeDeclaration>subsequentNode).name).text) {
Debug.assert(node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature);
const reportError =
(node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) &&
(node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static);
// we can get here in two cases
// 1. mixed static and instance class members
// 2. something with the same name was defined before the set of overloads that prevents them from merging
// here we'll report error only for the first case since for second we should already report error in binder
if ((node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static)) {
if (reportError) {
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
error(errorNode, diagnostic);
}

View File

@ -842,7 +842,7 @@ namespace ts {
}
export function fail(message?: string): void {
Debug.assert(false, message);
Debug.assert(/*expression*/ false, message);
}
}

View File

@ -516,7 +516,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let decorateEmitted: boolean;
let paramEmitted: boolean;
let awaiterEmitted: boolean;
let tempFlags: TempFlags;
let tempFlags: TempFlags = 0;
let tempVariables: Identifier[];
let tempParameters: Identifier[];
let externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[];
@ -584,33 +584,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
return doEmit;
function doEmit(jsFilePath: string, rootFile?: SourceFile) {
// reset the state
writer.reset();
currentSourceFile = undefined;
currentText = undefined;
currentLineMap = undefined;
exportFunctionForFile = undefined;
generatedNameSet = {};
nodeToGeneratedName = [];
computedPropertyNamesToGeneratedNames = undefined;
convertedLoopState = undefined;
extendsEmitted = false;
decorateEmitted = false;
paramEmitted = false;
awaiterEmitted = false;
tempFlags = 0;
tempVariables = undefined;
tempParameters = undefined;
externalImports = undefined;
exportSpecifiers = undefined;
exportEquals = undefined;
hasExportStars = undefined;
detachedCommentsInfo = undefined;
sourceMapData = undefined;
isEs6Module = false;
renamedDependencies = undefined;
isCurrentFileExternalModule = false;
root = rootFile;
if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
@ -634,6 +609,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
writeLine();
writeEmittedFiles(writer.getText(), jsFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM);
// reset the state
writer.reset();
currentSourceFile = undefined;
currentText = undefined;
currentLineMap = undefined;
exportFunctionForFile = undefined;
generatedNameSet = undefined;
nodeToGeneratedName = undefined;
computedPropertyNamesToGeneratedNames = undefined;
convertedLoopState = undefined;
extendsEmitted = false;
decorateEmitted = false;
paramEmitted = false;
awaiterEmitted = false;
tempFlags = 0;
tempVariables = undefined;
tempParameters = undefined;
externalImports = undefined;
exportSpecifiers = undefined;
exportEquals = undefined;
hasExportStars = undefined;
detachedCommentsInfo = undefined;
sourceMapData = undefined;
isEs6Module = false;
renamedDependencies = undefined;
isCurrentFileExternalModule = false;
root = undefined;
}
function emitSourceFile(sourceFile: SourceFile): void {
@ -1292,7 +1295,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
function emitCommaList(nodes: Node[]) {
if (nodes) {
emitList(nodes, 0, nodes.length, /*multiline*/ false, /*trailingComma*/ false);
emitList(nodes, 0, nodes.length, /*multiLine*/ false, /*trailingComma*/ false);
}
}
@ -2191,7 +2194,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
else if (languageVersion >= ScriptTarget.ES6 || !forEach(elements, isSpreadElementExpression)) {
write("[");
emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces:*/ false);
emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false);
write("]");
}
else {
@ -2215,7 +2218,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
// then try to preserve the original shape of the object literal.
// Otherwise just try to preserve the formatting.
if (numElements === properties.length) {
emitLinePreservingList(node, properties, /* allowTrailingComma */ languageVersion >= ScriptTarget.ES5, /* spacesBetweenBraces */ true);
emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true);
}
else {
const multiLine = (node.flags & NodeFlags.MultiLine) !== 0;
@ -2765,7 +2768,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(".bind.apply(");
emit(target);
write(", [void 0].concat(");
emitListWithSpread(node.arguments, /*needsUniqueCopy*/ false, /*multiline*/ false, /*trailingComma*/ false, /*useConcat*/ false);
emitListWithSpread(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*trailingComma*/ false, /*useConcat*/ false);
write(")))");
write("()");
}
@ -2982,7 +2985,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
synthesizedLHS = <ElementAccessExpression>createSynthesizedNode(SyntaxKind.ElementAccessExpression, /*startsOnNewLine*/ false);
const identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefinedTempVariablesInPlaces*/ false, /*shouldEmitCommaBeforeAssignment*/ false);
const identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefineTempVariablesInPlace*/ false, /*shouldEmitCommaBeforeAssignment*/ false);
synthesizedLHS.expression = identifier;
if (leftHandSideExpression.argumentExpression.kind !== SyntaxKind.NumericLiteral &&
@ -3001,7 +3004,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("(");
synthesizedLHS = <PropertyAccessExpression>createSynthesizedNode(SyntaxKind.PropertyAccessExpression, /*startsOnNewLine*/ false);
const identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefinedTempVariablesInPlaces*/ false, /*shouldemitCommaBeforeAssignment*/ false);
const identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefineTempVariablesInPlace*/ false, /*shouldEmitCommaBeforeAssignment*/ false);
synthesizedLHS.expression = identifier;
(<PropertyAccessExpression>synthesizedLHS).dotToken = leftHandSideExpression.dotToken;
@ -3181,10 +3184,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
function emitDoStatementWorker(node: DoStatement, loop: ConvertedLoop) {
write("do");
if (loop) {
emitConvertedLoopCall(loop, /* emitAsBlock */ true);
emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
}
else {
emitNormalLoopBody(node, /* emitAsEmbeddedStatement */ true);
emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
}
if (node.statement.kind === SyntaxKind.Block) {
write(" ");
@ -3207,10 +3210,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(")");
if (loop) {
emitConvertedLoopCall(loop, /* emitAsBlock */ true);
emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
}
else {
emitNormalLoopBody(node, /* emitAsEmbeddedStatement */ true);
emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
}
}
@ -3532,8 +3535,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(`switch(${loopResultVariable}) {`);
increaseIndent();
emitDispatchEntriesForLabeledJumps(currentLoop.labeledNonLocalBreaks, /* isBreak */ true, loopResultVariable, outerLoop);
emitDispatchEntriesForLabeledJumps(currentLoop.labeledNonLocalContinues, /* isBreak */ false, loopResultVariable, outerLoop);
emitDispatchEntriesForLabeledJumps(currentLoop.labeledNonLocalBreaks, /*isBreak*/ true, loopResultVariable, outerLoop);
emitDispatchEntriesForLabeledJumps(currentLoop.labeledNonLocalContinues, /*isBreak*/ false, loopResultVariable, outerLoop);
decreaseIndent();
writeLine();
@ -3597,10 +3600,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(")");
if (loop) {
emitConvertedLoopCall(loop, /* emitAsBlock */ true);
emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
}
else {
emitNormalLoopBody(node, /* emitAsEmbeddedStatement */ true);
emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
}
}
@ -3638,10 +3641,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitToken(SyntaxKind.CloseParenToken, node.expression.end);
if (loop) {
emitConvertedLoopCall(loop, /* emitAsBlock */ true);
emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
}
else {
emitNormalLoopBody(node, /* emitAsEmbeddedStatement */ true);
emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
}
}
@ -3781,10 +3784,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
if (loop) {
writeLine();
emitConvertedLoopCall(loop, /* emitAsBlock */ false);
emitConvertedLoopCall(loop, /*emitAsBlock*/ false);
}
else {
emitNormalLoopBody(node, /* emitAsEmbeddedStatement */ false);
emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ false);
}
writeLine();
@ -3818,11 +3821,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let labelMarker: string;
if (node.kind === SyntaxKind.BreakStatement) {
labelMarker = `break-${node.label.text}`;
setLabeledJump(convertedLoopState, /* isBreak */ true, node.label.text, labelMarker);
setLabeledJump(convertedLoopState, /*isBreak*/ true, node.label.text, labelMarker);
}
else {
labelMarker = `continue-${node.label.text}`;
setLabeledJump(convertedLoopState, /* isBreak */ false, node.label.text, labelMarker);
setLabeledJump(convertedLoopState, /*isBreak*/ false, node.label.text, labelMarker);
}
write(`return "${labelMarker}";`);
}
@ -4248,7 +4251,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let index: Expression;
const nameIsComputed = propName.kind === SyntaxKind.ComputedPropertyName;
if (nameIsComputed) {
index = ensureIdentifier((<ComputedPropertyName>propName).expression, /* reuseIdentifierExpression */ false);
index = ensureIdentifier((<ComputedPropertyName>propName).expression, /*reuseIdentifierExpressions*/ false);
}
else {
// We create a synthetic copy of the identifier in order to avoid the rewriting that might
@ -5380,7 +5383,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitEnd(baseTypeElement);
}
}
emitPropertyDeclarations(node, getInitializedProperties(node, /*static:*/ false));
emitPropertyDeclarations(node, getInitializedProperties(node, /*isStatic*/ false));
if (ctor) {
let statements: Node[] = (<Block>ctor.body).statements;
if (superCall) {
@ -5502,7 +5505,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
//
// This keeps the expression as an expression, while ensuring that the static parts
// of it have been initialized by the time it is used.
const staticProperties = getInitializedProperties(node, /*static:*/ true);
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
const isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === SyntaxKind.ClassExpression;
let tempVariable: Identifier;
@ -5564,7 +5567,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
for (var property of staticProperties) {
write(",");
writeLine();
emitPropertyDeclaration(node, property, /*receiver:*/ tempVariable, /*isExpression:*/ true);
emitPropertyDeclaration(node, property, /*receiver*/ tempVariable, /*isExpression*/ true);
}
write(",");
writeLine();
@ -5638,7 +5641,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
writeLine();
emitConstructor(node, baseTypeNode);
emitMemberFunctionsForES5AndLower(node);
emitPropertyDeclarations(node, getInitializedProperties(node, /*static:*/ true));
emitPropertyDeclarations(node, getInitializedProperties(node, /*isStatic*/ true));
writeLine();
emitDecoratorsOfClass(node);
writeLine();
@ -8087,11 +8090,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
* Emit comments associated with node that will not be emitted into JS file
*/
function emitCommentsOnNotEmittedNode(node: Node) {
emitLeadingCommentsWorker(node, /*isEmittedNode:*/ false);
emitLeadingCommentsWorker(node, /*isEmittedNode*/ false);
}
function emitLeadingComments(node: Node) {
return emitLeadingCommentsWorker(node, /*isEmittedNode:*/ true);
return emitLeadingCommentsWorker(node, /*isEmittedNode*/ true);
}
function emitLeadingCommentsWorker(node: Node, isEmittedNode: boolean) {
@ -8120,7 +8123,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator:*/ true, newLine, writeComment);
emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitTrailingComments(node: Node) {

View File

@ -722,10 +722,10 @@ namespace ts {
const contextFlagsToClear = context & contextFlags;
if (contextFlagsToClear) {
// clear the requested context flags
setContextFlag(false, contextFlagsToClear);
setContextFlag(/*val*/ false, contextFlagsToClear);
const result = func();
// restore the context flags we just cleared
setContextFlag(true, contextFlagsToClear);
setContextFlag(/*val*/ true, contextFlagsToClear);
return result;
}
@ -743,10 +743,10 @@ namespace ts {
const contextFlagsToSet = context & ~contextFlags;
if (contextFlagsToSet) {
// set the requested context flags
setContextFlag(true, contextFlagsToSet);
setContextFlag(/*val*/ true, contextFlagsToSet);
const result = func();
// reset the context flags we just set
setContextFlag(false, contextFlagsToSet);
setContextFlag(/*val*/ false, contextFlagsToSet);
return result;
}
@ -1098,11 +1098,11 @@ namespace ts {
}
function parsePropertyName(): PropertyName {
return parsePropertyNameWorker(/*allowComputedPropertyNames:*/ true);
return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
}
function parseSimplePropertyName(): Identifier | LiteralExpression {
return <Identifier | LiteralExpression>parsePropertyNameWorker(/*allowComputedPropertyNames:*/ false);
return <Identifier | LiteralExpression>parsePropertyNameWorker(/*allowComputedPropertyNames*/ false);
}
function isSimplePropertyName() {
@ -1157,7 +1157,7 @@ namespace ts {
}
function parseAnyContextualModifier(): boolean {
return isModifier(token) && tryParse(nextTokenCanFollowModifier);
return isModifierKind(token) && tryParse(nextTokenCanFollowModifier);
}
function canFollowModifier(): boolean {
@ -1385,7 +1385,7 @@ namespace ts {
function isInSomeParsingContext(): boolean {
for (let kind = 0; kind < ParsingContext.Count; kind++) {
if (parsingContext & (1 << kind)) {
if (isListElement(kind, /* inErrorRecovery */ true) || isListTerminator(kind)) {
if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) {
return true;
}
}
@ -1402,7 +1402,7 @@ namespace ts {
result.pos = getNodePos();
while (!isListTerminator(kind)) {
if (isListElement(kind, /* inErrorRecovery */ false)) {
if (isListElement(kind, /*inErrorRecovery*/ false)) {
const element = parseListElement(kind, parseElement);
result.push(element);
@ -1751,7 +1751,7 @@ namespace ts {
let commaStart = -1; // Meaning the previous token was not a comma
while (true) {
if (isListElement(kind, /* inErrorRecovery */ false)) {
if (isListElement(kind, /*inErrorRecovery*/ false)) {
result.push(parseListElement(kind, parseElement));
commaStart = scanner.getTokenPos();
if (parseOptional(SyntaxKind.CommaToken)) {
@ -1859,7 +1859,7 @@ namespace ts {
// Report that we need an identifier. However, report it right after the dot,
// and not on the next token. This is because the next token might actually
// be an identifier and the error would be quite confusing.
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentToken*/ true, Diagnostics.Identifier_expected);
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected);
}
}
@ -2004,7 +2004,7 @@ namespace ts {
}
function isStartOfParameter(): boolean {
return token === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifier(token) || token === SyntaxKind.AtToken;
return token === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifierKind(token) || token === SyntaxKind.AtToken;
}
function setModifiers(node: Node, modifiers: ModifiersArray) {
@ -2025,7 +2025,7 @@ namespace ts {
node.name = parseIdentifierOrPattern();
if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifier(token)) {
if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifierKind(token)) {
// in cases like
// 'use strict'
// function foo(static)
@ -2132,8 +2132,8 @@ namespace ts {
parseSemicolon();
}
function parseSignatureMember(kind: SyntaxKind): SignatureDeclaration {
const node = <SignatureDeclaration>createNode(kind);
function parseSignatureMember(kind: SyntaxKind): CallSignatureDeclaration | ConstructSignatureDeclaration {
const node = <CallSignatureDeclaration | ConstructSignatureDeclaration>createNode(kind);
if (kind === SyntaxKind.ConstructSignature) {
parseExpected(SyntaxKind.NewKeyword);
}
@ -2172,7 +2172,7 @@ namespace ts {
return true;
}
if (isModifier(token)) {
if (isModifierKind(token)) {
nextToken();
if (isIdentifier()) {
return true;
@ -2215,13 +2215,13 @@ namespace ts {
return finishNode(node);
}
function parsePropertyOrMethodSignature(): Declaration {
function parsePropertyOrMethodSignature(): PropertySignature | MethodSignature {
const fullStart = scanner.getStartPos();
const name = parsePropertyName();
const questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
const method = <MethodDeclaration>createNode(SyntaxKind.MethodSignature, fullStart);
const method = <MethodSignature>createNode(SyntaxKind.MethodSignature, fullStart);
method.name = name;
method.questionToken = questionToken;
@ -2232,7 +2232,7 @@ namespace ts {
return finishNode(method);
}
else {
const property = <PropertyDeclaration>createNode(SyntaxKind.PropertySignature, fullStart);
const property = <PropertySignature>createNode(SyntaxKind.PropertySignature, fullStart);
property.name = name;
property.questionToken = questionToken;
property.type = parseTypeAnnotation();
@ -2248,7 +2248,7 @@ namespace ts {
case SyntaxKind.OpenBracketToken: // Both for indexers and computed properties
return true;
default:
if (isModifier(token)) {
if (isModifierKind(token)) {
const result = lookAhead(isStartOfIndexSignatureDeclaration);
if (result) {
return result;
@ -2260,7 +2260,7 @@ namespace ts {
}
function isStartOfIndexSignatureDeclaration() {
while (isModifier(token)) {
while (isModifierKind(token)) {
nextToken();
}
@ -2276,7 +2276,7 @@ namespace ts {
canParseSemicolon();
}
function parseTypeMember(): Declaration {
function parseTypeMember(): TypeElement {
switch (token) {
case SyntaxKind.OpenParenToken:
case SyntaxKind.LessThanToken:
@ -2301,7 +2301,7 @@ namespace ts {
// when incrementally parsing as the parser will produce the Index declaration
// if it has the same text regardless of whether it is inside a class or an
// object type.
if (isModifier(token)) {
if (isModifierKind(token)) {
const result = tryParse(parseIndexSignatureWithModifiers);
if (result) {
return result;
@ -2334,14 +2334,14 @@ namespace ts {
return finishNode(node);
}
function parseObjectTypeMembers(): NodeArray<Declaration> {
let members: NodeArray<Declaration>;
function parseObjectTypeMembers(): NodeArray<TypeElement> {
let members: NodeArray<TypeElement>;
if (parseExpected(SyntaxKind.OpenBraceToken)) {
members = parseList(ParsingContext.TypeMembers, parseTypeMember);
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
members = createMissingList<Declaration>();
members = createMissingList<TypeElement>();
}
return members;
@ -2483,11 +2483,11 @@ namespace ts {
// ( ...
return true;
}
if (isIdentifier() || isModifier(token)) {
if (isIdentifier() || isModifierKind(token)) {
nextToken();
if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken ||
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken ||
isIdentifier() || isModifier(token)) {
isIdentifier() || isModifierKind(token)) {
// ( id :
// ( id ,
// ( id ?
@ -2609,7 +2609,7 @@ namespace ts {
// clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator
const saveDecoratorContext = inDecoratorContext();
if (saveDecoratorContext) {
setDecoratorContext(false);
setDecoratorContext(/*val*/ false);
}
let expr = parseAssignmentExpressionOrHigher();
@ -2619,7 +2619,7 @@ namespace ts {
}
if (saveDecoratorContext) {
setDecoratorContext(true);
setDecoratorContext(/*val*/ true);
}
return expr;
}
@ -2773,7 +2773,7 @@ namespace ts {
node.parameters.pos = parameter.pos;
node.parameters.end = parameter.end;
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, false, Diagnostics._0_expected, "=>");
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>");
node.body = parseArrowFunctionExpressionBody(/*isAsync*/ false);
return finishNode(node);
@ -2894,7 +2894,7 @@ namespace ts {
}
// This *could* be a parenthesized arrow function.
// Return Unknown to const the caller know.
// Return Unknown to let the caller know.
return Tristate.Unknown;
}
else {
@ -2993,7 +2993,7 @@ namespace ts {
// user meant to supply a block. For example, if the user wrote:
//
// a =>
// const v = 0;
// let v = 0;
// }
//
// they may be missing an open brace. Check to see if that's the case so we can
@ -3220,7 +3220,7 @@ namespace ts {
/**
* Parse ES7 unary expression and await expression
*
*
* ES7 UnaryExpression:
* 1) SimpleUnaryExpression[?yield]
* 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
@ -3573,7 +3573,7 @@ namespace ts {
parseExpected(SyntaxKind.GreaterThanToken);
}
else {
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
scanJsxText();
}
node = <JsxSelfClosingElement>createNode(SyntaxKind.JsxSelfClosingElement, fullStart);
@ -3609,7 +3609,7 @@ namespace ts {
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*advance*/ false);
parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*shouldAdvance*/ false);
scanJsxText();
}
@ -3654,7 +3654,7 @@ namespace ts {
parseExpected(SyntaxKind.GreaterThanToken);
}
else {
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
scanJsxText();
}
return finishNode(node);
@ -3973,7 +3973,7 @@ namespace ts {
// function BindingIdentifier[opt](FormalParameters){ FunctionBody }
const saveDecoratorContext = inDecoratorContext();
if (saveDecoratorContext) {
setDecoratorContext(false);
setDecoratorContext(/*val*/ false);
}
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression);
@ -3993,7 +3993,7 @@ namespace ts {
node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
if (saveDecoratorContext) {
setDecoratorContext(true);
setDecoratorContext(/*val*/ true);
}
return finishNode(node);
@ -4039,13 +4039,13 @@ namespace ts {
// arrow function. The body of the function is not in [Decorator] context.
const saveDecoratorContext = inDecoratorContext();
if (saveDecoratorContext) {
setDecoratorContext(false);
setDecoratorContext(/*val*/ false);
}
const block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
if (saveDecoratorContext) {
setDecoratorContext(true);
setDecoratorContext(/*val*/ true);
}
setYieldContext(savedYieldContext);
@ -4720,7 +4720,7 @@ namespace ts {
return finishNode(node);
}
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, asteriskToken: Node, name: DeclarationName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
const method = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, fullStart);
method.decorators = decorators;
setModifiers(method, modifiers);
@ -4734,7 +4734,7 @@ namespace ts {
return finishNode(method);
}
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, name: DeclarationName, questionToken: Node): ClassElement {
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, name: PropertyName, questionToken: Node): ClassElement {
const property = <PropertyDeclaration>createNode(SyntaxKind.PropertyDeclaration, fullStart);
property.decorators = decorators;
setModifiers(property, modifiers);
@ -4808,7 +4808,7 @@ namespace ts {
}
// Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
while (isModifier(token)) {
while (isModifierKind(token)) {
idToken = token;
// If the idToken is a class modifier (protected, private, public, and static), it is
// certain that we are starting to parse class member. This allows better error recovery
@ -5018,8 +5018,8 @@ namespace ts {
// implements is a future reserved word so
// 'class implements' might mean either
// - class expression with omitted name, 'implements' starts heritage clause
// - class with name 'implements'
// 'isImplementsClause' helps to disambiguate between these two cases
// - class with name 'implements'
// 'isImplementsClause' helps to disambiguate between these two cases
return isIdentifier() && !isImplementsClause()
? parseIdentifier()
: undefined;
@ -6162,7 +6162,7 @@ namespace ts {
if (sourceFile.statements.length === 0) {
// If we don't have any statements in the current source file, then there's no real
// way to incrementally parse. So just do a full parse instead.
return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setNodeParents*/ true);
return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true);
}
// Make sure we're not trying to incrementally update a source file more than once. Once
@ -6226,7 +6226,7 @@ namespace ts {
// inconsistent tree. Setting the parents on the new tree should be very fast. We
// will immediately bail out of walking any subtrees when we can see that their parents
// are already correct.
const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true);
const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true);
return result;
}

View File

@ -363,13 +363,13 @@ namespace ts {
}
if (!tryReuseStructureFromOldProgram()) {
forEach(rootNames, name => processRootFile(name, false));
forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false));
// Do not process the default library if:
// - The '--noLib' flag is used.
// - A 'no-default-lib' reference comment is encountered in
// processing the root files.
if (!skipDefaultLib) {
processRootFile(host.getDefaultLibFileName(options), true);
processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib*/ true);
}
}
@ -694,7 +694,7 @@ namespace ts {
let imports: LiteralExpression[];
for (const node of file.statements) {
collect(node, /* allowRelativeModuleNames */ true, /* collectOnlyRequireCalls */ false);
collect(node, /*allowRelativeModuleNames*/ true, /*collectOnlyRequireCalls*/ false);
}
file.imports = imports || emptyArray;
@ -730,7 +730,7 @@ namespace ts {
// TypeScript 1.0 spec (April 2014): 12.1.6
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
// only through top - level external module names. Relative external module names are not permitted.
collect(node, /* allowRelativeModuleNames */ false, collectOnlyRequireCalls);
collect(node, /*allowRelativeModuleNames*/ false, collectOnlyRequireCalls);
});
}
break;
@ -742,7 +742,7 @@ namespace ts {
(imports || (imports = [])).push(<StringLiteral>(<CallExpression>node).arguments[0]);
}
else {
forEachChild(node, node => collect(node, allowRelativeModuleNames, /* collectOnlyRequireCalls */ true));
forEachChild(node, node => collect(node, allowRelativeModuleNames, /*collectOnlyRequireCalls*/ true));
}
}
}
@ -801,12 +801,12 @@ namespace ts {
}
// Get source file from normalized fileName
function findSourceFile(fileName: string, normalizedAbsolutePath: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
if (filesByName.contains(normalizedAbsolutePath)) {
const file = filesByName.get(normalizedAbsolutePath);
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
if (filesByName.contains(path)) {
const file = filesByName.get(path);
// try to check if we've already seen this file but with a different casing in path
// NOTE: this only makes sense for case-insensitive file systems
if (file && options.forceConsistentCasingInFileNames && getNormalizedAbsolutePath(file.fileName, currentDirectory) !== normalizedAbsolutePath) {
if (file && options.forceConsistentCasingInFileNames && getNormalizedAbsolutePath(file.fileName, currentDirectory) !== getNormalizedAbsolutePath(fileName, currentDirectory)) {
reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd);
}
@ -824,18 +824,18 @@ namespace ts {
}
});
filesByName.set(normalizedAbsolutePath, file);
filesByName.set(path, file);
if (file) {
file.path = normalizedAbsolutePath;
file.path = path;
if (host.useCaseSensitiveFileNames()) {
// for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
const existingFile = filesByNameIgnoreCase.get(normalizedAbsolutePath);
const existingFile = filesByNameIgnoreCase.get(path);
if (existingFile) {
reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
}
else {
filesByNameIgnoreCase.set(normalizedAbsolutePath, file);
filesByNameIgnoreCase.set(path, file);
}
}
@ -863,7 +863,7 @@ namespace ts {
function processReferencedFiles(file: SourceFile, basePath: string) {
forEach(file.referencedFiles, ref => {
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
processSourceFile(referencedFileName, /* isDefaultLib */ false, file, ref.pos, ref.end);
processSourceFile(referencedFileName, /*isDefaultLib*/ false, file, ref.pos, ref.end);
});
}
@ -881,7 +881,7 @@ namespace ts {
const resolution = resolutions[i];
setResolvedModule(file, moduleNames[i], resolution);
if (resolution && !options.noResolve) {
const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /* isDefaultLib */ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end);
const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end);
if (importedFile && resolution.isExternalLibraryImport) {
if (!isExternalModule(importedFile)) {
@ -905,7 +905,7 @@ namespace ts {
function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string {
let commonPathComponents: string[];
forEach(files, sourceFile => {
const failed = forEach(files, sourceFile => {
// Each file contributes into common source file path
if (isDeclarationFile(sourceFile)) {
return;
@ -921,10 +921,10 @@ namespace ts {
}
for (let i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); i < n; i++) {
if (commonPathComponents[i] !== sourcePathComponents[i]) {
if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
if (i === 0) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
return;
// Failed to find any common path component
return true;
}
// New common path found that is 0 -> i-1
@ -939,6 +939,11 @@ namespace ts {
}
});
// A common path can not be found when paths span multiple drives on windows, for example
if (failed) {
return "";
}
if (!commonPathComponents) { // Can happen when all input files are .d.ts files
return currentDirectory;
}
@ -1057,7 +1062,14 @@ namespace ts {
// If a rootDir is specified and is valid use it as the commonSourceDirectory
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
}
}
else {
// Compute the commonSourceDirectory from the input files
commonSourceDirectory = computeCommonSourceDirectory(files);
// If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
if (options.outDir && commonSourceDirectory === "" && forEach(files, file => getRootLength(file.fileName) > 1)) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
}
}
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
// Make sure directory path ends with directory separator so this string can directly

View File

@ -1634,11 +1634,11 @@ namespace ts {
}
function lookAhead<T>(callback: () => T): T {
return speculationHelper(callback, /*isLookahead:*/ true);
return speculationHelper(callback, /*isLookahead*/ true);
}
function tryScan<T>(callback: () => T): T {
return speculationHelper(callback, /*isLookahead:*/ false);
return speculationHelper(callback, /*isLookahead*/ false);
}
function setText(newText: string, start: number, length: number) {

File diff suppressed because it is too large Load Diff

View File

@ -1327,7 +1327,7 @@ namespace ts {
}
// True if the given identifier, string literal, or number literal is the name of a declaration node
export function isDeclarationName(name: Node): boolean {
export function isDeclarationName(name: Node): name is Identifier | StringLiteral | LiteralExpression {
if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) {
return false;
}
@ -1545,7 +1545,7 @@ namespace ts {
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
}
export function isModifier(token: SyntaxKind): boolean {
export function isModifierKind(token: SyntaxKind): boolean {
switch (token) {
case SyntaxKind.AbstractKeyword:
case SyntaxKind.AsyncKeyword:

View File

@ -40,89 +40,76 @@ class CompilerBaselineRunner extends RunnerBase {
this.basePath += "/" + this.testSuiteName;
}
private makeUnitName(name: string, root: string) {
return ts.isRootedDiskPath(name) ? name : ts.combinePaths(root, name);
};
public checkTestCodeOutput(fileName: string) {
describe("compiler tests for " + fileName, () => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Everything declared here should be cleared out in the "after" callback.
let justName: string;
let content: string;
let testCaseContent: { settings: Harness.TestCaseParser.CompilerSettings; testUnitData: Harness.TestCaseParser.TestUnitData[]; };
let units: Harness.TestCaseParser.TestUnitData[];
let tcSettings: Harness.TestCaseParser.CompilerSettings;
let lastUnit: Harness.TestCaseParser.TestUnitData;
let rootDir: string;
let harnessSettings: Harness.TestCaseParser.CompilerSettings;
let result: Harness.Compiler.CompilerResult;
let program: ts.Program;
let options: ts.CompilerOptions;
// equivalent to the files that will be passed on the command line
let toBeCompiled: { unitName: string; content: string }[];
let toBeCompiled: Harness.Compiler.TestFile[];
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
let otherFiles: { unitName: string; content: string }[];
let harnessCompiler: Harness.Compiler.HarnessCompiler;
let otherFiles: Harness.Compiler.TestFile[];
before(() => {
justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path.
content = Harness.IO.readFile(fileName);
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
units = testCaseContent.testUnitData;
tcSettings = testCaseContent.settings;
const content = Harness.IO.readFile(fileName);
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
const units = testCaseContent.testUnitData;
harnessSettings = testCaseContent.settings;
lastUnit = units[units.length - 1];
rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/";
harnessCompiler = Harness.Compiler.getCompiler();
const rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/";
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
// otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another.
toBeCompiled = [];
otherFiles = [];
if (/require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) {
toBeCompiled.push({ unitName: rootDir + lastUnit.name, content: lastUnit.content });
toBeCompiled.push({ unitName: this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content });
units.forEach(unit => {
if (unit.name !== lastUnit.name) {
otherFiles.push({ unitName: rootDir + unit.name, content: unit.content });
otherFiles.push({ unitName: this.makeUnitName(unit.name, rootDir), content: unit.content });
}
});
}
else {
toBeCompiled = units.map(unit => {
return { unitName: rootDir + unit.name, content: unit.content };
return { unitName: this.makeUnitName(unit.name, rootDir), content: unit.content };
});
}
options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult, _program) {
result = compileResult;
// The program will be used by typeWriter
program = _program;
}, function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
});
const output = Harness.Compiler.compileFiles(
toBeCompiled, otherFiles, harnessSettings, /* options */ undefined, /* currentDirectory */ undefined);
options = output.options;
result = output.result;
});
after(() => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Therefore we have to clean out large objects after the test is done.
justName = undefined;
content = undefined;
testCaseContent = undefined;
units = undefined;
tcSettings = undefined;
lastUnit = undefined;
rootDir = undefined;
result = undefined;
program = undefined;
options = undefined;
toBeCompiled = undefined;
otherFiles = undefined;
harnessCompiler = undefined;
});
function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string {
return file.writeByteOrderMark ? "\u00EF\u00BB\u00BF" : "";
}
function getErrorBaseline(toBeCompiled: { unitName: string; content: string }[], otherFiles: { unitName: string; content: string }[], result: Harness.Compiler.CompilerResult) {
function getErrorBaseline(toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], result: Harness.Compiler.CompilerResult) {
return Harness.Compiler.getErrorBaseline(toBeCompiled.concat(otherFiles), result.errors);
}
@ -184,9 +171,9 @@ class CompilerBaselineRunner extends RunnerBase {
}
}
const declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
}, options);
const declFileCompilationResult =
Harness.Compiler.compileDeclarationFiles(
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined);
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
@ -257,10 +244,11 @@ class CompilerBaselineRunner extends RunnerBase {
// These types are equivalent, but depend on what order the compiler observed
// certain parts of the program.
const program = result.program;
const allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName));
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ true);
const pullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ false);
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
const pullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ false);
const fullResults: ts.Map<TypeWriterResult[]> = {};
const pullResults: ts.Map<TypeWriterResult[]> = {};
@ -274,14 +262,14 @@ class CompilerBaselineRunner extends RunnerBase {
// The second gives symbols for all identifiers.
let e1: Error, e2: Error;
try {
checkBaseLines(/*isSymbolBaseLine:*/ false);
checkBaseLines(/*isSymbolBaseLine*/ false);
}
catch (e) {
e1 = e;
}
try {
checkBaseLines(/*isSymbolBaseLine:*/ true);
checkBaseLines(/*isSymbolBaseLine*/ true);
}
catch (e) {
e2 = e;
@ -367,7 +355,6 @@ class CompilerBaselineRunner extends RunnerBase {
public initializeTests() {
describe(this.testSuiteName + " tests", () => {
describe("Setup compiler for compiler baselines", () => {
const harnessCompiler = Harness.Compiler.getCompiler();
this.parseOptions();
});

File diff suppressed because it is too large Load Diff

View File

@ -58,56 +58,6 @@ class FourSlashRunner extends RunnerBase {
}
});
});
describe("Generate Tao XML", () => {
const invalidReasons: any = {};
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1;
}
});
const invalidReport: { reason: string; count: number }[] = [];
for (const reason in invalidReasons) {
if (invalidReasons.hasOwnProperty(reason)) {
invalidReport.push({ reason: reason, count: invalidReasons[reason] });
}
}
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
const lines: string[] = [];
lines.push("<!-- Blocked Test Report");
invalidReport.forEach((reasonAndCount) => {
lines.push(reasonAndCount.count + " tests blocked by " + reasonAndCount.reason);
});
lines.push("-->");
lines.push("<TaoTest xmlns=\"http://microsoft.com/schemas/VSLanguages/TAO\">");
lines.push(" <InitTest>");
lines.push(" <StartTarget />");
lines.push(" </InitTest>");
lines.push(" <ScenarioList>");
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
lines.push("<!-- Skipped " + xml.originalName + ", reason: " + xml.invalidReason + " -->");
}
else {
lines.push(" <Scenario Name=\"" + xml.originalName + "\">");
xml.actions.forEach(action => {
lines.push(" " + action);
});
lines.push(" </Scenario>");
}
});
lines.push(" </ScenarioList>");
lines.push(" <CleanupScenario>");
lines.push(" <CloseAllDocuments />");
lines.push(" <CleanupCreatedFiles />");
lines.push(" </CleanupScenario>");
lines.push(" <CleanupTest>");
lines.push(" <CloseTarget />");
lines.push(" </CleanupTest>");
lines.push("</TaoTest>");
Harness.IO.writeFile("built/local/fourslash.xml", lines.join("\r\n"));
});
});
}
}

View File

@ -628,7 +628,7 @@ namespace Harness {
function getResolvedPathFromServer(path: string) {
const xhr = new XMLHttpRequest();
try {
xhr.open("GET", path + "?resolve", false);
xhr.open("GET", path + "?resolve", /*async*/ false);
xhr.send();
}
catch (e) {
@ -647,7 +647,7 @@ namespace Harness {
export function getFileFromServerSync(url: string): XHRResponse {
const xhr = new XMLHttpRequest();
try {
xhr.open("GET", url, false);
xhr.open("GET", url, /*async*/ false);
xhr.send();
}
catch (e) {
@ -662,7 +662,7 @@ namespace Harness {
const xhr = new XMLHttpRequest();
try {
const actionMsg = "?action=" + action;
xhr.open("POST", url + actionMsg, false);
xhr.open("POST", url + actionMsg, /*async*/ false);
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.send(contents);
}
@ -767,26 +767,9 @@ namespace Harness {
}
namespace Harness {
let tcServicesFileName = "typescriptServices.js";
export let libFolder: string;
switch (Utils.getExecutionEnvironment()) {
case Utils.ExecutionEnvironment.CScript:
libFolder = "built/local/";
tcServicesFileName = "built/local/typescriptServices.js";
break;
case Utils.ExecutionEnvironment.Node:
libFolder = "built/local/";
tcServicesFileName = "built/local/typescriptServices.js";
break;
case Utils.ExecutionEnvironment.Browser:
libFolder = "built/local/";
tcServicesFileName = "built/local/typescriptServices.js";
break;
default:
throw new Error("Unknown context");
}
export let tcServicesFile = IO.readFile(tcServicesFileName);
export const libFolder = "built/local/";
const tcServicesFileName = ts.combinePaths(libFolder, "typescriptServices.js");
export const tcServicesFile = IO.readFile(tcServicesFileName);
export interface SourceMapEmitterCallback {
(emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void;
@ -827,57 +810,14 @@ namespace Harness {
}
}
export interface IEmitterIOHost {
writeFile(path: string, contents: string, writeByteOrderMark: boolean): void;
resolvePath(path: string): string;
}
/** Mimics having multiple files, later concatenated to a single file. */
export class EmitterIOHost implements IEmitterIOHost {
private fileCollection: any = {};
/** create file gets the whole path to create, so this works as expected with the --out parameter */
public writeFile(s: string, contents: string, writeByteOrderMark: boolean): void {
let writer: ITextWriter;
if (this.fileCollection[s]) {
writer = <ITextWriter>this.fileCollection[s];
}
else {
writer = new Harness.Compiler.WriterAggregator();
this.fileCollection[s] = writer;
}
writer.Write(contents);
writer.Close();
}
public resolvePath(s: string) { return s; }
public reset() { this.fileCollection = {}; }
public toArray(): { fileName: string; file: WriterAggregator; }[] {
const result: { fileName: string; file: WriterAggregator; }[] = [];
for (const p in this.fileCollection) {
if (this.fileCollection.hasOwnProperty(p)) {
const current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
if (current.lines.length > 0) {
if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); }
result.push({ fileName: p, file: this.fileCollection[p] });
}
}
}
return result;
}
}
export function createSourceFileAndAssertInvariants(
fileName: string,
sourceText: string,
languageVersion: ts.ScriptTarget) {
// We'll only assert inletiants outside of light mode.
// We'll only assert invariants outside of light mode.
const shouldAssertInvariants = !Harness.lightMode;
// Only set the parent nodes if we're asserting inletiants. We don't need them otherwise.
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
const result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
if (shouldAssertInvariants) {
@ -890,12 +830,12 @@ namespace Harness {
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export let defaultLibFileName = "lib.d.ts";
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
export const defaultLibFileName = "lib.d.ts";
export const defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
export const defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
// Cache these between executions so we don't have to re-parse them for every test
export let fourslashFileName = "fourslash.ts";
export const fourslashFileName = "fourslash.ts";
export let fourslashSourceFile: ts.SourceFile;
export function getCanonicalFileName(fileName: string): string {
@ -903,41 +843,32 @@ namespace Harness {
}
export function createCompilerHost(
inputFiles: { unitName: string; content: string; }[],
inputFiles: TestFile[],
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
scriptTarget: ts.ScriptTarget,
useCaseSensitiveFileNames: boolean,
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
currentDirectory?: string,
currentDirectory: string,
newLineKind?: ts.NewLineKind): ts.CompilerHost {
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
function getCanonicalFileName(fileName: string): string {
return useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
}
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
const filemap: { [fileName: string]: ts.SourceFile; } = {};
const getCurrentDirectory = currentDirectory === undefined ? Harness.IO.getCurrentDirectory : () => currentDirectory;
// Register input files
function register(file: { unitName: string; content: string; }) {
const fileMap: ts.FileMap<ts.SourceFile> = ts.createFileMap<ts.SourceFile>();
for (const file of inputFiles) {
if (file.content !== undefined) {
const fileName = ts.normalizePath(file.unitName);
const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
filemap[getCanonicalFileName(fileName)] = sourceFile;
filemap[getCanonicalFileName(ts.getNormalizedAbsolutePath(fileName, getCurrentDirectory()))] = sourceFile;
const path = ts.toPath(file.unitName, currentDirectory, getCanonicalFileName);
fileMap.set(path, sourceFile);
}
};
inputFiles.forEach(register);
}
function getSourceFile(fn: string, languageVersion: ts.ScriptTarget) {
fn = ts.normalizePath(fn);
if (Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(fn))) {
return filemap[getCanonicalFileName(fn)];
}
else if (currentDirectory) {
const canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
const path = ts.toPath(fn, currentDirectory, getCanonicalFileName);
if (fileMap.contains(path)) {
return fileMap.get(path);
}
else if (fn === fourslashFileName) {
const tsFn = "tests/cases/fourslash/" + fourslashFileName;
@ -959,7 +890,7 @@ namespace Harness {
Harness.IO.newLine();
return {
getCurrentDirectory,
getCurrentDirectory: () => currentDirectory,
getSourceFile,
getDefaultLibFileName: options => defaultLibFileName,
writeFile,
@ -1034,177 +965,139 @@ namespace Harness {
}
}
export class HarnessCompiler {
private inputFiles: { unitName: string; content: string }[] = [];
private compileOptions: ts.CompilerOptions;
private settings: Harness.TestCaseParser.CompilerSettings = {};
export interface TestFile {
unitName: string;
content: string;
}
private lastErrors: ts.Diagnostic[];
export interface CompilationOutput {
result: CompilerResult;
options: ts.CompilerOptions & HarnessOptions;
}
public reset() {
this.inputFiles = [];
this.settings = {};
this.lastErrors = [];
export function compileFiles(
inputFiles: TestFile[],
otherFiles: TestFile[],
harnessSettings: TestCaseParser.CompilerSettings,
compilerOptions: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory: string): CompilationOutput {
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.clone(compilerOptions) : { noResolve: false };
options.target = options.target || ts.ScriptTarget.ES3;
options.module = options.module || ts.ModuleKind.None;
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
options.noErrorTruncation = true;
options.skipDefaultLibCheck = true;
currentDirectory = currentDirectory || Harness.IO.getCurrentDirectory();
// Parse settings
let useCaseSensitiveFileNames = Harness.IO.useCaseSensitiveFileNames();
if (harnessSettings) {
setCompilerOptionsFromHarnessSetting(harnessSettings, options);
}
if (options.useCaseSensitiveFileNames !== undefined) {
useCaseSensitiveFileNames = options.useCaseSensitiveFileNames;
}
public reportCompilationErrors() {
return this.lastErrors;
const programFiles: TestFile[] = inputFiles.slice();
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
// Treat them as library files, so include them in build, but not in baselines.
if (options.includeBuiltFile) {
const builtFileName = ts.combinePaths(libFolder, options.includeBuiltFile);
const builtFile: TestFile = {
unitName: builtFileName,
content: normalizeLineEndings(IO.readFile(builtFileName), Harness.IO.newLine()),
};
programFiles.push(builtFile);
}
public setCompilerSettings(tcSettings: Harness.TestCaseParser.CompilerSettings) {
this.settings = tcSettings;
const fileOutputs: GeneratedFile[] = [];
const programFileNames = programFiles.map(file => file.unitName);
const compilerHost = createCompilerHost(
programFiles.concat(otherFiles),
(fileName, code, writeByteOrderMark) => fileOutputs.push({ fileName, code, writeByteOrderMark }),
options.target,
useCaseSensitiveFileNames,
currentDirectory,
options.newLine);
const program = ts.createProgram(programFileNames, options, compilerHost);
const emitResult = program.emit();
const errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
const result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
return { result, options };
}
export function compileDeclarationFiles(inputFiles: TestFile[],
otherFiles: TestFile[],
result: CompilerResult,
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions,
options: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory: string) {
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
}
public addInputFiles(files: { unitName: string; content: string }[]) {
files.forEach(file => this.addInputFile(file));
const declInputFiles: TestFile[] = [];
const declOtherFiles: TestFile[] = [];
// if the .d.ts is non-empty, confirm it compiles correctly as well
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory);
return { declInputFiles, declOtherFiles, declResult: output.result };
}
public addInputFile(file: { unitName: string; content: string }) {
this.inputFiles.push(file);
}
public setCompilerOptions(options?: ts.CompilerOptions) {
this.compileOptions = options || { noResolve: false };
}
public emitAll(ioHost?: IEmitterIOHost) {
this.compileFiles(this.inputFiles,
/*otherFiles*/ [],
/*onComplete*/ result => {
result.files.forEach(writeFile);
result.declFilesCode.forEach(writeFile);
result.sourceMaps.forEach(writeFile);
},
/*settingsCallback*/ () => { },
this.compileOptions);
function writeFile(file: GeneratedFile) {
ioHost.writeFile(file.fileName, file.code, false);
function addDtsFile(file: TestFile, dtsFiles: TestFile[]) {
if (isDTS(file.unitName)) {
dtsFiles.push(file);
}
}
public compileFiles(inputFiles: { unitName: string; content: string }[],
otherFiles: { unitName: string; content: string }[],
onComplete: (result: CompilerResult, program: ts.Program) => void,
settingsCallback?: (settings: ts.CompilerOptions) => void,
options?: ts.CompilerOptions & HarnessOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory?: string) {
options = options || { noResolve: false };
options.target = options.target || ts.ScriptTarget.ES3;
options.module = options.module || ts.ModuleKind.None;
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
options.noErrorTruncation = true;
options.skipDefaultLibCheck = true;
if (settingsCallback) {
settingsCallback(null);
}
const newLine = "\r\n";
// Parse settings
setCompilerOptionsFromHarnessSetting(this.settings, options);
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
// Treat them as library files, so include them in build, but not in baselines.
const includeBuiltFiles: { unitName: string; content: string }[] = [];
if (options.includeBuiltFile) {
const builtFileName = libFolder + options.includeBuiltFile;
includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) });
}
const useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : Harness.IO.useCaseSensitiveFileNames();
const fileOutputs: GeneratedFile[] = [];
const programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
const compilerHost = createCompilerHost(
inputFiles.concat(includeBuiltFiles).concat(otherFiles),
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
const program = ts.createProgram(programFiles, options, compilerHost);
const emitResult = program.emit();
const errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
this.lastErrors = errors;
const result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
onComplete(result, program);
return options;
}
public compileDeclarationFiles(inputFiles: { unitName: string; content: string; }[],
otherFiles: { unitName: string; content: string; }[],
result: CompilerResult,
settingsCallback?: (settings: ts.CompilerOptions) => void,
options?: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory?: string) {
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
}
const declInputFiles: { unitName: string; content: string }[] = [];
const declOtherFiles: { unitName: string; content: string }[] = [];
let declResult: Harness.Compiler.CompilerResult;
// if the .d.ts is non-empty, confirm it compiles correctly as well
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) { declResult = compileResult; },
settingsCallback, options, currentDirectory);
return { declInputFiles, declOtherFiles, declResult };
}
function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) {
if (isDTS(file.unitName)) {
dtsFiles.push(file);
}
else if (isTS(file.unitName)) {
const declFile = findResultCodeFile(file.unitName);
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
}
}
function findResultCodeFile(fileName: string) {
const sourceFile = result.program.getSourceFile(fileName);
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
// Is this file going to be emitted separately
let sourceFileName: string;
const outFile = options.outFile || options.out;
if (ts.isExternalModule(sourceFile) || !outFile) {
if (options.outDir) {
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
}
else {
sourceFileName = sourceFile.fileName;
}
}
else {
// Goes to single --out file
sourceFileName = outFile;
}
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
function findUnit(fileName: string, units: { unitName: string; content: string; }[]) {
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
else if (isTS(file.unitName)) {
const declFile = findResultCodeFile(file.unitName);
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
}
}
}
function findResultCodeFile(fileName: string) {
const sourceFile = result.program.getSourceFile(fileName);
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
// Is this file going to be emitted separately
let sourceFileName: string;
const outFile = options.outFile || options.out;
if (ts.isExternalModule(sourceFile) || !outFile) {
if (options.outDir) {
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
}
else {
sourceFileName = sourceFile.fileName;
}
}
else {
// Goes to single --out file
sourceFileName = outFile;
}
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
function findUnit(fileName: string, units: TestFile[]) {
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
}
}
function normalizeLineEndings(text: string, lineEnding: string): string {
@ -1230,7 +1123,7 @@ namespace Harness {
return errorOutput;
}
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) {
export function getErrorBaseline(inputFiles: TestFile[], diagnostics: ts.Diagnostic[]) {
diagnostics.sort(ts.compareDiagnostics);
const outputLines: string[] = [];
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
@ -1371,16 +1264,6 @@ namespace Harness {
}
}
/** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */
let harnessCompiler: HarnessCompiler;
/** Returns the singleton harness compiler instance for generating and running tests.
If required a fresh compiler instance will be created, otherwise the existing singleton will be re-used.
*/
export function getCompiler() {
return harnessCompiler = harnessCompiler || new HarnessCompiler();
}
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) {
// NEWTODO: Re-implement 'compileString'
@ -1431,7 +1314,7 @@ namespace Harness {
constructor(fileResults: GeneratedFile[], errors: ts.Diagnostic[], public program: ts.Program,
public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) {
fileResults.forEach(emittedFile => {
for (const emittedFile of fileResults) {
if (isDTS(emittedFile.fileName)) {
// .d.ts file, add to declFiles emit
this.declFilesCode.push(emittedFile);
@ -1446,7 +1329,7 @@ namespace Harness {
else {
throw new Error("Unrecognized file extension for file " + emittedFile.fileName);
}
});
}
this.errors = errors;
}
@ -1711,12 +1594,9 @@ namespace Harness {
return filePath.indexOf(Harness.libFolder) === 0;
}
export function getDefaultLibraryFile(io: Harness.IO): { unitName: string, content: string } {
export function getDefaultLibraryFile(io: Harness.IO): Harness.Compiler.TestFile {
const libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts";
return {
unitName: libFile,
content: io.readFile(libFile)
};
return { unitName: libFile, content: io.readFile(libFile) };
}
if (Error) (<any>Error).stackTraceLimit = 1;

View File

@ -7,7 +7,7 @@ namespace Harness.LanguageService {
export class ScriptInfo {
public version: number = 1;
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
public lineMap: number[] = undefined;
private lineMap: number[] = undefined;
constructor(public fileName: string, public content: string) {
this.setContent(content);
@ -15,7 +15,11 @@ namespace Harness.LanguageService {
private setContent(content: string): void {
this.content = content;
this.lineMap = ts.computeLineStarts(content);
this.lineMap = undefined;
}
public getLineMap(): number[] {
return this.lineMap || (this.lineMap = ts.computeLineStarts(this.content));
}
public updateContent(content: string): void {
@ -164,7 +168,7 @@ namespace Harness.LanguageService {
const script: ScriptInfo = this.fileNameToScript[fileName];
assert.isNotNull(script);
return ts.computeLineAndCharacterOfPosition(script.lineMap, position);
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
}
}

View File

@ -174,7 +174,7 @@ namespace Playback {
return true;
}
else {
return findResultByFields(replayLog.fileExists, { path }, false);
return findResultByFields(replayLog.fileExists, { path }, /*defaultValue*/ false);
}
})
);

View File

@ -349,7 +349,7 @@ class ProjectRunner extends RunnerBase {
const inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
sourceFile => sourceFile.fileName !== "lib.d.ts"),
sourceFile => {
return { unitName: RunnerBase.removeFullPaths(sourceFile.fileName), content: sourceFile.text };
return { unitName: RunnerBase.removeFullPaths(sourceFile.fileName), content: sourceFile.text, };
});
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);

View File

@ -27,8 +27,8 @@ namespace RWC {
export function runRWCTest(jsonPath: string) {
describe("Testing a RWC project: " + jsonPath, () => {
let inputFiles: { unitName: string; content: string; }[] = [];
let otherFiles: { unitName: string; content: string; }[] = [];
let inputFiles: Harness.Compiler.TestFile[] = [];
let otherFiles: Harness.Compiler.TestFile[] = [];
let compilerResult: Harness.Compiler.CompilerResult;
let compilerOptions: ts.CompilerOptions;
let baselineOpts: Harness.Baseline.BaselineOptions = {
@ -55,7 +55,6 @@ namespace RWC {
});
it("can compile", () => {
const harnessCompiler = Harness.Compiler.getCompiler();
let opts: ts.ParsedCommandLine;
const ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
@ -71,8 +70,6 @@ namespace RWC {
});
runWithIOLog(ioLog, oldIO => {
harnessCompiler.reset();
let fileNames = opts.fileNames;
const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined);
@ -128,17 +125,21 @@ namespace RWC {
opts.options.noLib = true;
// Emit the results
compilerOptions = harnessCompiler.compileFiles(
compilerOptions = null;
const output = Harness.Compiler.compileFiles(
inputFiles,
otherFiles,
newCompilerResults => { compilerResult = newCompilerResults; },
/*settingsCallback*/ undefined, opts.options,
/* harnessOptions */ undefined,
opts.options,
// Since each RWC json file specifies its current directory in its json file, we need
// to pass this information in explicitly instead of acquiring it from the process.
currentDirectory);
compilerOptions = output.options;
compilerResult = output.result;
});
function getHarnessCompilerInputUnit(fileName: string) {
function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile {
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
let content: string = null;
try {
@ -201,8 +202,9 @@ namespace RWC {
it("has the expected errors in generated declaration files", () => {
if (compilerOptions.declaration && !compilerResult.errors.length) {
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
const declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined, compilerOptions, currentDirectory);
if (declFileCompilationResult.declResult.errors.length === 0) {
return null;
}

View File

@ -190,7 +190,7 @@ namespace Harness.SourceMapRecoder {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
createErrorIfCondition(true, "No encoded entry found");
createErrorIfCondition(/*condition*/ true, "No encoded entry found");
}
export function hasCompletedDecoding() {

View File

@ -5,9 +5,9 @@
class Test262BaselineRunner extends RunnerBase {
private static basePath = "internal/cases/test262";
private static helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
private static helperFile = {
private static helperFile: Harness.Compiler.TestFile = {
unitName: Test262BaselineRunner.helpersFilePath,
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath)
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath),
};
private static testFileExtensionRegex = /\.js$/;
private static options: ts.CompilerOptions = {
@ -31,8 +31,7 @@ class Test262BaselineRunner extends RunnerBase {
let testState: {
filename: string;
compilerResult: Harness.Compiler.CompilerResult;
inputFiles: { unitName: string; content: string }[];
program: ts.Program;
inputFiles: Harness.Compiler.TestFile[];
};
before(() => {
@ -40,8 +39,9 @@ class Test262BaselineRunner extends RunnerBase {
const testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
const inputFiles = testCaseContent.testUnitData.map(unit => {
return { unitName: Test262BaselineRunner.getTestFilePath(unit.name), content: unit.content };
const inputFiles: Harness.Compiler.TestFile[] = testCaseContent.testUnitData.map(unit => {
const unitName = Test262BaselineRunner.getTestFilePath(unit.name);
return { unitName, content: unit.content };
});
// Emit the results
@ -49,13 +49,16 @@ class Test262BaselineRunner extends RunnerBase {
filename: testFilename,
inputFiles: inputFiles,
compilerResult: undefined,
program: undefined,
};
Harness.Compiler.getCompiler().compileFiles([Test262BaselineRunner.helperFile].concat(inputFiles), /*otherFiles*/ [], (compilerResult, program) => {
testState.compilerResult = compilerResult;
testState.program = program;
}, /*settingsCallback*/ undefined, Test262BaselineRunner.options);
const output = Harness.Compiler.compileFiles(
[Test262BaselineRunner.helperFile].concat(inputFiles),
/*otherFiles*/ [],
/* harnessOptions */ undefined,
Test262BaselineRunner.options,
/* currentDirectory */ undefined
);
testState.compilerResult = output.result;
});
after(() => {
@ -80,14 +83,14 @@ class Test262BaselineRunner extends RunnerBase {
}, false, Test262BaselineRunner.baselineOptions);
});
it("satisfies inletiants", () => {
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
it("satisfies invariants", () => {
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
});
it("has the expected AST", () => {
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
return Utils.sourceFileToJSON(sourceFile);
}, false, Test262BaselineRunner.baselineOptions);
});

View File

@ -388,7 +388,7 @@ namespace ts.server {
}
openReferencedFile(filename: string) {
return this.projectService.openFile(filename, false);
return this.projectService.openFile(filename, /*openedByClient*/ false);
}
getRootFiles() {
@ -1068,7 +1068,7 @@ namespace ts.server {
*/
openClientFile(fileName: string, fileContent?: string) {
this.openOrUpdateConfiguredProjectForFile(fileName);
const info = this.openFile(fileName, true, fileContent);
const info = this.openFile(fileName, /*openedByClient*/ true, fileContent);
this.addOpenFile(info);
this.printProjects();
return info;
@ -1277,7 +1277,7 @@ namespace ts.server {
for (const fileName of fileNamesToAdd) {
let info = this.getScriptInfo(fileName);
if (!info) {
info = this.openFile(fileName, false);
info = this.openFile(fileName, /*openedByClient*/ false);
}
else {
// if the root file was opened by client, it would belong to either

View File

@ -901,7 +901,7 @@ namespace ts.server {
}
getDiagnosticsForProject(delay: number, fileName: string) {
const { configFileName, fileNames } = this.getProjectInfo(fileName, true);
const { configFileName, fileNames } = this.getProjectInfo(fileName, /*needFileNameList*/ true);
// No need to analyze lib.d.ts
let fileNamesInProject = fileNames.filter((value, index, array) => value.indexOf("lib.d.ts") < 0);

View File

@ -132,43 +132,43 @@ namespace ts {
let scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
let emptyArray: any[] = [];
const jsDocTagNames = [
"augments",
"author",
"argument",
"borrows",
"class",
"constant",
"constructor",
"constructs",
"default",
"deprecated",
"description",
"event",
"example",
"extends",
"field",
"fileOverview",
"function",
"ignore",
"inner",
"lends",
"link",
"memberOf",
"name",
"namespace",
"param",
"private",
"property",
"public",
"requires",
"returns",
"see",
"since",
"static",
"throws",
"type",
"augments",
"author",
"argument",
"borrows",
"class",
"constant",
"constructor",
"constructs",
"default",
"deprecated",
"description",
"event",
"example",
"extends",
"field",
"fileOverview",
"function",
"ignore",
"inner",
"lends",
"link",
"memberOf",
"name",
"namespace",
"param",
"private",
"property",
"public",
"requires",
"returns",
"see",
"since",
"static",
"throws",
"type",
"version"
];
let jsDocCompletionEntries: CompletionEntry[];
@ -817,7 +817,7 @@ namespace ts {
constructor(kind: SyntaxKind, pos: number, end: number) {
super(kind, pos, end)
}
public update(newText: string, textChangeRange: TextChangeRange): SourceFile {
return updateSourceFile(this, newText, textChangeRange);
}
@ -1031,7 +1031,7 @@ namespace ts {
/*
* LS host can optionally implement this method if it wants to be completely in charge of module name resolution.
* if implementation is omitted then language service will use built-in module resolution logic and get answers to
* if implementation is omitted then language service will use built-in module resolution logic and get answers to
* host specific questions using 'getScriptSnapshot'.
*/
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
@ -1861,7 +1861,7 @@ namespace ts {
* - allowNonTsExtensions = true
* - noLib = true
* - noResolve = true
*/
*/
export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput {
let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions();
@ -2670,7 +2670,7 @@ namespace ts {
}
}
export function createLanguageService(host: LanguageServiceHost,
export function createLanguageService(host: LanguageServiceHost,
documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService {
let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host);
@ -2758,10 +2758,10 @@ namespace ts {
getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),
writeFile: (fileName, data, writeByteOrderMark) => { },
getCurrentDirectory: () => currentDirectory,
fileExists: (fileName): boolean => {
fileExists: (fileName): boolean => {
// stub missing host functionality
Debug.assert(!host.resolveModuleNames);
return hostCache.getOrCreateEntry(fileName) !== undefined;
return hostCache.getOrCreateEntry(fileName) !== undefined;
},
readFile: (fileName): string => {
// stub missing host functionality
@ -3167,7 +3167,7 @@ namespace ts {
log("getCompletionData: Is inside comment: " + (new Date().getTime() - start));
if (insideComment) {
// The current position is next to the '@' sign, when no tag name being provided yet.
// The current position is next to the '@' sign, when no tag name being provided yet.
// Provide a full list of tag names
if (hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
isJsDocTagName = true;
@ -3200,7 +3200,7 @@ namespace ts {
}
if (!insideJsDocTagExpression) {
// Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
// Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
// comment or the plain text part of a jsDoc comment, so no completion should be available
log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment.");
return undefined;
@ -3721,8 +3721,8 @@ namespace ts {
case SyntaxKind.CloseBraceToken:
if (parent &&
parent.kind === SyntaxKind.JsxExpression &&
parent.parent &&
parent.kind === SyntaxKind.JsxExpression &&
parent.parent &&
(parent.parent.kind === SyntaxKind.JsxAttribute)) {
return <JsxOpeningLikeElement>parent.parent.parent;
}
@ -3771,7 +3771,7 @@ namespace ts {
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A<T, |
containingNodeKind === SyntaxKind.ArrayBindingPattern || // var [x, y|
containingNodeKind === SyntaxKind.TypeAliasDeclaration; // type Map, K, |
case SyntaxKind.DotToken:
return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [.|
@ -5006,7 +5006,7 @@ namespace ts {
}
break;
default:
if (isModifier(node.kind) && node.parent &&
if (isModifierKind(node.kind) && node.parent &&
(isDeclaration(node.parent) || node.parent.kind === SyntaxKind.VariableStatement)) {
return getModifierOccurrences(node.kind, node.parent);
}

View File

@ -0,0 +1,13 @@
//// [tests/cases/compiler/commonSourceDir1.ts] ////
//// [bar.ts]
var x: number;
//// [baz.ts]
var y: number;
//// [bar.js]
var x;
//// [baz.js]
var y;

View File

@ -0,0 +1,8 @@
=== A:/foo/bar.ts ===
var x: number;
>x : Symbol(x, Decl(bar.ts, 0, 3))
=== A:/foo/baz.ts ===
var y: number;
>y : Symbol(y, Decl(baz.ts, 0, 3))

View File

@ -0,0 +1,8 @@
=== A:/foo/bar.ts ===
var x: number;
>x : number
=== A:/foo/baz.ts ===
var y: number;
>y : number

View File

@ -0,0 +1,9 @@
error TS5009: Cannot find the common subdirectory path for the input files.
!!! error TS5009: Cannot find the common subdirectory path for the input files.
==== A:/foo/bar.ts (0 errors) ====
var x: number;
==== B:/foo/baz.ts (0 errors) ====
var y: number;

View File

@ -0,0 +1,12 @@
//// [tests/cases/compiler/commonSourceDir2.ts] ////
//// [bar.ts]
var x: number;
//// [baz.ts]
var y: number;
//// [bar.js]
var x;
//// [baz.js]
var y;

View File

@ -0,0 +1,12 @@
//// [tests/cases/compiler/commonSourceDir3.ts] ////
//// [bar.ts]
var x: number;
//// [baz.ts]
var y: number;
//// [bar.js]
var x;
//// [baz.js]
var y;

View File

@ -0,0 +1,8 @@
=== A:/foo/bar.ts ===
var x: number;
>x : Symbol(x, Decl(bar.ts, 0, 3))
=== a:/foo/baz.ts ===
var y: number;
>y : Symbol(y, Decl(baz.ts, 0, 3))

View File

@ -0,0 +1,8 @@
=== A:/foo/bar.ts ===
var x: number;
>x : number
=== a:/foo/baz.ts ===
var y: number;
>y : number

View File

@ -0,0 +1,9 @@
error TS5009: Cannot find the common subdirectory path for the input files.
!!! error TS5009: Cannot find the common subdirectory path for the input files.
==== A:/foo/bar.ts (0 errors) ====
var x: number;
==== a:/foo/baz.ts (0 errors) ====
var y: number;

View File

@ -0,0 +1,12 @@
//// [tests/cases/compiler/commonSourceDir4.ts] ////
//// [bar.ts]
var x: number;
//// [baz.ts]
var y: number;
//// [bar.js]
var x;
//// [baz.js]
var y;

View File

@ -0,0 +1,10 @@
tests/cases/compiler/functionVariableInReturnTypeAnnotation.ts(1,24): error TS2304: Cannot find name 'b'.
==== tests/cases/compiler/functionVariableInReturnTypeAnnotation.ts (1 errors) ====
function bar(): typeof b {
~
!!! error TS2304: Cannot find name 'b'.
var b = 1;
return undefined;
}

View File

@ -0,0 +1,11 @@
//// [functionVariableInReturnTypeAnnotation.ts]
function bar(): typeof b {
var b = 1;
return undefined;
}
//// [functionVariableInReturnTypeAnnotation.js]
function bar() {
var b = 1;
return undefined;
}

View File

@ -0,0 +1,20 @@
tests/cases/compiler/nonMergedOverloads.ts(1,5): error TS2300: Duplicate identifier 'f'.
tests/cases/compiler/nonMergedOverloads.ts(3,17): error TS1148: Cannot compile modules unless the '--module' flag is provided.
tests/cases/compiler/nonMergedOverloads.ts(3,17): error TS2300: Duplicate identifier 'f'.
tests/cases/compiler/nonMergedOverloads.ts(4,17): error TS2300: Duplicate identifier 'f'.
==== tests/cases/compiler/nonMergedOverloads.ts (4 errors) ====
var f = 10;
~
!!! error TS2300: Duplicate identifier 'f'.
export function f();
~
!!! error TS1148: Cannot compile modules unless the '--module' flag is provided.
~
!!! error TS2300: Duplicate identifier 'f'.
export function f() {
~
!!! error TS2300: Duplicate identifier 'f'.
}

View File

@ -0,0 +1,12 @@
//// [nonMergedOverloads.ts]
var f = 10;
export function f();
export function f() {
}
//// [nonMergedOverloads.js]
var f = 10;
function f() {
}
exports.f = f;

View File

@ -0,0 +1,44 @@
tests/cases/compiler/parameterNamesInTypeParameterList.ts(1,30): error TS2304: Cannot find name 'a'.
tests/cases/compiler/parameterNamesInTypeParameterList.ts(5,30): error TS2304: Cannot find name 'a'.
tests/cases/compiler/parameterNamesInTypeParameterList.ts(9,30): error TS2304: Cannot find name 'a'.
tests/cases/compiler/parameterNamesInTypeParameterList.ts(14,22): error TS2304: Cannot find name 'a'.
tests/cases/compiler/parameterNamesInTypeParameterList.ts(17,22): error TS2304: Cannot find name 'a'.
tests/cases/compiler/parameterNamesInTypeParameterList.ts(20,22): error TS2304: Cannot find name 'a'.
==== tests/cases/compiler/parameterNamesInTypeParameterList.ts (6 errors) ====
function f0<T extends typeof a>(a: T) {
~
!!! error TS2304: Cannot find name 'a'.
a.b;
}
function f1<T extends typeof a>({a}: {a:T}) {
~
!!! error TS2304: Cannot find name 'a'.
a.b;
}
function f2<T extends typeof a>([a]: T[]) {
~
!!! error TS2304: Cannot find name 'a'.
a.b;
}
class A {
m0<T extends typeof a>(a: T) {
~
!!! error TS2304: Cannot find name 'a'.
a.b
}
m1<T extends typeof a>({a}: {a:T}) {
~
!!! error TS2304: Cannot find name 'a'.
a.b
}
m2<T extends typeof a>([a]: T[]) {
~
!!! error TS2304: Cannot find name 'a'.
a.b
}
}

View File

@ -0,0 +1,53 @@
//// [parameterNamesInTypeParameterList.ts]
function f0<T extends typeof a>(a: T) {
a.b;
}
function f1<T extends typeof a>({a}: {a:T}) {
a.b;
}
function f2<T extends typeof a>([a]: T[]) {
a.b;
}
class A {
m0<T extends typeof a>(a: T) {
a.b
}
m1<T extends typeof a>({a}: {a:T}) {
a.b
}
m2<T extends typeof a>([a]: T[]) {
a.b
}
}
//// [parameterNamesInTypeParameterList.js]
function f0(a) {
a.b;
}
function f1(_a) {
var a = _a.a;
a.b;
}
function f2(_a) {
var a = _a[0];
a.b;
}
var A = (function () {
function A() {
}
A.prototype.m0 = function (a) {
a.b;
};
A.prototype.m1 = function (_a) {
var a = _a.a;
a.b;
};
A.prototype.m2 = function (_a) {
var a = _a[0];
a.b;
};
return A;
})();

View File

@ -0,0 +1,17 @@
tests/cases/compiler/typeParametersAndParametersInComputedNames.ts(6,10): error TS2304: Cannot find name 'T'.
tests/cases/compiler/typeParametersAndParametersInComputedNames.ts(6,13): error TS2304: Cannot find name 'a'.
==== tests/cases/compiler/typeParametersAndParametersInComputedNames.ts (2 errors) ====
function foo<T>(a: T) : string {
return "";
}
class A {
[foo<T>(a)]<T>(a: T) {
~
!!! error TS2304: Cannot find name 'T'.
~
!!! error TS2304: Cannot find name 'a'.
}
}

View File

@ -0,0 +1,21 @@
//// [typeParametersAndParametersInComputedNames.ts]
function foo<T>(a: T) : string {
return "";
}
class A {
[foo<T>(a)]<T>(a: T) {
}
}
//// [typeParametersAndParametersInComputedNames.js]
function foo(a) {
return "";
}
var A = (function () {
function A() {
}
A.prototype[foo(a)] = function (a) {
};
return A;
})();

View File

@ -0,0 +1,6 @@
// @outDir: A:/
// @Filename: A:/foo/bar.ts
var x: number;
// @Filename: A:/foo/baz.ts
var y: number;

View File

@ -0,0 +1,6 @@
// @outDir: A:/
// @Filename: A:/foo/bar.ts
var x: number;
// @Filename: B:/foo/baz.ts
var y: number;

View File

@ -0,0 +1,7 @@
// @useCaseSensitiveFileNames: false
// @outDir: A:/
// @Filename: A:/foo/bar.ts
var x: number;
// @Filename: a:/foo/baz.ts
var y: number;

View File

@ -0,0 +1,7 @@
// @useCaseSensitiveFileNames: true
// @outDir: A:/
// @Filename: A:/foo/bar.ts
var x: number;
// @Filename: a:/foo/baz.ts
var y: number;

View File

@ -0,0 +1,4 @@
function bar(): typeof b {
var b = 1;
return undefined;
}

View File

@ -0,0 +1,5 @@
var f = 10;
export function f();
export function f() {
}

View File

@ -0,0 +1,23 @@
function f0<T extends typeof a>(a: T) {
a.b;
}
function f1<T extends typeof a>({a}: {a:T}) {
a.b;
}
function f2<T extends typeof a>([a]: T[]) {
a.b;
}
class A {
m0<T extends typeof a>(a: T) {
a.b
}
m1<T extends typeof a>({a}: {a:T}) {
a.b
}
m2<T extends typeof a>([a]: T[]) {
a.b
}
}

View File

@ -0,0 +1,8 @@
function foo<T>(a: T) : string {
return "";
}
class A {
[foo<T>(a)]<T>(a: T) {
}
}

View File

@ -3,16 +3,16 @@
//// var f4 = <T>(x: T/**/ ) => {
//// }
fs.goTo.marker();
goTo.marker();
// Replace the "T" type with the non-existent type 'V'.
fs.edit.backspace(1);
fs.edit.insert("A");
edit.backspace(1);
edit.insert("A");
// Bring up completion to force a pull resolve. This will end up resolving several symbols and
// producing unreported diagnostics (i.e. that 'V' wasn't found).
fs.verify.completionListContains("T");
fs.verify.completionEntryDetailIs("T", "(type parameter) T in <T>(x: any): void");
verify.completionListContains("T");
verify.completionEntryDetailIs("T", "(type parameter) T in <T>(x: any): void");
// There should now be a single error.
fs.verify.numberOfErrorsInCurrentFile(1);
verify.numberOfErrorsInCurrentFile(1);

View File

@ -24,10 +24,7 @@
// @Module: Node
// @Target: ES5
// In the imperative section, you can write any valid TypeScript code. If
// you need help finding a something in Intellisense, you can
// type 'fs.' as an alternate way of accessing the top-level objects
// (e.g. 'fs.goTo.eof();')
// In the imperative section, you can write any valid TypeScript code.
//---------------------------------------
// For API editors:
@ -45,52 +42,32 @@
//
// TODO: figure out a better solution to the API exposure problem.
// /// <reference path="../../../built/local/typescriptServices.d.ts"/>
// /// <reference path="../../../src/harness/fourslash.ts"/>
declare var FourSlash;
module ts {
export interface SymbolDisplayPart {
declare module ts {
interface SymbolDisplayPart {
text: string;
kind: string;
}
enum IndentStyle {
None = 0,
Block = 1,
Smart = 2,
}
}
//---------------------------------------------
// Return code used by getEmitOutput function to indicate status of the function
// It is a duplicate of the one in types.ts to expose it to testcases in fourslash
enum EmitReturnStatus {
Succeeded = 0, // All outputs generated if requested (.js, .map, .d.ts), no errors reported
AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated
JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors
DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors
EmitErrorsEncountered = 4 // Emitter errors occurred during emitting process
}
// This is a duplicate of the indentstyle in services.ts to expose it to testcases in fourslash
enum IndentStyle {
None,
Block,
Smart,
}
module FourSlashInterface {
export interface Marker {
declare namespace FourSlashInterface {
interface Marker {
fileName: string;
position: number;
data?: any;
}
export interface EditorOptions {
interface EditorOptions {
IndentSize: number;
TabSize: number;
NewLineCharacter: string;
ConvertTabsToSpaces: boolean;
}
export interface FormatCodeOptions extends EditorOptions {
interface FormatCodeOptions extends EditorOptions {
InsertSpaceAfterCommaDelimiter: boolean;
InsertSpaceAfterSemicolonInForStatements: boolean;
InsertSpaceBeforeAndAfterBinaryOperators: boolean;
@ -100,646 +77,266 @@ module FourSlashInterface {
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
PlaceOpenBraceOnNewLineForFunctions: boolean;
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
[s: string]: boolean | number| string;
[s: string]: boolean | number | string;
}
export interface Range {
interface Range {
fileName: string;
start: number;
end: number;
marker?: Marker;
}
export interface TextSpan {
interface TextSpan {
start: number;
end: number;
}
export class test_ {
public markers(): Marker[] {
return FourSlash.currentTestState.getMarkers();
}
public marker(name?: string): Marker {
return FourSlash.currentTestState.getMarkerByName(name);
}
public ranges(): Range[] {
return FourSlash.currentTestState.getRanges();
}
public markerByName(s: string): Marker {
return FourSlash.currentTestState.getMarkerByName(s);
}
class test_ {
markers(): Marker[];
marker(name?: string): Marker;
ranges(): Range[];
markerByName(s: string): Marker;
}
export class goTo {
// Moves the caret to the specified marker,
// or the anonymous marker ('/**/') if no name
// is given
public marker(name?: string) {
FourSlash.currentTestState.goToMarker(name);
}
public bof() {
FourSlash.currentTestState.goToBOF();
}
public eof() {
FourSlash.currentTestState.goToEOF();
}
public definition(definitionIndex: number = 0) {
FourSlash.currentTestState.goToDefinition(definitionIndex);
}
public type(definitionIndex: number = 0) {
FourSlash.currentTestState.goToTypeDefinition(definitionIndex);
}
public position(position: number, fileIndex?: number);
public position(position: number, fileName?: string);
public position(position: number, fileNameOrIndex?: any) {
if (fileNameOrIndex !== undefined) {
this.file(fileNameOrIndex);
}
FourSlash.currentTestState.goToPosition(position);
}
// Opens a file, given either its index as it
// appears in the test source, or its filename
// as specified in the test metadata
public file(index: number, content?: string);
public file(name: string, content?: string);
public file(indexOrName: any, content?: string) {
FourSlash.currentTestState.openFile(indexOrName, content);
}
class goTo {
marker(name?: string): void;
bof(): void;
eof(): void;
definition(definitionIndex?: number): void;
type(definitionIndex?: number): void;
position(position: number, fileIndex?: number): any;
position(position: number, fileName?: string): any;
file(index: number, content?: string): any;
file(name: string, content?: string): any;
}
export class verifyNegatable {
public not: verifyNegatable;
constructor(private negative = false) {
if (!negative) {
this.not = new verifyNegatable(true);
}
}
// Verifies the member list contains the specified symbol. The
// member list is brought up if necessary
public memberListContains(symbol: string, text?: string, documenation?: string, kind?: string) {
if (this.negative) {
FourSlash.currentTestState.verifyMemberListDoesNotContain(symbol);
} else {
FourSlash.currentTestState.verifyMemberListContains(symbol, text, documenation, kind);
}
}
public memberListCount(expectedCount: number) {
FourSlash.currentTestState.verifyMemberListCount(expectedCount, this.negative);
}
// Verifies the completion list contains the specified symbol. The
// completion list is brought up if necessary
public completionListContains(symbol: string, text?: string, documentation?: string, kind?: string) {
if (this.negative) {
FourSlash.currentTestState.verifyCompletionListDoesNotContain(symbol, text, documentation, kind);
} else {
FourSlash.currentTestState.verifyCompletionListContains(symbol, text, documentation, kind);
}
}
// Verifies the completion list items count to be greater than the specified amount. The
// completion list is brought up if necessary
public completionListItemsCountIsGreaterThan(count: number) {
FourSlash.currentTestState.verifyCompletionListItemsCountIsGreaterThan(count, this.negative);
}
public completionListIsEmpty() {
FourSlash.currentTestState.verifyCompletionListIsEmpty(this.negative);
}
public completionListAllowsNewIdentifier() {
FourSlash.currentTestState.verifyCompletionListAllowsNewIdentifier(this.negative);
}
public memberListIsEmpty() {
FourSlash.currentTestState.verifyMemberListIsEmpty(this.negative);
}
public referencesCountIs(count: number) {
FourSlash.currentTestState.verifyReferencesCountIs(count, /*localFilesOnly*/ false);
}
public referencesAtPositionContains(range: Range, isWriteAccess?: boolean) {
FourSlash.currentTestState.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess);
}
public signatureHelpPresent() {
FourSlash.currentTestState.verifySignatureHelpPresent(!this.negative);
}
public errorExistsBetweenMarkers(startMarker: string, endMarker: string) {
FourSlash.currentTestState.verifyErrorExistsBetweenMarkers(startMarker, endMarker, !this.negative);
}
public errorExistsAfterMarker(markerName = "") {
FourSlash.currentTestState.verifyErrorExistsAfterMarker(markerName, !this.negative, true);
}
public errorExistsBeforeMarker(markerName = "") {
FourSlash.currentTestState.verifyErrorExistsAfterMarker(markerName, !this.negative, false);
}
public quickInfoIs(expectedText?: string, expectedDocumentation?: string) {
FourSlash.currentTestState.verifyQuickInfoString(this.negative, expectedText, expectedDocumentation);
}
public quickInfoExists() {
FourSlash.currentTestState.verifyQuickInfoExists(this.negative);
}
public definitionCountIs(expectedCount: number) {
FourSlash.currentTestState.verifyDefinitionsCount(this.negative, expectedCount);
}
public typeDefinitionCountIs(expectedCount: number) {
FourSlash.currentTestState.verifyTypeDefinitionsCount(this.negative, expectedCount);
}
public definitionLocationExists() {
FourSlash.currentTestState.verifyDefinitionLocationExists(this.negative);
}
public verifyDefinitionsName(name: string, containerName: string) {
FourSlash.currentTestState.verifyDefinitionsName(this.negative, name, containerName);
}
class verifyNegatable {
private negative;
not: verifyNegatable;
constructor(negative?: boolean);
memberListContains(symbol: string, text?: string, documenation?: string, kind?: string): void;
memberListCount(expectedCount: number): void;
completionListContains(symbol: string, text?: string, documentation?: string, kind?: string): void;
completionListItemsCountIsGreaterThan(count: number): void;
completionListIsEmpty(): void;
completionListAllowsNewIdentifier(): void;
memberListIsEmpty(): void;
referencesCountIs(count: number): void;
referencesAtPositionContains(range: Range, isWriteAccess?: boolean): void;
signatureHelpPresent(): void;
errorExistsBetweenMarkers(startMarker: string, endMarker: string): void;
errorExistsAfterMarker(markerName?: string): void;
errorExistsBeforeMarker(markerName?: string): void;
quickInfoIs(expectedText?: string, expectedDocumentation?: string): void;
quickInfoExists(): void;
definitionCountIs(expectedCount: number): void;
typeDefinitionCountIs(expectedCount: number): void;
definitionLocationExists(): void;
verifyDefinitionsName(name: string, containerName: string): void;
}
export class verify extends verifyNegatable {
public caretAtMarker(markerName?: string) {
FourSlash.currentTestState.verifyCaretAtMarker(markerName);
}
public indentationIs(numberOfSpaces: number) {
FourSlash.currentTestState.verifyIndentationAtCurrentPosition(numberOfSpaces);
}
public indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle = IndentStyle.Smart) {
FourSlash.currentTestState.verifyIndentationAtPosition(fileName, position, numberOfSpaces, indentStyle);
}
public textAtCaretIs(text: string) {
FourSlash.currentTestState.verifyTextAtCaretIs(text);
}
class verify extends verifyNegatable {
caretAtMarker(markerName?: string): void;
indentationIs(numberOfSpaces: number): void;
indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle?: IndentStyle): void;
textAtCaretIs(text: string): void;
/**
* Compiles the current file and evaluates 'expr' in a context containing
* the emitted output, then compares (using ===) the result of that expression
* to 'value'. Do not use this function with external modules as it is not supported.
*/
public eval(expr: string, value: any) {
FourSlash.currentTestState.verifyEval(expr, value);
}
public currentLineContentIs(text: string) {
FourSlash.currentTestState.verifyCurrentLineContent(text);
}
public currentFileContentIs(text: string) {
FourSlash.currentTestState.verifyCurrentFileContent(text);
}
public verifyGetEmitOutputForCurrentFile(expected: string): void {
FourSlash.currentTestState.verifyGetEmitOutputForCurrentFile(expected);
}
public currentParameterHelpArgumentNameIs(name: string) {
FourSlash.currentTestState.verifyCurrentParameterHelpName(name);
}
public currentParameterSpanIs(parameter: string) {
FourSlash.currentTestState.verifyCurrentParameterSpanIs(parameter);
}
public currentParameterHelpArgumentDocCommentIs(docComment: string) {
FourSlash.currentTestState.verifyCurrentParameterHelpDocComment(docComment);
}
public currentSignatureHelpDocCommentIs(docComment: string) {
FourSlash.currentTestState.verifyCurrentSignatureHelpDocComment(docComment);
}
public signatureHelpCountIs(expected: number) {
FourSlash.currentTestState.verifySignatureHelpCount(expected);
}
public signatureHelpArgumentCountIs(expected: number) {
FourSlash.currentTestState.verifySignatureHelpArgumentCount(expected);
}
public currentSignatureParameterCountIs(expected: number) {
FourSlash.currentTestState.verifyCurrentSignatureHelpParameterCount(expected);
}
public currentSignatureTypeParameterCountIs(expected: number) {
FourSlash.currentTestState.verifyCurrentSignatureHelpTypeParameterCount(expected);
}
public currentSignatureHelpIs(expected: string) {
FourSlash.currentTestState.verifyCurrentSignatureHelpIs(expected);
}
public numberOfErrorsInCurrentFile(expected: number) {
FourSlash.currentTestState.verifyNumberOfErrorsInCurrentFile(expected);
}
public baselineCurrentFileBreakpointLocations() {
FourSlash.currentTestState.baselineCurrentFileBreakpointLocations();
}
public baselineCurrentFileNameOrDottedNameSpans() {
FourSlash.currentTestState.baselineCurrentFileNameOrDottedNameSpans();
}
public baselineGetEmitOutput() {
FourSlash.currentTestState.baselineGetEmitOutput();
}
public nameOrDottedNameSpanTextIs(text: string) {
FourSlash.currentTestState.verifyCurrentNameOrDottedNameSpanText(text);
}
public outliningSpansInCurrentFile(spans: TextSpan[]) {
FourSlash.currentTestState.verifyOutliningSpans(spans);
}
public todoCommentsInCurrentFile(descriptors: string[]) {
FourSlash.currentTestState.verifyTodoComments(descriptors, test.ranges());
}
public matchingBracePositionInCurrentFile(bracePosition: number, expectedMatchPosition: number) {
FourSlash.currentTestState.verifyMatchingBracePosition(bracePosition, expectedMatchPosition);
}
public noMatchingBracePositionInCurrentFile(bracePosition: number) {
FourSlash.currentTestState.verifyNoMatchingBracePosition(bracePosition);
}
public DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean) {
FourSlash.currentTestState.verifyDocCommentTemplate(empty ? undefined : { newText: expectedText, caretOffset: expectedOffset });
}
public noDocCommentTemplate() {
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, true);
}
public getScriptLexicalStructureListCount(count: number) {
FourSlash.currentTestState.verifyGetScriptLexicalStructureListCount(count);
}
// TODO: figure out what to do with the unused arguments.
public getScriptLexicalStructureListContains(
name: string,
kind: string,
fileName?: string,
parentName?: string,
isAdditionalSpan?: boolean,
markerPosition?: number) {
FourSlash.currentTestState.verifyGetScriptLexicalStructureListContains(name, kind);
}
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string) {
FourSlash.currentTestState.verifyNavigationItemsCount(count, searchValue, matchKind);
}
public navigationItemsListContains(
name: string,
kind: string,
searchValue: string,
matchKind: string,
fileName?: string,
parentName?: string) {
FourSlash.currentTestState.verifyNavigationItemsListContains(
name,
kind,
searchValue,
matchKind,
fileName,
parentName);
}
public occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean) {
FourSlash.currentTestState.verifyOccurrencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess);
}
public occurrencesAtPositionCount(expectedCount: number) {
FourSlash.currentTestState.verifyOccurrencesAtPositionListCount(expectedCount);
}
public documentHighlightsAtPositionContains(range: Range, fileNamesToSearch: string[], kind?: string) {
FourSlash.currentTestState.verifyDocumentHighlightsAtPositionListContains(range.fileName, range.start, range.end, fileNamesToSearch, kind);
}
public documentHighlightsAtPositionCount(expectedCount: number, fileNamesToSearch: string[]) {
FourSlash.currentTestState.verifyDocumentHighlightsAtPositionListCount(expectedCount, fileNamesToSearch);
}
public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string) {
FourSlash.currentTestState.verifyCompletionEntryDetails(entryName, text, documentation, kind);
}
eval(expr: string, value: any): void;
currentLineContentIs(text: string): void;
currentFileContentIs(text: string): void;
verifyGetEmitOutputForCurrentFile(expected: string): void;
currentParameterHelpArgumentNameIs(name: string): void;
currentParameterSpanIs(parameter: string): void;
currentParameterHelpArgumentDocCommentIs(docComment: string): void;
currentSignatureHelpDocCommentIs(docComment: string): void;
signatureHelpCountIs(expected: number): void;
signatureHelpArgumentCountIs(expected: number): void;
currentSignatureParameterCountIs(expected: number): void;
currentSignatureTypeParameterCountIs(expected: number): void;
currentSignatureHelpIs(expected: string): void;
numberOfErrorsInCurrentFile(expected: number): void;
baselineCurrentFileBreakpointLocations(): void;
baselineCurrentFileNameOrDottedNameSpans(): void;
baselineGetEmitOutput(): void;
nameOrDottedNameSpanTextIs(text: string): void;
outliningSpansInCurrentFile(spans: TextSpan[]): void;
todoCommentsInCurrentFile(descriptors: string[]): void;
matchingBracePositionInCurrentFile(bracePosition: number, expectedMatchPosition: number): void;
noMatchingBracePositionInCurrentFile(bracePosition: number): void;
DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void;
noDocCommentTemplate(): void;
getScriptLexicalStructureListCount(count: number): void;
getScriptLexicalStructureListContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number): void;
navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void;
navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void;
occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void;
occurrencesAtPositionCount(expectedCount: number): void;
documentHighlightsAtPositionContains(range: Range, fileNamesToSearch: string[], kind?: string): void;
documentHighlightsAtPositionCount(expectedCount: number, fileNamesToSearch: string[]): void;
completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string): void;
/**
* This method *requires* a contiguous, complete, and ordered stream of classifications for a file.
*/
public syntacticClassificationsAre(...classifications: { classificationType: string; text: string }[]) {
FourSlash.currentTestState.verifySyntacticClassifications(classifications);
}
syntacticClassificationsAre(...classifications: {
classificationType: string;
text: string;
}[]): void;
/**
* This method *requires* an ordered stream of classifications for a file, and spans are highly recommended.
*/
public semanticClassificationsAre(...classifications: { classificationType: string; text: string; textSpan?: TextSpan }[]) {
FourSlash.currentTestState.verifySemanticClassifications(classifications);
}
public renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) {
FourSlash.currentTestState.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers)
}
public renameInfoFailed(message?: string) {
FourSlash.currentTestState.verifyRenameInfoFailed(message)
}
public renameLocations(findInStrings: boolean, findInComments: boolean) {
FourSlash.currentTestState.verifyRenameLocations(findInStrings, findInComments);
}
public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; },
displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[]) {
FourSlash.currentTestState.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation);
}
public getSyntacticDiagnostics(expected: string) {
FourSlash.currentTestState.getSyntacticDiagnostics(expected);
}
public getSemanticDiagnostics(expected: string) {
FourSlash.currentTestState.getSemanticDiagnostics(expected);
}
public ProjectInfo(expected: string []) {
FourSlash.currentTestState.verifyProjectInfo(expected);
}
semanticClassificationsAre(...classifications: {
classificationType: string;
text: string;
textSpan?: TextSpan;
}[]): void;
renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string): void;
renameInfoFailed(message?: string): void;
renameLocations(findInStrings: boolean, findInComments: boolean): void;
verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: {
start: number;
length: number;
}, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[]): void;
getSyntacticDiagnostics(expected: string): void;
getSemanticDiagnostics(expected: string): void;
ProjectInfo(expected: string[]): void;
}
export class edit {
public backspace(count?: number) {
FourSlash.currentTestState.deleteCharBehindMarker(count);
}
public deleteAtCaret(times?: number) {
FourSlash.currentTestState.deleteChar(times);
}
public replace(start: number, length: number, text: string) {
FourSlash.currentTestState.replace(start, length, text);
}
public paste(text: string) {
FourSlash.currentTestState.paste(text);
}
public insert(text: string) {
this.insertLines(text);
}
public insertLine(text: string) {
this.insertLines(text + '\n');
}
public insertLines(...lines: string[]) {
FourSlash.currentTestState.type(lines.join('\n'));
}
public moveRight(count?: number) {
FourSlash.currentTestState.moveCaretRight(count);
}
public moveLeft(count?: number) {
if (typeof count === 'undefined') {
count = 1;
}
FourSlash.currentTestState.moveCaretRight(count * -1);
}
public enableFormatting() {
FourSlash.currentTestState.enableFormatting = true;
}
public disableFormatting() {
FourSlash.currentTestState.enableFormatting = false;
}
class edit {
backspace(count?: number): void;
deleteAtCaret(times?: number): void;
replace(start: number, length: number, text: string): void;
paste(text: string): void;
insert(text: string): void;
insertLine(text: string): void;
insertLines(...lines: string[]): void;
moveRight(count?: number): void;
moveLeft(count?: number): void;
enableFormatting(): void;
disableFormatting(): void;
}
export class debug {
public printCurrentParameterHelp() {
FourSlash.currentTestState.printCurrentParameterHelp();
}
public printCurrentFileState() {
FourSlash.currentTestState.printCurrentFileState();
}
public printCurrentFileStateWithWhitespace() {
FourSlash.currentTestState.printCurrentFileState(/*withWhiteSpace=*/true);
}
public printCurrentFileStateWithoutCaret() {
FourSlash.currentTestState.printCurrentFileState(/*withWhiteSpace=*/false, /*withCaret=*/false);
}
public printCurrentQuickInfo() {
FourSlash.currentTestState.printCurrentQuickInfo();
}
public printCurrentSignatureHelp() {
FourSlash.currentTestState.printCurrentSignatureHelp();
}
public printMemberListMembers() {
FourSlash.currentTestState.printMemberListMembers();
}
public printCompletionListMembers() {
FourSlash.currentTestState.printCompletionListMembers();
}
public printBreakpointLocation(pos: number) {
FourSlash.currentTestState.printBreakpointLocation(pos);
}
public printBreakpointAtCurrentLocation() {
FourSlash.currentTestState.printBreakpointAtCurrentLocation();
}
public printNameOrDottedNameSpans(pos: number) {
FourSlash.currentTestState.printNameOrDottedNameSpans(pos);
}
public printErrorList() {
FourSlash.currentTestState.printErrorList();
}
public printNavigationItems(searchValue: string = ".*") {
FourSlash.currentTestState.printNavigationItems(searchValue);
}
public printScriptLexicalStructureItems() {
FourSlash.currentTestState.printScriptLexicalStructureItems();
}
public printReferences() {
FourSlash.currentTestState.printReferences();
}
public printContext() {
FourSlash.currentTestState.printContext();
}
class debug {
printCurrentParameterHelp(): void;
printCurrentFileState(): void;
printCurrentFileStateWithWhitespace(): void;
printCurrentFileStateWithoutCaret(): void;
printCurrentQuickInfo(): void;
printCurrentSignatureHelp(): void;
printMemberListMembers(): void;
printCompletionListMembers(): void;
printBreakpointLocation(pos: number): void;
printBreakpointAtCurrentLocation(): void;
printNameOrDottedNameSpans(pos: number): void;
printErrorList(): void;
printNavigationItems(searchValue?: string): void;
printScriptLexicalStructureItems(): void;
printReferences(): void;
printContext(): void;
}
export class format {
public document() {
FourSlash.currentTestState.formatDocument();
}
public copyFormatOptions(): FormatCodeOptions {
return FourSlash.currentTestState.copyFormatOptions();
}
public setFormatOptions(options: FormatCodeOptions) {
return FourSlash.currentTestState.setFormatOptions(options);
}
public selection(startMarker: string, endMarker: string) {
FourSlash.currentTestState.formatSelection(FourSlash.currentTestState.getMarkerByName(startMarker).position, FourSlash.currentTestState.getMarkerByName(endMarker).position);
}
public setOption(name: string, value: number);
public setOption(name: string, value: string);
public setOption(name: string, value: boolean);
public setOption(name: string, value: any) {
FourSlash.currentTestState.formatCodeOptions[name] = value;
}
class format {
document(): void;
copyFormatOptions(): FormatCodeOptions;
setFormatOptions(options: FormatCodeOptions): any;
selection(startMarker: string, endMarker: string): void;
setOption(name: string, value: number): any;
setOption(name: string, value: string): any;
setOption(name: string, value: boolean): any;
}
export class cancellation {
public resetCancelled() {
FourSlash.currentTestState.resetCancelled();
}
public setCancelled(numberOfCalls: number = 0) {
FourSlash.currentTestState.setCancelled(numberOfCalls);
}
class cancellation {
resetCancelled(): void;
setCancelled(numberOfCalls?: number): void;
}
export module classification {
export function comment(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("comment", text, position);
}
export function identifier(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("identifier", text, position);
}
export function keyword(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("keyword", text, position);
}
export function numericLiteral(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("numericLiteral", text, position);
}
export function operator(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("operator", text, position);
}
export function stringLiteral(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("stringLiteral", text, position);
}
export function whiteSpace(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("whiteSpace", text, position);
}
export function text(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("text", text, position);
}
export function punctuation(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("punctuation", text, position);
}
export function docCommentTagName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("docCommentTagName", text, position);
}
export function className(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("className", text, position);
}
export function enumName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("enumName", text, position);
}
export function interfaceName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("interfaceName", text, position);
}
export function moduleName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("moduleName", text, position);
}
export function typeParameterName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("typeParameterName", text, position);
}
export function parameterName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("parameterName", text, position);
}
export function typeAliasName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } {
return getClassification("typeAliasName", text, position);
}
function getClassification(type: string, text: string, position?: number) {
return {
classificationType: type,
text: text,
textSpan: position === undefined ? undefined : { start: position, end: position + text.length }
};
}
module classification {
function comment(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function identifier(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function keyword(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function numericLiteral(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function operator(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function stringLiteral(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function whiteSpace(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function text(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function punctuation(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function docCommentTagName(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function className(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function enumName(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function interfaceName(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function moduleName(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function typeParameterName(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function parameterName(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
function typeAliasName(text: string, position?: number): {
classificationType: string;
text: string;
textSpan?: TextSpan;
};
}
}
module fs {
export var test = new FourSlashInterface.test_();
export var goTo = new FourSlashInterface.goTo();
export var verify = new FourSlashInterface.verify();
export var edit = new FourSlashInterface.edit();
export var debug = new FourSlashInterface.debug();
export var format = new FourSlashInterface.format();
export var cancellation = new FourSlashInterface.cancellation();
}
function verifyOperationIsCancelled(f) {
FourSlash.verifyOperationIsCancelled(f);
}
var test = new FourSlashInterface.test_();
var goTo = new FourSlashInterface.goTo();
var verify = new FourSlashInterface.verify();
var edit = new FourSlashInterface.edit();
var debug = new FourSlashInterface.debug();
var format = new FourSlashInterface.format();
var cancellation = new FourSlashInterface.cancellation();
var classification = FourSlashInterface.classification;
declare function verifyOperationIsCancelled(f: any): void;
declare var test: FourSlashInterface.test_;
declare var goTo: FourSlashInterface.goTo;
declare var verify: FourSlashInterface.verify;
declare var edit: FourSlashInterface.edit;
declare var debug: FourSlashInterface.debug;
declare var format: FourSlashInterface.format;
declare var cancellation: FourSlashInterface.cancellation;
declare var classification: typeof FourSlashInterface.classification;

View File

@ -179,5 +179,5 @@
////{| "indent": 0 |}
test.markers().forEach(marker => {
verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indent, IndentStyle.Block);
verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indent, ts.IndentStyle.Block);
});

View File

@ -179,5 +179,5 @@
////{| "indent": 0 |}
test.markers().forEach(marker => {
verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indent, IndentStyle.None);
verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indent, ts.IndentStyle.None);
});

View File

@ -11,4 +11,4 @@
//// }
goTo.marker();
fs.verify.quickInfoExists();
verify.quickInfoExists();

View File

@ -10,7 +10,7 @@
//// var z = y + 5;
////}
fs.goTo.marker();
fs.edit.backspace(6);
fs.edit.insert("var");
fs.verify.numberOfErrorsInCurrentFile(0);
goTo.marker();
edit.backspace(6);
edit.insert("var");
verify.numberOfErrorsInCurrentFile(0);

View File

@ -0,0 +1,18 @@
/// <reference path='fourslash.ts' />
////class Circle {
//// /**
//// * Initialize a circle.
//// * @param radius The radius of the circle.
//// */
//// constructor(private radius: number) {
//// }
////}
////var a = new Circle(/**/
goTo.marker('');
verify.signatureHelpCountIs(1);
verify.currentSignatureHelpIs("Circle(radius: number): Circle");
verify.currentParameterHelpArgumentNameIs("radius");
verify.currentParameterSpanIs("radius: number");
verify.currentParameterHelpArgumentDocCommentIs("The radius of the circle.");

View File

@ -354,6 +354,31 @@ export = C;
"moduleC.ts": "export var x"
};
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /* useCaseSensitiveFileNames */ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]);
});
it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => {
const files: Map<string> = {
"/a/B/c/moduleA.ts": `import a = require("./ModuleC")`,
"/a/B/c/moduleB.ts": `import a = require("./moduleC")`,
"/a/B/c/moduleC.ts": "export var x",
"/a/B/c/moduleD.ts": `
import a = require("./moduleA.ts");
import b = require("./moduleB.ts");
`
};
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /* useCaseSensitiveFileNames */ false, ["moduleD.ts"], [1149]);
});
it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => {
const files: Map<string> = {
"/a/B/c/moduleA.ts": `import a = require("./moduleC")`,
"/a/B/c/moduleB.ts": `import a = require("./moduleC")`,
"/a/B/c/moduleC.ts": "export var x",
"/a/B/c/moduleD.ts": `
import a = require("./moduleA.ts");
import b = require("./moduleB.ts");
`
};
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /* useCaseSensitiveFileNames */ false, ["moduleD.ts"], []);
})
});
}

View File

@ -20,7 +20,10 @@ module ts {
}
describe('VersionCache TS code', () => {
var testContent = `/// <reference path="z.ts" />
let validateEditAtLineCharIndex: (line: number, char: number, deleteLength: number, insertString: string) => void;
before(() => {
let testContent = `/// <reference path="z.ts" />
var x = 10;
var y = { zebra: 12, giraffe: "ell" };
z.a;
@ -31,16 +34,21 @@ k=y;
var p:Point=new Point();
var q:Point=<Point>p;`
let {lines, lineMap} = server.LineIndex.linesFromText(testContent);
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
let {lines, lineMap} = server.LineIndex.linesFromText(testContent);
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
let lineIndex = new server.LineIndex();
lineIndex.load(lines);
let lineIndex = new server.LineIndex();
lineIndex.load(lines);
function validateEditAtLineCharIndex(line: number, char: number, deleteLength: number, insertString: string): void {
let position = lineColToPosition(lineIndex, line, char);
validateEdit(lineIndex, testContent, position, deleteLength, insertString);
}
validateEditAtLineCharIndex = (line: number, char: number, deleteLength: number, insertString: string) => {
let position = lineColToPosition(lineIndex, line, char);
validateEdit(lineIndex, testContent, position, deleteLength, insertString);
};
});
after(() => {
validateEditAtLineCharIndex = undefined;
})
it('change 9 1 0 1 {"y"}', () => {
validateEditAtLineCharIndex(9, 1, 0, "y");
@ -68,22 +76,35 @@ var q:Point=<Point>p;`
});
describe('VersionCache simple text', () => {
let testContent = `in this story:
let validateEditAtPosition: (position: number, deleteLength: number, insertString: string) => void;
let testContent: string;
let lines: string[];
let lineMap: number[];
before(() => {
testContent = `in this story:
the lazy brown fox
jumped over the cow
that ate the grass
that was purple at the tips
and grew 1cm per day`;
let {lines, lineMap} = server.LineIndex.linesFromText(testContent);
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
({lines, lineMap} = server.LineIndex.linesFromText(testContent));
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
let lineIndex = new server.LineIndex();
lineIndex.load(lines);
let lineIndex = new server.LineIndex();
lineIndex.load(lines);
function validateEditAtPosition(position: number, deleteLength: number, insertString: string): void {
validateEdit(lineIndex, testContent, position, deleteLength, insertString);
}
validateEditAtPosition = (position: number, deleteLength: number, insertString: string) => {
validateEdit(lineIndex, testContent, position, deleteLength, insertString);
}
});
after(() => {
validateEditAtPosition = undefined;
testContent = undefined;
lines = undefined;
lineMap = undefined;
});
it('Insert at end of file', () => {
validateEditAtPosition(testContent.length, 0, "hmmmm...\r\n");
@ -159,50 +180,69 @@ and grew 1cm per day`;
});
describe('VersionCache stress test', () => {
const iterationCount = 20;
//const interationCount = 20000; // uncomment for testing
// Use scanner.ts, decent size, does not change frequentlly
let testFileName = "src/compiler/scanner.ts";
let testContent = Harness.IO.readFile(testFileName);
let totalChars = testContent.length;
assert.isTrue(totalChars > 0, "Failed to read test file.");
let {lines, lineMap} = server.LineIndex.linesFromText(testContent);
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
let lineIndex = new server.LineIndex();
lineIndex.load(lines);
let rsa: number[] = [];
let la: number[] = [];
let las: number[] = [];
let elas: number[] = [];
let ersa: number[] = [];
let ela: number[] = [];
let etotalChars = totalChars;
const iterationCount = 20;
//const iterationCount = 20000; // uncomment for testing
let lines: string[];
let lineMap: number[];
let lineIndex: server.LineIndex;
let testContent: string;
for (let j = 0; j < 100000; j++) {
rsa[j] = Math.floor(Math.random() * totalChars);
la[j] = Math.floor(Math.random() * (totalChars - rsa[j]));
if (la[j] > 4) {
las[j] = 4;
}
else {
las[j] = la[j];
}
if (j < 4000) {
ersa[j] = Math.floor(Math.random() * etotalChars);
ela[j] = Math.floor(Math.random() * (etotalChars - ersa[j]));
if (ela[j] > 4) {
elas[j] = 4;
before(() => {
// Use scanner.ts, decent size, does not change frequently
let testFileName = "src/compiler/scanner.ts";
testContent = Harness.IO.readFile(testFileName);
let totalChars = testContent.length;
assert.isTrue(totalChars > 0, "Failed to read test file.");
({lines, lineMap} = server.LineIndex.linesFromText(testContent));
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
lineIndex = new server.LineIndex();
lineIndex.load(lines);
let etotalChars = totalChars;
for (let j = 0; j < 100000; j++) {
rsa[j] = Math.floor(Math.random() * totalChars);
la[j] = Math.floor(Math.random() * (totalChars - rsa[j]));
if (la[j] > 4) {
las[j] = 4;
}
else {
elas[j] = ela[j];
las[j] = la[j];
}
if (j < 4000) {
ersa[j] = Math.floor(Math.random() * etotalChars);
ela[j] = Math.floor(Math.random() * (etotalChars - ersa[j]));
if (ela[j] > 4) {
elas[j] = 4;
}
else {
elas[j] = ela[j];
}
etotalChars += (las[j] - elas[j]);
}
etotalChars += (las[j] - elas[j]);
}
}
});
after(() => {
rsa = undefined;
la = undefined;
las = undefined;
elas = undefined;
ersa = undefined;
ela = undefined;
lines = undefined;
lineMap = undefined;
lineIndex = undefined;
testContent = undefined;
});
it("Range (average length 1/4 file size)", () => {
for (let i = 0; i < iterationCount; i++) {

View File

@ -269,6 +269,9 @@ if ((browser && browser === 'chrome')) {
case "win64":
defaultChromePath = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe";
break;
case "darwin":
defaultChromePath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
break;
case "linux":
defaultChromePath = "/opt/google/chrome/chrome"
break;