Merge remote-tracking branch 'refs/remotes/Microsoft/master' into tsconfigpath

This commit is contained in:
SaschaNaz
2015-11-19 01:56:55 +09:00
34 changed files with 879 additions and 238 deletions
+16 -11
View File
@@ -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;
}
@@ -106,18 +106,23 @@ class PreferConstWalker extends Lint.RuleWalker {
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 {
// Should we throw an exception?
}
}
}
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 +150,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 +216,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);
}
}
+2
View File
@@ -139,6 +139,8 @@ namespace ts {
file.classifiableNames = classifiableNames;
}
file = undefined;
options = undefined;
parent = undefined;
container = undefined;
blockScopeContainer = undefined;
+34 -8
View File
@@ -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) {
@@ -9879,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);
+29 -26
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 {
+26 -26
View File
@@ -1157,7 +1157,7 @@ namespace ts {
}
function parseAnyContextualModifier(): boolean {
return isModifier(token) && tryParse(nextTokenCanFollowModifier);
return isModifierKind(token) && tryParse(nextTokenCanFollowModifier);
}
function canFollowModifier(): boolean {
@@ -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 ?
@@ -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]
@@ -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;
+13 -4
View File
@@ -904,7 +904,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;
@@ -920,10 +920,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
@@ -938,6 +938,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;
}
@@ -1059,6 +1064,10 @@ namespace ts {
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) {
+291 -45
View File
@@ -348,7 +348,7 @@ namespace ts {
LastKeyword = OfKeyword,
FirstFutureReservedWord = ImplementsKeyword,
LastFutureReservedWord = YieldKeyword,
FirstTypeNode = TypeReference,
FirstTypeNode = TypePredicate,
LastTypeNode = ParenthesizedType,
FirstPunctuation = OpenBraceToken,
LastPunctuation = CaretEqualsToken,
@@ -474,15 +474,29 @@ namespace ts {
hasTrailingComma?: boolean;
}
export interface ModifiersArray extends NodeArray<Node> {
export interface ModifiersArray extends NodeArray<Modifier> {
flags: number;
}
// @kind(SyntaxKind.AbstractKeyword)
// @kind(SyntaxKind.AsyncKeyword)
// @kind(SyntaxKind.ConstKeyword)
// @kind(SyntaxKind.DeclareKeyword)
// @kind(SyntaxKind.DefaultKeyword)
// @kind(SyntaxKind.ExportKeyword)
// @kind(SyntaxKind.PublicKeyword)
// @kind(SyntaxKind.PrivateKeyword)
// @kind(SyntaxKind.ProtectedKeyword)
// @kind(SyntaxKind.StaticKeyword)
export interface Modifier extends Node { }
// @kind(SyntaxKind.Identifier)
export interface Identifier extends PrimaryExpression {
text: string; // Text of identifier (with escapes converted to characters)
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
}
// @kind(SyntaxKind.QualifiedName)
export interface QualifiedName extends Node {
// Must have same layout as PropertyAccess
left: EntityName;
@@ -492,6 +506,7 @@ namespace ts {
export type EntityName = Identifier | QualifiedName;
export type PropertyName = Identifier | LiteralExpression | ComputedPropertyName;
export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
export interface Declaration extends Node {
@@ -499,14 +514,21 @@ namespace ts {
name?: DeclarationName;
}
export interface DeclarationStatement extends Declaration, Statement {
name?: Identifier;
}
// @kind(SyntaxKind.ComputedPropertyName)
export interface ComputedPropertyName extends Node {
expression: Expression;
}
// @kind(SyntaxKind.Decorator)
export interface Decorator extends Node {
expression: LeftHandSideExpression;
}
// @kind(SyntaxKind.TypeParameter)
export interface TypeParameterDeclaration extends Declaration {
name: Identifier;
constraint?: TypeNode;
@@ -516,12 +538,19 @@ namespace ts {
}
export interface SignatureDeclaration extends Declaration {
name?: PropertyName;
typeParameters?: NodeArray<TypeParameterDeclaration>;
parameters: NodeArray<ParameterDeclaration>;
type?: TypeNode;
}
// SyntaxKind.VariableDeclaration
// @kind(SyntaxKind.CallSignature)
export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement { }
// @kind(SyntaxKind.ConstructSignature)
export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement { }
// @kind(SyntaxKind.VariableDeclaration)
export interface VariableDeclaration extends Declaration {
parent?: VariableDeclarationList;
name: Identifier | BindingPattern; // Declared variable name
@@ -529,11 +558,12 @@ namespace ts {
initializer?: Expression; // Optional initializer
}
// @kind(SyntaxKind.VariableDeclarationList)
export interface VariableDeclarationList extends Node {
declarations: NodeArray<VariableDeclaration>;
}
// SyntaxKind.Parameter
// @kind(SyntaxKind.Parameter)
export interface ParameterDeclaration extends Declaration {
dotDotDotToken?: Node; // Present on rest parameter
name: Identifier | BindingPattern; // Declared parameter name
@@ -542,7 +572,7 @@ namespace ts {
initializer?: Expression; // Optional initializer
}
// SyntaxKind.BindingElement
// @kind(SyntaxKind.BindingElement)
export interface BindingElement extends Declaration {
propertyName?: PropertyName; // Binding property name (in object binding pattern)
dotDotDotToken?: Node; // Present on rest binding element
@@ -550,27 +580,35 @@ namespace ts {
initializer?: Expression; // Optional initializer
}
// SyntaxKind.Property
export interface PropertyDeclaration extends Declaration, ClassElement {
name: DeclarationName; // Declared property name
// @kind(SyntaxKind.PropertySignature)
export interface PropertySignature extends TypeElement {
name: PropertyName; // Declared property name
questionToken?: Node; // Present on optional property
type?: TypeNode; // Optional type annotation
}
// @kind(SyntaxKind.PropertyDeclaration)
export interface PropertyDeclaration extends ClassElement {
questionToken?: Node; // Present for use with reporting a grammar error
name: PropertyName;
type?: TypeNode;
initializer?: Expression; // Optional initializer
}
export interface ObjectLiteralElement extends Declaration {
_objectLiteralBrandBrand: any;
}
name?: PropertyName;
}
// SyntaxKind.PropertyAssignment
// @kind(SyntaxKind.PropertyAssignment)
export interface PropertyAssignment extends ObjectLiteralElement {
_propertyAssignmentBrand: any;
name: DeclarationName;
name: PropertyName;
questionToken?: Node;
initializer: Expression;
}
// SyntaxKind.ShorthandPropertyAssignment
// @kind(SyntaxKind.ShorthandPropertyAssignment)
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
name: Identifier;
questionToken?: Node;
@@ -596,10 +634,20 @@ namespace ts {
initializer?: Expression;
}
export interface PropertyLikeDeclaration extends Declaration {
name: PropertyName;
}
export interface BindingPattern extends Node {
elements: NodeArray<BindingElement>;
}
// @kind(SyntaxKind.ObjectBindingPattern)
export interface ObjectBindingPattern extends BindingPattern { }
// @kind(SyntaxKind.ArrayBindingPattern)
export interface ArrayBindingPattern extends BindingPattern { }
/**
* Several node kinds share function-like features such as a signature,
* a name, and a body. These nodes should extend FunctionLikeDeclaration.
@@ -616,9 +664,15 @@ namespace ts {
body?: Block | Expression;
}
export interface FunctionDeclaration extends FunctionLikeDeclaration, Statement {
// @kind(SyntaxKind.FunctionDeclaration)
export interface FunctionDeclaration extends FunctionLikeDeclaration, DeclarationStatement {
name?: Identifier;
body?: Block;
body?: FunctionBody;
}
// @kind(SyntaxKind.MethodSignature)
export interface MethodSignature extends SignatureDeclaration, TypeElement {
name: PropertyName;
}
// Note that a MethodDeclaration is considered both a ClassElement and an ObjectLiteralElement.
@@ -630,15 +684,19 @@ namespace ts {
// Because of this, it may be necessary to determine what sort of MethodDeclaration you have
// at later stages of the compiler pipeline. In that case, you can either check the parent kind
// of the method, or use helpers like isObjectLiteralMethodDeclaration
// @kind(SyntaxKind.MethodDeclaration)
export interface MethodDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
body?: Block;
name: PropertyName;
body?: FunctionBody;
}
// @kind(SyntaxKind.Constructor)
export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement {
body?: Block;
body?: FunctionBody;
}
// For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.
// @kind(SyntaxKind.SemicolonClassElement)
export interface SemicolonClassElement extends ClassElement {
_semicolonClassElementBrand: any;
}
@@ -647,13 +705,27 @@ namespace ts {
// ClassElement and an ObjectLiteralElement.
export interface AccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
_accessorDeclarationBrand: any;
body: Block;
name: PropertyName;
body: FunctionBody;
}
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement {
// @kind(SyntaxKind.GetAccessor)
export interface GetAccessorDeclaration extends AccessorDeclaration { }
// @kind(SyntaxKind.SetAccessor)
export interface SetAccessorDeclaration extends AccessorDeclaration { }
// @kind(SyntaxKind.IndexSignature)
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
_indexSignatureDeclarationBrand: any;
}
// @kind(SyntaxKind.AnyKeyword)
// @kind(SyntaxKind.NumberKeyword)
// @kind(SyntaxKind.BooleanKeyword)
// @kind(SyntaxKind.StringKeyword)
// @kind(SyntaxKind.SymbolKeyword)
// @kind(SyntaxKind.VoidKeyword)
export interface TypeNode extends Node {
_typeNodeBrand: any;
}
@@ -662,29 +734,41 @@ namespace ts {
_functionOrConstructorTypeNodeBrand: any;
}
// @kind(SyntaxKind.FunctionType)
export interface FunctionTypeNode extends FunctionOrConstructorTypeNode { }
// @kind(SyntaxKind.ConstructorType)
export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode { }
// @kind(SyntaxKind.TypeReference)
export interface TypeReferenceNode extends TypeNode {
typeName: EntityName;
typeArguments?: NodeArray<TypeNode>;
}
// @kind(SyntaxKind.TypePredicate)
export interface TypePredicateNode extends TypeNode {
parameterName: Identifier;
type: TypeNode;
}
// @kind(SyntaxKind.TypeQuery)
export interface TypeQueryNode extends TypeNode {
exprName: EntityName;
}
// A TypeLiteral is the declaration node for an anonymous symbol.
// @kind(SyntaxKind.TypeLiteral)
export interface TypeLiteralNode extends TypeNode, Declaration {
members: NodeArray<Node>;
members: NodeArray<TypeElement>;
}
// @kind(SyntaxKind.ArrayType)
export interface ArrayTypeNode extends TypeNode {
elementType: TypeNode;
}
// @kind(SyntaxKind.TupleType)
export interface TupleTypeNode extends TypeNode {
elementTypes: NodeArray<TypeNode>;
}
@@ -693,16 +777,20 @@ namespace ts {
types: NodeArray<TypeNode>;
}
// @kind(SyntaxKind.UnionType)
export interface UnionTypeNode extends UnionOrIntersectionTypeNode { }
// @kind(SyntaxKind.IntersectionType)
export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode { }
// @kind(SyntaxKind.ParenthesizedType)
export interface ParenthesizedTypeNode extends TypeNode {
type: TypeNode;
}
// Note that a StringLiteral AST node is both an Expression and a TypeNode. The latter is
// because string literals can appear in type annotations as well.
// @kind(SyntaxKind.StringLiteral)
export interface StringLiteral extends LiteralExpression, TypeNode {
_stringLiteralBrand: any;
}
@@ -719,6 +807,9 @@ namespace ts {
contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
}
// @kind(SyntaxKind.OmittedExpression)
export interface OmittedExpression extends Expression { }
export interface UnaryExpression extends Expression {
_unaryExpressionBrand: any;
}
@@ -727,11 +818,13 @@ namespace ts {
_incrementExpressionBrand: any;
}
// @kind(SyntaxKind.PrefixUnaryExpression)
export interface PrefixUnaryExpression extends IncrementExpression {
operator: SyntaxKind;
operand: UnaryExpression;
}
// @kind(SyntaxKind.PostfixUnaryExpression)
export interface PostfixUnaryExpression extends IncrementExpression {
operand: LeftHandSideExpression;
operator: SyntaxKind;
@@ -749,31 +842,42 @@ namespace ts {
_memberExpressionBrand: any;
}
// @kind(SyntaxKind.TrueKeyword)
// @kind(SyntaxKind.FalseKeyword)
// @kind(SyntaxKind.NullKeyword)
// @kind(SyntaxKind.ThisKeyword)
// @kind(SyntaxKind.SuperKeyword)
export interface PrimaryExpression extends MemberExpression {
_primaryExpressionBrand: any;
}
// @kind(SyntaxKind.DeleteExpression)
export interface DeleteExpression extends UnaryExpression {
expression: UnaryExpression;
}
// @kind(SyntaxKind.TypeOfExpression)
export interface TypeOfExpression extends UnaryExpression {
expression: UnaryExpression;
}
// @kind(SyntaxKind.VoidExpression)
export interface VoidExpression extends UnaryExpression {
expression: UnaryExpression;
}
// @kind(SyntaxKind.AwaitExpression)
export interface AwaitExpression extends UnaryExpression {
expression: UnaryExpression;
}
// @kind(SyntaxKind.YieldExpression)
export interface YieldExpression extends Expression {
asteriskToken?: Node;
expression?: Expression;
}
// @kind(SyntaxKind.BinaryExpression)
// Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files
export interface BinaryExpression extends Expression, Declaration {
left: Expression;
@@ -781,6 +885,7 @@ namespace ts {
right: Expression;
}
// @kind(SyntaxKind.ConditionalExpression)
export interface ConditionalExpression extends Expression {
condition: Expression;
questionToken: Node;
@@ -789,24 +894,37 @@ namespace ts {
whenFalse: Expression;
}
export type FunctionBody = Block;
export type ConciseBody = FunctionBody | Expression;
// @kind(SyntaxKind.FunctionExpression)
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration {
name?: Identifier;
body: Block | Expression; // Required, whereas the member inherited from FunctionDeclaration is optional
body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional
}
// @kind(SyntaxKind.ArrowFunction)
export interface ArrowFunction extends Expression, FunctionLikeDeclaration {
equalsGreaterThanToken: Node;
body: ConciseBody;
}
// The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral,
// or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters.
// For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1".
// @kind(SyntaxKind.NumericLiteral)
// @kind(SyntaxKind.RegularExpressionLiteral)
// @kind(SyntaxKind.NoSubstitutionTemplateLiteral)
// @kind(SyntaxKind.TemplateHead)
// @kind(SyntaxKind.TemplateMiddle)
// @kind(SyntaxKind.TemplateTail)
export interface LiteralExpression extends PrimaryExpression {
text: string;
isUnterminated?: boolean;
hasExtendedUnicodeEscape?: boolean;
}
// @kind(SyntaxKind.TemplateExpression)
export interface TemplateExpression extends PrimaryExpression {
head: LiteralExpression;
templateSpans: NodeArray<TemplateSpan>;
@@ -814,52 +932,63 @@ namespace ts {
// Each of these corresponds to a substitution expression and a template literal, in that order.
// The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral.
// @kind(SyntaxKind.TemplateSpan)
export interface TemplateSpan extends Node {
expression: Expression;
literal: LiteralExpression;
}
// @kind(SyntaxKind.ParenthesizedExpression)
export interface ParenthesizedExpression extends PrimaryExpression {
expression: Expression;
}
// @kind(SyntaxKind.ArrayLiteralExpression)
export interface ArrayLiteralExpression extends PrimaryExpression {
elements: NodeArray<Expression>;
}
// @kind(SyntaxKind.SpreadElementExpression)
export interface SpreadElementExpression extends Expression {
expression: Expression;
}
// An ObjectLiteralExpression is the declaration node for an anonymous symbol.
// @kind(SyntaxKind.ObjectLiteralExpression)
export interface ObjectLiteralExpression extends PrimaryExpression, Declaration {
properties: NodeArray<ObjectLiteralElement>;
}
// @kind(SyntaxKind.PropertyAccessExpression)
export interface PropertyAccessExpression extends MemberExpression, Declaration {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
}
// @kind(SyntaxKind.ElementAccessExpression)
export interface ElementAccessExpression extends MemberExpression {
expression: LeftHandSideExpression;
argumentExpression?: Expression;
}
// @kind(SyntaxKind.CallExpression)
export interface CallExpression extends LeftHandSideExpression {
expression: LeftHandSideExpression;
typeArguments?: NodeArray<TypeNode>;
arguments: NodeArray<Expression>;
}
// @kind(SyntaxKind.ExpressionWithTypeArguments)
export interface ExpressionWithTypeArguments extends TypeNode {
expression: LeftHandSideExpression;
typeArguments?: NodeArray<TypeNode>;
}
// @kind(SyntaxKind.NewExpression)
export interface NewExpression extends CallExpression, PrimaryExpression { }
// @kind(SyntaxKind.TaggedTemplateExpression)
export interface TaggedTemplateExpression extends MemberExpression {
tag: LeftHandSideExpression;
template: LiteralExpression | TemplateExpression;
@@ -867,11 +996,13 @@ namespace ts {
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator;
// @kind(SyntaxKind.AsExpression)
export interface AsExpression extends Expression {
expression: Expression;
type: TypeNode;
}
// @kind(SyntaxKind.TypeAssertionExpression)
export interface TypeAssertion extends UnaryExpression {
type: TypeNode;
expression: UnaryExpression;
@@ -880,6 +1011,7 @@ namespace ts {
export type AssertionExpression = TypeAssertion | AsExpression;
/// A JSX expression of the form <TagName attrs>...</TagName>
// @kind(SyntaxKind.JsxElement)
export interface JsxElement extends PrimaryExpression {
openingElement: JsxOpeningElement;
children: NodeArray<JsxChild>;
@@ -887,6 +1019,7 @@ namespace ts {
}
/// The opening element of a <Tag>...</Tag> JsxElement
// @kind(SyntaxKind.JsxOpeningElement)
export interface JsxOpeningElement extends Expression {
_openingElementBrand?: any;
tagName: EntityName;
@@ -894,6 +1027,7 @@ namespace ts {
}
/// A JSX expression of the form <TagName attrs />
// @kind(SyntaxKind.JsxSelfClosingElement)
export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement {
_selfClosingElementBrand?: any;
}
@@ -901,24 +1035,29 @@ namespace ts {
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
// @kind(SyntaxKind.JsxAttribute)
export interface JsxAttribute extends Node {
name: Identifier;
/// JSX attribute initializers are optional; <X y /> is sugar for <X y={true} />
initializer?: Expression;
}
// @kind(SyntaxKind.JsxSpreadAttribute)
export interface JsxSpreadAttribute extends Node {
expression: Expression;
}
// @kind(SyntaxKind.JsxClosingElement)
export interface JsxClosingElement extends Node {
tagName: EntityName;
}
// @kind(SyntaxKind.JsxExpression)
export interface JsxExpression extends Expression {
expression?: Expression;
}
// @kind(SyntaxKind.JsxText)
export interface JsxText extends Node {
_jsxTextExpressionBrand: any;
}
@@ -929,18 +1068,36 @@ namespace ts {
_statementBrand: any;
}
// @kind(SyntaxKind.EmptyStatement)
export interface EmptyStatement extends Statement { }
// @kind(SyntaxKind.DebuggerStatement)
export interface DebuggerStatement extends Statement { }
// @kind(SyntaxKind.MissingDeclaration)
// @factoryhidden("name", true)
export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
name?: Identifier;
}
export type BlockLike = SourceFile | Block | ModuleBlock | CaseClause;
// @kind(SyntaxKind.Block)
export interface Block extends Statement {
statements: NodeArray<Statement>;
}
// @kind(SyntaxKind.VariableStatement)
export interface VariableStatement extends Statement {
declarationList: VariableDeclarationList;
}
// @kind(SyntaxKind.ExpressionStatement)
export interface ExpressionStatement extends Statement {
expression: Expression;
}
// @kind(SyntaxKind.IfStatement)
export interface IfStatement extends Statement {
expression: Expression;
thenStatement: Statement;
@@ -951,78 +1108,101 @@ namespace ts {
statement: Statement;
}
// @kind(SyntaxKind.DoStatement)
export interface DoStatement extends IterationStatement {
expression: Expression;
}
// @kind(SyntaxKind.WhileStatement)
export interface WhileStatement extends IterationStatement {
expression: Expression;
}
// @kind(SyntaxKind.ForStatement)
export interface ForStatement extends IterationStatement {
initializer?: VariableDeclarationList | Expression;
condition?: Expression;
incrementor?: Expression;
}
// @kind(SyntaxKind.ForInStatement)
export interface ForInStatement extends IterationStatement {
initializer: VariableDeclarationList | Expression;
expression: Expression;
}
// @kind(SyntaxKind.ForOfStatement)
export interface ForOfStatement extends IterationStatement {
initializer: VariableDeclarationList | Expression;
expression: Expression;
}
export interface BreakOrContinueStatement extends Statement {
// @kind(SyntaxKind.BreakStatement)
export interface BreakStatement extends Statement {
label?: Identifier;
}
// @kind(SyntaxKind.ContinueStatement)
export interface ContinueStatement extends Statement {
label?: Identifier;
}
export type BreakOrContinueStatement = BreakStatement | ContinueStatement;
// @kind(SyntaxKind.ReturnStatement)
export interface ReturnStatement extends Statement {
expression?: Expression;
}
// @kind(SyntaxKind.WithStatement)
export interface WithStatement extends Statement {
expression: Expression;
statement: Statement;
}
// @kind(SyntaxKind.SwitchStatement)
export interface SwitchStatement extends Statement {
expression: Expression;
caseBlock: CaseBlock;
}
// @kind(SyntaxKind.CaseBlock)
export interface CaseBlock extends Node {
clauses: NodeArray<CaseOrDefaultClause>;
}
// @kind(SyntaxKind.CaseClause)
export interface CaseClause extends Node {
expression?: Expression;
statements: NodeArray<Statement>;
}
// @kind(SyntaxKind.DefaultClause)
export interface DefaultClause extends Node {
statements: NodeArray<Statement>;
}
export type CaseOrDefaultClause = CaseClause | DefaultClause;
// @kind(SyntaxKind.LabeledStatement)
export interface LabeledStatement extends Statement {
label: Identifier;
statement: Statement;
}
// @kind(SyntaxKind.ThrowStatement)
export interface ThrowStatement extends Statement {
expression: Expression;
}
// @kind(SyntaxKind.TryStatement)
export interface TryStatement extends Statement {
tryBlock: Block;
catchClause?: CatchClause;
finallyBlock?: Block;
}
// @kind(SyntaxKind.CatchClause)
export interface CatchClause extends Node {
variableDeclaration: VariableDeclaration;
block: Block;
@@ -1035,34 +1215,49 @@ namespace ts {
members: NodeArray<ClassElement>;
}
export interface ClassDeclaration extends ClassLikeDeclaration, Statement {
// @kind(SyntaxKind.ClassDeclaration)
export interface ClassDeclaration extends ClassLikeDeclaration, DeclarationStatement {
name?: Identifier;
}
// @kind(SyntaxKind.ClassExpression)
export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression {
}
export interface ClassElement extends Declaration {
_classElementBrand: any;
name?: PropertyName;
}
export interface InterfaceDeclaration extends Declaration, Statement {
export interface TypeElement extends Declaration {
_typeElementBrand: any;
name?: PropertyName;
// @factoryparam
questionToken?: Node;
}
// @kind(SyntaxKind.InterfaceDeclaration)
export interface InterfaceDeclaration extends DeclarationStatement {
name: Identifier;
typeParameters?: NodeArray<TypeParameterDeclaration>;
heritageClauses?: NodeArray<HeritageClause>;
members: NodeArray<Declaration>;
members: NodeArray<TypeElement>;
}
// @kind(SyntaxKind.HeritageClause)
export interface HeritageClause extends Node {
token: SyntaxKind;
types?: NodeArray<ExpressionWithTypeArguments>;
}
export interface TypeAliasDeclaration extends Declaration, Statement {
// @kind(SyntaxKind.TypeAliasDeclaration)
export interface TypeAliasDeclaration extends DeclarationStatement {
name: Identifier;
typeParameters?: NodeArray<TypeParameterDeclaration>;
type: TypeNode;
}
// @kind(SyntaxKind.EnumMember)
export interface EnumMember extends Declaration {
// This does include ComputedPropertyName, but the parser will give an error
// if it parses a ComputedPropertyName in an EnumMember
@@ -1070,21 +1265,27 @@ namespace ts {
initializer?: Expression;
}
export interface EnumDeclaration extends Declaration, Statement {
// @kind(SyntaxKind.EnumDeclaration)
export interface EnumDeclaration extends DeclarationStatement {
name: Identifier;
members: NodeArray<EnumMember>;
}
export interface ModuleDeclaration extends Declaration, Statement {
export type ModuleBody = ModuleBlock | ModuleDeclaration;
// @kind(SyntaxKind.ModuleDeclaration)
export interface ModuleDeclaration extends DeclarationStatement {
name: Identifier | LiteralExpression;
body: ModuleBlock | ModuleDeclaration;
}
// @kind(SyntaxKind.ModuleBlock)
export interface ModuleBlock extends Node, Statement {
statements: NodeArray<Statement>;
}
export interface ImportEqualsDeclaration extends Declaration, Statement {
// @kind(SyntaxKind.ImportEqualsDeclaration)
export interface ImportEqualsDeclaration extends DeclarationStatement {
name: Identifier;
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
@@ -1092,6 +1293,7 @@ namespace ts {
moduleReference: EntityName | ExternalModuleReference;
}
// @kind(SyntaxKind.ExternalModuleReference)
export interface ExternalModuleReference extends Node {
expression?: Expression;
}
@@ -1100,6 +1302,7 @@ namespace ts {
// import "mod" => importClause = undefined, moduleSpecifier = "mod"
// In rest of the cases, module specifier is string literal corresponding to module
// ImportClause information is shown at its declaration below.
// @kind(SyntaxKind.ImportDeclaration)
export interface ImportDeclaration extends Statement {
importClause?: ImportClause;
moduleSpecifier: Expression;
@@ -1111,36 +1314,51 @@ namespace ts {
// import d, * as ns from "mod" => name = d, namedBinding: NamespaceImport = { name: ns }
// import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
// import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
// @kind(SyntaxKind.ImportClause)
export interface ImportClause extends Declaration {
name?: Identifier; // Default binding
namedBindings?: NamespaceImport | NamedImports;
}
// @kind(SyntaxKind.NamespaceImport)
export interface NamespaceImport extends Declaration {
name: Identifier;
}
export interface ExportDeclaration extends Declaration, Statement {
// @kind(SyntaxKind.ExportDeclaration)
export interface ExportDeclaration extends DeclarationStatement {
exportClause?: NamedExports;
moduleSpecifier?: Expression;
}
export interface NamedImportsOrExports extends Node {
elements: NodeArray<ImportOrExportSpecifier>;
// @kind(SyntaxKind.NamedImports)
export interface NamedImports extends Node {
elements: NodeArray<ImportSpecifier>;
}
export type NamedImports = NamedImportsOrExports;
export type NamedExports = NamedImportsOrExports;
// @kind(SyntaxKind.NamedExports)
export interface NamedExports extends Node {
elements: NodeArray<ExportSpecifier>;
}
export interface ImportOrExportSpecifier extends Declaration {
export type NamedImportsOrExports = NamedImports | NamedExports;
// @kind(SyntaxKind.ImportSpecifier)
export interface ImportSpecifier extends Declaration {
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
name: Identifier; // Declared name
}
export type ImportSpecifier = ImportOrExportSpecifier;
export type ExportSpecifier = ImportOrExportSpecifier;
// @kind(SyntaxKind.ExportSpecifier)
export interface ExportSpecifier extends Declaration {
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
name: Identifier; // Declared name
}
export interface ExportAssignment extends Declaration, Statement {
export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier;
// @kind(SyntaxKind.ExportAssignment)
export interface ExportAssignment extends DeclarationStatement {
isExportEquals?: boolean;
expression: Expression;
}
@@ -1155,6 +1373,7 @@ namespace ts {
}
// represents a top level: { type } expression in a JSDoc comment.
// @kind(SyntaxKind.JSDocTypeExpression)
export interface JSDocTypeExpression extends Node {
type: JSDocType;
}
@@ -1163,90 +1382,111 @@ namespace ts {
_jsDocTypeBrand: any;
}
// @kind(SyntaxKind.JSDocAllType)
export interface JSDocAllType extends JSDocType {
_JSDocAllTypeBrand: any;
}
// @kind(SyntaxKind.JSDocUnknownType)
export interface JSDocUnknownType extends JSDocType {
_JSDocUnknownTypeBrand: any;
}
// @kind(SyntaxKind.JSDocArrayType)
export interface JSDocArrayType extends JSDocType {
elementType: JSDocType;
}
// @kind(SyntaxKind.JSDocUnionType)
export interface JSDocUnionType extends JSDocType {
types: NodeArray<JSDocType>;
}
// @kind(SyntaxKind.JSDocTupleType)
export interface JSDocTupleType extends JSDocType {
types: NodeArray<JSDocType>;
}
// @kind(SyntaxKind.JSDocNonNullableType)
export interface JSDocNonNullableType extends JSDocType {
type: JSDocType;
}
// @kind(SyntaxKind.JSDocNullableType)
export interface JSDocNullableType extends JSDocType {
type: JSDocType;
}
// @kind(SyntaxKind.JSDocRecordType)
export interface JSDocRecordType extends JSDocType, TypeLiteralNode {
members: NodeArray<JSDocRecordMember>;
}
// @kind(SyntaxKind.JSDocTypeReference)
export interface JSDocTypeReference extends JSDocType {
name: EntityName;
typeArguments: NodeArray<JSDocType>;
}
// @kind(SyntaxKind.JSDocOptionalType)
export interface JSDocOptionalType extends JSDocType {
type: JSDocType;
}
// @kind(SyntaxKind.JSDocFunctionType)
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
parameters: NodeArray<ParameterDeclaration>;
type: JSDocType;
}
// @kind(SyntaxKind.JSDocVariadicType)
export interface JSDocVariadicType extends JSDocType {
type: JSDocType;
}
// @kind(SyntaxKind.JSDocConstructorType)
export interface JSDocConstructorType extends JSDocType {
type: JSDocType;
}
// @kind(SyntaxKind.JSDocThisType)
export interface JSDocThisType extends JSDocType {
type: JSDocType;
}
export interface JSDocRecordMember extends PropertyDeclaration {
// @kind(SyntaxKind.JSDocRecordMember)
export interface JSDocRecordMember extends PropertySignature {
name: Identifier | LiteralExpression;
type?: JSDocType;
}
// @kind(SyntaxKind.JSDocComment)
export interface JSDocComment extends Node {
tags: NodeArray<JSDocTag>;
}
// @kind(SyntaxKind.JSDocTag)
export interface JSDocTag extends Node {
atToken: Node;
tagName: Identifier;
}
// @kind(SyntaxKind.JSDocTemplateTag)
export interface JSDocTemplateTag extends JSDocTag {
typeParameters: NodeArray<TypeParameterDeclaration>;
}
// @kind(SyntaxKind.JSDocReturnTag)
export interface JSDocReturnTag extends JSDocTag {
typeExpression: JSDocTypeExpression;
}
// @kind(SyntaxKind.JSDocTypeTag)
export interface JSDocTypeTag extends JSDocTag {
typeExpression: JSDocTypeExpression;
}
// @kind(SyntaxKind.JSDocParameterTag)
export interface JSDocParameterTag extends JSDocTag {
preParameterName?: Identifier;
typeExpression?: JSDocTypeExpression;
@@ -1254,7 +1494,13 @@ namespace ts {
isBracketed: boolean;
}
export interface AmdDependency {
path: string;
name: string;
}
// Source files are declarations when they are external modules.
// @kind(SyntaxKind.SourceFile)
export interface SourceFile extends Declaration {
statements: NodeArray<Statement>;
endOfFileToken: Node;
@@ -1263,7 +1509,7 @@ namespace ts {
/* internal */ path: Path;
text: string;
amdDependencies: {path: string; name: string}[];
amdDependencies: AmdDependency[];
moduleName: string;
referencedFiles: FileReference[];
languageVariant: LanguageVariant;
@@ -2341,7 +2587,7 @@ namespace ts {
export interface ModuleResolutionHost {
fileExists(fileName: string): boolean;
// readFile function is used to read arbitrary text files on disk, i.e. when resolution procedure needs the content of 'package.json'
// to determine location of bundled typings for node module
// to determine location of bundled typings for node module
readFile(fileName: string): string;
}
@@ -2349,7 +2595,7 @@ namespace ts {
resolvedFileName: string;
/*
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be proper external module:
* - be a .d.ts file
* - be a .d.ts file
* - use top level imports\exports
* - don't use tripleslash references
*/
@@ -2372,11 +2618,11 @@ namespace ts {
getNewLine(): string;
/*
* CompilerHost must either implement resolveModuleNames (in case if it wants to be completely in charge of
* module name resolution) or provide implementation for methods from ModuleResolutionHost (in this case compiler
* CompilerHost must either implement resolveModuleNames (in case if it wants to be completely in charge of
* module name resolution) or provide implementation for methods from ModuleResolutionHost (in this case compiler
* will appply built-in module resolution logic and use members of ModuleResolutionHost to ask host specific questions).
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
* 'throw new Error("NotImplemented")'
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
* 'throw new Error("NotImplemented")'
*/
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
}
+2 -2
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:
+12 -18
View File
@@ -40,19 +40,18 @@ 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 harnessSettings: Harness.TestCaseParser.CompilerSettings;
let lastUnit: Harness.TestCaseParser.TestUnitData;
let rootDir: string;
let harnessSettings: Harness.TestCaseParser.CompilerSettings;
let result: Harness.Compiler.CompilerResult;
let options: ts.CompilerOptions;
@@ -63,28 +62,28 @@ class CompilerBaselineRunner extends RunnerBase {
before(() => {
justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path.
content = Harness.IO.readFile(fileName);
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
units = testCaseContent.testUnitData;
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("/")) + "/";
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: ts.combinePaths(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: ts.combinePaths(rootDir, unit.name), content: unit.content });
otherFiles.push({ unitName: this.makeUnitName(unit.name, rootDir), content: unit.content });
}
});
}
else {
toBeCompiled = units.map(unit => {
return { unitName: ts.combinePaths(rootDir, unit.name), content: unit.content };
return { unitName: this.makeUnitName(unit.name, rootDir), content: unit.content };
});
}
@@ -99,12 +98,7 @@ class CompilerBaselineRunner extends RunnerBase {
// 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;
harnessSettings = undefined;
lastUnit = undefined;
rootDir = undefined;
result = undefined;
options = undefined;
toBeCompiled = undefined;
+48 -48
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);
}
@@ -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;
@@ -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))
@@ -0,0 +1,8 @@
=== A:/foo/bar.ts ===
var x: number;
>x : number
=== A:/foo/baz.ts ===
var y: number;
>y : number
@@ -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;
@@ -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;
@@ -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;
@@ -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))
@@ -0,0 +1,8 @@
=== A:/foo/bar.ts ===
var x: number;
>x : number
=== a:/foo/baz.ts ===
var y: number;
>y : number
@@ -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;
@@ -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;
@@ -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;
}
@@ -0,0 +1,11 @@
//// [functionVariableInReturnTypeAnnotation.ts]
function bar(): typeof b {
var b = 1;
return undefined;
}
//// [functionVariableInReturnTypeAnnotation.js]
function bar() {
var b = 1;
return undefined;
}
@@ -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
}
}
@@ -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;
})();
@@ -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'.
}
}
@@ -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;
})();
+6
View File
@@ -0,0 +1,6 @@
// @outDir: A:/
// @Filename: A:/foo/bar.ts
var x: number;
// @Filename: A:/foo/baz.ts
var y: number;
+6
View File
@@ -0,0 +1,6 @@
// @outDir: A:/
// @Filename: A:/foo/bar.ts
var x: number;
// @Filename: B:/foo/baz.ts
var y: number;
+7
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;
+7
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;
@@ -0,0 +1,4 @@
function bar(): typeof b {
var b = 1;
return undefined;
}
@@ -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
}
}
@@ -0,0 +1,8 @@
function foo<T>(a: T) : string {
return "";
}
class A {
[foo<T>(a)]<T>(a: T) {
}
}
+90 -50
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++) {