Merge branch 'master' into out-module-concat
This commit is contained in:
commit
cadf54334b
|
@ -1,5 +1,6 @@
|
||||||
built
|
built
|
||||||
doc
|
doc
|
||||||
|
lib/README.md
|
||||||
scripts
|
scripts
|
||||||
src
|
src
|
||||||
tests
|
tests
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
language: node_js
|
language: node_js
|
||||||
|
|
||||||
node_js:
|
node_js:
|
||||||
|
- 'stable'
|
||||||
- '4'
|
- '4'
|
||||||
- '0.10'
|
- '0.10'
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,19 @@ Your pull request should:
|
||||||
* Follow the code conventions descriped in [Coding guidelines](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines)
|
* Follow the code conventions descriped in [Coding guidelines](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines)
|
||||||
* To avoid line ending issues, set `autocrlf = input` and `whitespace = cr-at-eol` in your git configuration
|
* To avoid line ending issues, set `autocrlf = input` and `whitespace = cr-at-eol` in your git configuration
|
||||||
|
|
||||||
|
## Contributing `lib.d.ts` fixes
|
||||||
|
|
||||||
|
The library sources are in: [src/lib](https://github.com/Microsoft/TypeScript/tree/master/src/lib)
|
||||||
|
|
||||||
|
To build the library files, run
|
||||||
|
```Shell
|
||||||
|
jake lib
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `src/lib/dom.generated.d.ts` and `src/lib/webworker.generated.d.ts`
|
||||||
|
|
||||||
|
These two files represent the DOM typings and are auto-generated. To make any modifications to them, please submit a PR to https://github.com/Microsoft/TSJS-lib-generator
|
||||||
|
|
||||||
## Running the Tests
|
## Running the Tests
|
||||||
|
|
||||||
To run all tests, invoke the `runtests` target using jake:
|
To run all tests, invoke the `runtests` target using jake:
|
||||||
|
|
|
@ -862,6 +862,7 @@ var tslintRuleDir = "scripts/tslint";
|
||||||
var tslintRules = ([
|
var tslintRules = ([
|
||||||
"nextLineRule",
|
"nextLineRule",
|
||||||
"noNullRule",
|
"noNullRule",
|
||||||
|
"preferConstRule",
|
||||||
"booleanTriviaRule",
|
"booleanTriviaRule",
|
||||||
"typeOperatorSpacingRule"
|
"typeOperatorSpacingRule"
|
||||||
]);
|
]);
|
||||||
|
|
4
lib/README.md
Normal file
4
lib/README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Read this!
|
||||||
|
|
||||||
|
These files are not meant to be edited by hand.
|
||||||
|
If you need to make modifications, the respective files should be changed within the repository's top-level `src` directory.
|
228
scripts/tslint/preferConstRule.ts
Normal file
228
scripts/tslint/preferConstRule.ts
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
|
||||||
|
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||||
|
|
||||||
|
|
||||||
|
export class Rule extends Lint.Rules.AbstractRule {
|
||||||
|
public static FAILURE_STRING_FACTORY = (identifier: string) => `Identifier '${identifier}' never appears on the LHS of an assignment - use const instead of let for its declaration.`;
|
||||||
|
|
||||||
|
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||||
|
return this.applyWithWalker(new PreferConstWalker(sourceFile, this.getOptions()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isBindingPattern(node: ts.Node): node is ts.BindingPattern {
|
||||||
|
return !!node && (node.kind === ts.SyntaxKind.ArrayBindingPattern || node.kind === ts.SyntaxKind.ObjectBindingPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
function walkUpBindingElementsAndPatterns(node: ts.Node): ts.Node {
|
||||||
|
while (node && (node.kind === ts.SyntaxKind.BindingElement || isBindingPattern(node))) {
|
||||||
|
node = node.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCombinedNodeFlags(node: ts.Node): ts.NodeFlags {
|
||||||
|
node = walkUpBindingElementsAndPatterns(node);
|
||||||
|
|
||||||
|
let flags = node.flags;
|
||||||
|
if (node.kind === ts.SyntaxKind.VariableDeclaration) {
|
||||||
|
node = node.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node && node.kind === ts.SyntaxKind.VariableDeclarationList) {
|
||||||
|
flags |= node.flags;
|
||||||
|
node = node.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node && node.kind === ts.SyntaxKind.VariableStatement) {
|
||||||
|
flags |= node.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLet(node: ts.Node) {
|
||||||
|
return !!(getCombinedNodeFlags(node) & ts.NodeFlags.Let);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExported(node: ts.Node) {
|
||||||
|
return !!(getCombinedNodeFlags(node) & ts.NodeFlags.Export);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAssignmentOperator(token: ts.SyntaxKind): boolean {
|
||||||
|
return token >= ts.SyntaxKind.FirstAssignment && token <= ts.SyntaxKind.LastAssignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isBindingLiteralExpression(node: ts.Node): node is (ts.ArrayLiteralExpression | ts.ObjectLiteralExpression) {
|
||||||
|
return (!!node) && (node.kind === ts.SyntaxKind.ObjectLiteralExpression || node.kind === ts.SyntaxKind.ArrayLiteralExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DeclarationUsages {
|
||||||
|
declaration: ts.VariableDeclaration;
|
||||||
|
usages: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PreferConstWalker extends Lint.RuleWalker {
|
||||||
|
private inScopeLetDeclarations: ts.Map<DeclarationUsages>[] = [];
|
||||||
|
private errors: Lint.RuleFailure[] = [];
|
||||||
|
private markAssignment(identifier: ts.Identifier) {
|
||||||
|
const name = identifier.text;
|
||||||
|
for (let i = this.inScopeLetDeclarations.length - 1; i >= 0; i--) {
|
||||||
|
const declarations = this.inScopeLetDeclarations[i];
|
||||||
|
if (declarations[name]) {
|
||||||
|
declarations[name].usages++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitSourceFile(node: ts.SourceFile) {
|
||||||
|
super.visitSourceFile(node);
|
||||||
|
// Sort errors by position because tslint doesn't
|
||||||
|
this.errors.sort((a, b) => a.getStartPosition().getPosition() - b.getStartPosition().getPosition()).forEach(e => this.addFailure(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
visitBinaryExpression(node: ts.BinaryExpression) {
|
||||||
|
if (isAssignmentOperator(node.operatorToken.kind)) {
|
||||||
|
this.visitLHSExpressions(node.left);
|
||||||
|
}
|
||||||
|
super.visitBinaryExpression(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private visitLHSExpressions(node: ts.Expression) {
|
||||||
|
while (node.kind === ts.SyntaxKind.ParenthesizedExpression) {
|
||||||
|
node = (node as ts.ParenthesizedExpression).expression;
|
||||||
|
}
|
||||||
|
if (node.kind === ts.SyntaxKind.Identifier) {
|
||||||
|
this.markAssignment(node as ts.Identifier);
|
||||||
|
}
|
||||||
|
else if (isBindingLiteralExpression(node)) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
else if (isBindingPattern(element.name)) {
|
||||||
|
this.visitBindingPatternIdentifiers(element.name as ts.BindingPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
||||||
|
const pattern = node as ts.ArrayLiteralExpression;
|
||||||
|
for (const element of pattern.elements) {
|
||||||
|
this.visitLHSExpressions(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private visitBindingPatternIdentifiers(pattern: ts.BindingPattern) {
|
||||||
|
for (const element of pattern.elements) {
|
||||||
|
if (element.name.kind === ts.SyntaxKind.Identifier) {
|
||||||
|
this.markAssignment(element.name as ts.Identifier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.visitBindingPatternIdentifiers(element.name as ts.BindingPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression) {
|
||||||
|
this.visitAnyUnaryExpression(node);
|
||||||
|
super.visitPrefixUnaryExpression(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression) {
|
||||||
|
this.visitAnyUnaryExpression(node);
|
||||||
|
super.visitPostfixUnaryExpression(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private visitAnyUnaryExpression(node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression) {
|
||||||
|
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) {
|
||||||
|
this.visitLHSExpressions(node.operand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitModuleDeclaration(node: ts.ModuleDeclaration) {
|
||||||
|
if (node.body.kind === ts.SyntaxKind.ModuleBlock) {
|
||||||
|
// For some reason module blocks are left out of the visit block traversal
|
||||||
|
this.visitBlock(node.body as ts.ModuleBlock);
|
||||||
|
}
|
||||||
|
super.visitModuleDeclaration(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitForOfStatement(node: ts.ForOfStatement) {
|
||||||
|
this.visitAnyForStatement(node);
|
||||||
|
super.visitForOfStatement(node);
|
||||||
|
this.popDeclarations();
|
||||||
|
}
|
||||||
|
|
||||||
|
visitForInStatement(node: ts.ForInStatement) {
|
||||||
|
this.visitAnyForStatement(node);
|
||||||
|
super.visitForInStatement(node);
|
||||||
|
this.popDeclarations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private visitAnyForStatement(node: ts.ForOfStatement | ts.ForInStatement) {
|
||||||
|
const names: ts.Map<DeclarationUsages> = {};
|
||||||
|
if (isLet(node.initializer)) {
|
||||||
|
if (node.initializer.kind === ts.SyntaxKind.VariableDeclarationList) {
|
||||||
|
this.collectLetIdentifiers(node.initializer as ts.VariableDeclarationList, names);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.inScopeLetDeclarations.push(names);
|
||||||
|
}
|
||||||
|
|
||||||
|
private popDeclarations() {
|
||||||
|
const completed = this.inScopeLetDeclarations.pop();
|
||||||
|
for (const name in completed) {
|
||||||
|
if (Object.hasOwnProperty.call(completed, name)) {
|
||||||
|
const element = completed[name];
|
||||||
|
if (element.usages === 0) {
|
||||||
|
this.errors.push(this.createFailure(element.declaration.getStart(this.getSourceFile()), element.declaration.getWidth(this.getSourceFile()), Rule.FAILURE_STRING_FACTORY(name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitBlock(node: ts.Block) {
|
||||||
|
const names: ts.Map<DeclarationUsages> = {};
|
||||||
|
for (const statement of node.statements) {
|
||||||
|
if (statement.kind === ts.SyntaxKind.VariableStatement) {
|
||||||
|
this.collectLetIdentifiers((statement as ts.VariableStatement).declarationList, names);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.inScopeLetDeclarations.push(names);
|
||||||
|
super.visitBlock(node);
|
||||||
|
this.popDeclarations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private collectLetIdentifiers(list: ts.VariableDeclarationList, ret: ts.Map<DeclarationUsages>) {
|
||||||
|
for (const node of list.declarations) {
|
||||||
|
if (isLet(node) && !isExported(node)) {
|
||||||
|
this.collectNameIdentifiers(node, node.name, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private collectNameIdentifiers(value: 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};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.collectBindingPatternIdentifiers(value, node as ts.BindingPattern, table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private collectBindingPatternIdentifiers(value: ts.VariableDeclaration, pattern: ts.BindingPattern, table: ts.Map<DeclarationUsages>) {
|
||||||
|
for (const element of pattern.elements) {
|
||||||
|
this.collectNameIdentifiers(value, element.name, table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,7 +95,7 @@ namespace ts {
|
||||||
const binder = createBinder();
|
const binder = createBinder();
|
||||||
|
|
||||||
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
|
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
|
||||||
let start = new Date().getTime();
|
const start = new Date().getTime();
|
||||||
binder(file, options);
|
binder(file, options);
|
||||||
bindTime += new Date().getTime() - start;
|
bindTime += new Date().getTime() - start;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ namespace ts {
|
||||||
return `"${(<LiteralExpression>node.name).text}"`;
|
return `"${(<LiteralExpression>node.name).text}"`;
|
||||||
}
|
}
|
||||||
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||||
let nameExpression = (<ComputedPropertyName>node.name).expression;
|
const nameExpression = (<ComputedPropertyName>node.name).expression;
|
||||||
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
|
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
|
||||||
return getPropertyNameForKnownSymbolName((<PropertyAccessExpression>nameExpression).name.text);
|
return getPropertyNameForKnownSymbolName((<PropertyAccessExpression>nameExpression).name.text);
|
||||||
}
|
}
|
||||||
|
@ -229,9 +229,9 @@ namespace ts {
|
||||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
|
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
|
||||||
Debug.assert(!hasDynamicName(node));
|
Debug.assert(!hasDynamicName(node));
|
||||||
|
|
||||||
let isDefaultExport = node.flags & NodeFlags.Default;
|
const isDefaultExport = node.flags & NodeFlags.Default;
|
||||||
// The exported symbol for an export default function/class node is always named "default"
|
// The exported symbol for an export default function/class node is always named "default"
|
||||||
let name = isDefaultExport && parent ? "default" : getDeclarationName(node);
|
const name = isDefaultExport && parent ? "default" : getDeclarationName(node);
|
||||||
|
|
||||||
let symbol: Symbol;
|
let symbol: Symbol;
|
||||||
if (name !== undefined) {
|
if (name !== undefined) {
|
||||||
|
@ -298,7 +298,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
|
function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
|
||||||
let hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export;
|
const hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export;
|
||||||
if (symbolFlags & SymbolFlags.Alias) {
|
if (symbolFlags & SymbolFlags.Alias) {
|
||||||
if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) {
|
if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) {
|
||||||
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||||
|
@ -320,11 +320,11 @@ namespace ts {
|
||||||
// but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
|
// but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
|
||||||
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
|
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
|
||||||
if (hasExportModifier || container.flags & NodeFlags.ExportContext) {
|
if (hasExportModifier || container.flags & NodeFlags.ExportContext) {
|
||||||
let exportKind =
|
const exportKind =
|
||||||
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
|
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
|
||||||
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
|
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
|
||||||
(symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0);
|
(symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0);
|
||||||
let local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
|
const local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
|
||||||
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||||
node.localSymbol = local;
|
node.localSymbol = local;
|
||||||
return local;
|
return local;
|
||||||
|
@ -342,9 +342,9 @@ namespace ts {
|
||||||
// Before we recurse into a node's chilren, we first save the existing parent, container
|
// Before we recurse into a node's chilren, we first save the existing parent, container
|
||||||
// and block-container. Then after we pop out of processing the children, we restore
|
// and block-container. Then after we pop out of processing the children, we restore
|
||||||
// these saved values.
|
// these saved values.
|
||||||
let saveParent = parent;
|
const saveParent = parent;
|
||||||
let saveContainer = container;
|
const saveContainer = container;
|
||||||
let savedBlockScopeContainer = blockScopeContainer;
|
const savedBlockScopeContainer = blockScopeContainer;
|
||||||
|
|
||||||
// This node will now be set as the parent of all of its children as we recurse into them.
|
// This node will now be set as the parent of all of its children as we recurse into them.
|
||||||
parent = node;
|
parent = node;
|
||||||
|
@ -366,7 +366,7 @@ namespace ts {
|
||||||
// reusing a node from a previous compilation, that node may have had 'locals' created
|
// reusing a node from a previous compilation, that node may have had 'locals' created
|
||||||
// for it. We must clear this so we don't accidently move any stale data forward from
|
// for it. We must clear this so we don't accidently move any stale data forward from
|
||||||
// a previous compilation.
|
// a previous compilation.
|
||||||
let containerFlags = getContainerFlags(node);
|
const containerFlags = getContainerFlags(node);
|
||||||
if (containerFlags & ContainerFlags.IsContainer) {
|
if (containerFlags & ContainerFlags.IsContainer) {
|
||||||
container = blockScopeContainer = node;
|
container = blockScopeContainer = node;
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ namespace ts {
|
||||||
seenThisKeyword = false;
|
seenThisKeyword = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let saveState = kind === SyntaxKind.SourceFile || kind === SyntaxKind.ModuleBlock || isFunctionLikeKind(kind);
|
const saveState = kind === SyntaxKind.SourceFile || kind === SyntaxKind.ModuleBlock || isFunctionLikeKind(kind);
|
||||||
if (saveState) {
|
if (saveState) {
|
||||||
savedReachabilityState = currentReachabilityState;
|
savedReachabilityState = currentReachabilityState;
|
||||||
savedLabelStack = labelStack;
|
savedLabelStack = labelStack;
|
||||||
|
@ -633,7 +633,7 @@ namespace ts {
|
||||||
function bindCaseBlock(n: CaseBlock): void {
|
function bindCaseBlock(n: CaseBlock): void {
|
||||||
const startState = currentReachabilityState;
|
const startState = currentReachabilityState;
|
||||||
|
|
||||||
for (let clause of n.clauses) {
|
for (const clause of n.clauses) {
|
||||||
currentReachabilityState = startState;
|
currentReachabilityState = startState;
|
||||||
bind(clause);
|
bind(clause);
|
||||||
if (clause.statements.length && currentReachabilityState === Reachability.Reachable && options.noFallthroughCasesInSwitch) {
|
if (clause.statements.length && currentReachabilityState === Reachability.Reachable && options.noFallthroughCasesInSwitch) {
|
||||||
|
@ -790,9 +790,9 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
|
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
|
||||||
let body = node.kind === SyntaxKind.SourceFile ? node : (<ModuleDeclaration>node).body;
|
const body = node.kind === SyntaxKind.SourceFile ? node : (<ModuleDeclaration>node).body;
|
||||||
if (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock) {
|
if (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock) {
|
||||||
for (let stat of (<Block>body).statements) {
|
for (const stat of (<Block>body).statements) {
|
||||||
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
|
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -818,7 +818,7 @@ namespace ts {
|
||||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
|
declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let state = getModuleInstanceState(node);
|
const state = getModuleInstanceState(node);
|
||||||
if (state === ModuleInstanceState.NonInstantiated) {
|
if (state === ModuleInstanceState.NonInstantiated) {
|
||||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes);
|
declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes);
|
||||||
}
|
}
|
||||||
|
@ -830,7 +830,7 @@ namespace ts {
|
||||||
node.symbol.constEnumOnlyModule = false;
|
node.symbol.constEnumOnlyModule = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly;
|
const currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly;
|
||||||
if (node.symbol.constEnumOnlyModule === undefined) {
|
if (node.symbol.constEnumOnlyModule === undefined) {
|
||||||
// non-merged case - use the current state
|
// non-merged case - use the current state
|
||||||
node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
|
node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
|
||||||
|
@ -851,10 +851,10 @@ namespace ts {
|
||||||
// We do that by making an anonymous type literal symbol, and then setting the function
|
// We do that by making an anonymous type literal symbol, and then setting the function
|
||||||
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
|
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
|
||||||
// from an actual type literal symbol you would have gotten had you used the long form.
|
// from an actual type literal symbol you would have gotten had you used the long form.
|
||||||
let symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
|
const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
|
||||||
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
|
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
|
||||||
|
|
||||||
let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
|
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
|
||||||
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
|
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
|
||||||
typeLiteralSymbol.members = { [symbol.name]: symbol };
|
typeLiteralSymbol.members = { [symbol.name]: symbol };
|
||||||
}
|
}
|
||||||
|
@ -866,14 +866,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inStrictMode) {
|
if (inStrictMode) {
|
||||||
let seen: Map<ElementKind> = {};
|
const seen: Map<ElementKind> = {};
|
||||||
|
|
||||||
for (let prop of node.properties) {
|
for (const prop of node.properties) {
|
||||||
if (prop.name.kind !== SyntaxKind.Identifier) {
|
if (prop.name.kind !== SyntaxKind.Identifier) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let identifier = <Identifier>prop.name;
|
const identifier = <Identifier>prop.name;
|
||||||
|
|
||||||
// ECMA-262 11.1.5 Object Initialiser
|
// ECMA-262 11.1.5 Object Initialiser
|
||||||
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
|
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
|
||||||
|
@ -883,18 +883,18 @@ namespace ts {
|
||||||
// c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
|
// c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
|
||||||
// d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
|
// d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
|
||||||
// and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
|
// and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
|
||||||
let currentKind = prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment || prop.kind === SyntaxKind.MethodDeclaration
|
const currentKind = prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment || prop.kind === SyntaxKind.MethodDeclaration
|
||||||
? ElementKind.Property
|
? ElementKind.Property
|
||||||
: ElementKind.Accessor;
|
: ElementKind.Accessor;
|
||||||
|
|
||||||
let existingKind = seen[identifier.text];
|
const existingKind = seen[identifier.text];
|
||||||
if (!existingKind) {
|
if (!existingKind) {
|
||||||
seen[identifier.text] = currentKind;
|
seen[identifier.text] = currentKind;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentKind === ElementKind.Property && existingKind === ElementKind.Property) {
|
if (currentKind === ElementKind.Property && existingKind === ElementKind.Property) {
|
||||||
let span = getErrorSpanForNode(file, identifier);
|
const span = getErrorSpanForNode(file, identifier);
|
||||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
||||||
Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
|
Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
|
||||||
}
|
}
|
||||||
|
@ -905,7 +905,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
|
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
|
||||||
let symbol = createSymbol(symbolFlags, name);
|
const symbol = createSymbol(symbolFlags, name);
|
||||||
addDeclarationToSymbol(symbol, node, symbolFlags);
|
addDeclarationToSymbol(symbol, node, symbolFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,7 +984,7 @@ namespace ts {
|
||||||
if (inStrictMode && node.expression.kind === SyntaxKind.Identifier) {
|
if (inStrictMode && node.expression.kind === SyntaxKind.Identifier) {
|
||||||
// When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
|
// When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
|
||||||
// UnaryExpression is a direct reference to a variable, function argument, or function name
|
// UnaryExpression is a direct reference to a variable, function argument, or function name
|
||||||
let span = getErrorSpanForNode(file, node.expression);
|
const span = getErrorSpanForNode(file, node.expression);
|
||||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
|
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,11 +996,11 @@ namespace ts {
|
||||||
|
|
||||||
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
|
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
|
||||||
if (name && name.kind === SyntaxKind.Identifier) {
|
if (name && name.kind === SyntaxKind.Identifier) {
|
||||||
let identifier = <Identifier>name;
|
const identifier = <Identifier>name;
|
||||||
if (isEvalOrArgumentsIdentifier(identifier)) {
|
if (isEvalOrArgumentsIdentifier(identifier)) {
|
||||||
// We check first if the name is inside class declaration or class expression; if so give explicit message
|
// We check first if the name is inside class declaration or class expression; if so give explicit message
|
||||||
// otherwise report generic error message.
|
// otherwise report generic error message.
|
||||||
let span = getErrorSpanForNode(file, name);
|
const span = getErrorSpanForNode(file, name);
|
||||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
||||||
getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
|
getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
|
||||||
}
|
}
|
||||||
|
@ -1061,7 +1061,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function errorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) {
|
function errorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) {
|
||||||
let span = getSpanOfTokenAtPosition(file, node.pos);
|
const span = getSpanOfTokenAtPosition(file, node.pos);
|
||||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
|
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1076,7 +1076,7 @@ namespace ts {
|
||||||
|
|
||||||
node.parent = parent;
|
node.parent = parent;
|
||||||
|
|
||||||
let savedInStrictMode = inStrictMode;
|
const savedInStrictMode = inStrictMode;
|
||||||
if (!savedInStrictMode) {
|
if (!savedInStrictMode) {
|
||||||
updateStrictMode(node);
|
updateStrictMode(node);
|
||||||
}
|
}
|
||||||
|
@ -1122,7 +1122,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
|
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
|
||||||
for (let statement of statements) {
|
for (const statement of statements) {
|
||||||
if (!isPrologueDirective(statement)) {
|
if (!isPrologueDirective(statement)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1136,7 @@ namespace ts {
|
||||||
|
|
||||||
/// Should be called only on prologue directives (isPrologueDirective(node) should be true)
|
/// Should be called only on prologue directives (isPrologueDirective(node) should be true)
|
||||||
function isUseStrictPrologueDirective(node: ExpressionStatement): boolean {
|
function isUseStrictPrologueDirective(node: ExpressionStatement): boolean {
|
||||||
let nodeText = getTextOfNodeFromSourceText(file.text, node.expression);
|
const nodeText = getTextOfNodeFromSourceText(file.text, node.expression);
|
||||||
|
|
||||||
// Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
|
// Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
|
||||||
// string to contain unicode escapes (as per ES5).
|
// string to contain unicode escapes (as per ES5).
|
||||||
|
@ -1211,7 +1211,7 @@ namespace ts {
|
||||||
case SyntaxKind.FunctionExpression:
|
case SyntaxKind.FunctionExpression:
|
||||||
case SyntaxKind.ArrowFunction:
|
case SyntaxKind.ArrowFunction:
|
||||||
checkStrictModeFunctionName(<FunctionExpression>node);
|
checkStrictModeFunctionName(<FunctionExpression>node);
|
||||||
let bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
|
const bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
|
||||||
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
|
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
|
||||||
case SyntaxKind.ClassExpression:
|
case SyntaxKind.ClassExpression:
|
||||||
case SyntaxKind.ClassDeclaration:
|
case SyntaxKind.ClassDeclaration:
|
||||||
|
@ -1284,7 +1284,7 @@ namespace ts {
|
||||||
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let bindingName = node.name ? node.name.text : "__class";
|
const bindingName = node.name ? node.name.text : "__class";
|
||||||
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
|
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
|
||||||
// Add name of class expression into the map for semantic classifier
|
// Add name of class expression into the map for semantic classifier
|
||||||
if (node.name) {
|
if (node.name) {
|
||||||
|
@ -1292,7 +1292,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let symbol = node.symbol;
|
const symbol = node.symbol;
|
||||||
|
|
||||||
// TypeScript 1.0 spec (April 2014): 8.4
|
// TypeScript 1.0 spec (April 2014): 8.4
|
||||||
// Every class automatically contains a static property member named 'prototype', the
|
// Every class automatically contains a static property member named 'prototype', the
|
||||||
|
@ -1303,7 +1303,7 @@ namespace ts {
|
||||||
// Note: we check for this here because this class may be merging into a module. The
|
// Note: we check for this here because this class may be merging into a module. The
|
||||||
// module might have an exported variable called 'prototype'. We can't allow that as
|
// module might have an exported variable called 'prototype'. We can't allow that as
|
||||||
// that would clash with the built-in 'prototype' for the class.
|
// that would clash with the built-in 'prototype' for the class.
|
||||||
let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
|
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
|
||||||
if (hasProperty(symbol.exports, prototypeSymbol.name)) {
|
if (hasProperty(symbol.exports, prototypeSymbol.name)) {
|
||||||
if (node.name) {
|
if (node.name) {
|
||||||
node.name.parent = node;
|
node.name.parent = node;
|
||||||
|
@ -1368,7 +1368,7 @@ namespace ts {
|
||||||
node.parent.kind === SyntaxKind.Constructor &&
|
node.parent.kind === SyntaxKind.Constructor &&
|
||||||
isClassLike(node.parent.parent)) {
|
isClassLike(node.parent.parent)) {
|
||||||
|
|
||||||
let classDeclaration = <ClassLikeDeclaration>node.parent.parent;
|
const classDeclaration = <ClassLikeDeclaration>node.parent.parent;
|
||||||
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1394,13 +1394,13 @@ namespace ts {
|
||||||
function pushImplicitLabel(): number {
|
function pushImplicitLabel(): number {
|
||||||
initializeReachabilityStateIfNecessary();
|
initializeReachabilityStateIfNecessary();
|
||||||
|
|
||||||
let index = labelStack.push(Reachability.Unintialized) - 1;
|
const index = labelStack.push(Reachability.Unintialized) - 1;
|
||||||
implicitLabels.push(index);
|
implicitLabels.push(index);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
function popNamedLabel(label: Identifier, outerState: Reachability): void {
|
function popNamedLabel(label: Identifier, outerState: Reachability): void {
|
||||||
let index = labelIndexMap[label.text];
|
const index = labelIndexMap[label.text];
|
||||||
Debug.assert(index !== undefined);
|
Debug.assert(index !== undefined);
|
||||||
Debug.assert(labelStack.length == index + 1);
|
Debug.assert(labelStack.length == index + 1);
|
||||||
|
|
||||||
|
@ -1414,7 +1414,7 @@ namespace ts {
|
||||||
Debug.assert(false, `Label stack: ${labelStack.length}, index:${implicitLabelIndex}`);
|
Debug.assert(false, `Label stack: ${labelStack.length}, index:${implicitLabelIndex}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = implicitLabels.pop();
|
const i = implicitLabels.pop();
|
||||||
|
|
||||||
if (implicitLabelIndex !== i) {
|
if (implicitLabelIndex !== i) {
|
||||||
Debug.assert(false, `i: ${i}, index: ${implicitLabelIndex}`);
|
Debug.assert(false, `i: ${i}, index: ${implicitLabelIndex}`);
|
||||||
|
@ -1453,8 +1453,8 @@ namespace ts {
|
||||||
switch (currentReachabilityState) {
|
switch (currentReachabilityState) {
|
||||||
case Reachability.Unreachable:
|
case Reachability.Unreachable:
|
||||||
const reportError =
|
const reportError =
|
||||||
// report error on all statements
|
// report error on all statements except empty ones
|
||||||
isStatement(node) ||
|
(isStatement(node) && node.kind !== SyntaxKind.EmptyStatement) ||
|
||||||
// report error on class declarations
|
// report error on class declarations
|
||||||
node.kind === SyntaxKind.ClassDeclaration ||
|
node.kind === SyntaxKind.ClassDeclaration ||
|
||||||
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
|
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -295,8 +295,8 @@ namespace ts {
|
||||||
return optionNameMapCache;
|
return optionNameMapCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
let optionNameMap: Map<CommandLineOption> = {};
|
const optionNameMap: Map<CommandLineOption> = {};
|
||||||
let shortOptionNames: Map<string> = {};
|
const shortOptionNames: Map<string> = {};
|
||||||
forEach(optionDeclarations, option => {
|
forEach(optionDeclarations, option => {
|
||||||
optionNameMap[option.name.toLowerCase()] = option;
|
optionNameMap[option.name.toLowerCase()] = option;
|
||||||
if (option.shortName) {
|
if (option.shortName) {
|
||||||
|
@ -309,10 +309,10 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine {
|
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine {
|
||||||
let options: CompilerOptions = {};
|
const options: CompilerOptions = {};
|
||||||
let fileNames: string[] = [];
|
const fileNames: string[] = [];
|
||||||
let errors: Diagnostic[] = [];
|
const errors: Diagnostic[] = [];
|
||||||
let { optionNameMap, shortOptionNames } = getOptionNameMap();
|
const { optionNameMap, shortOptionNames } = getOptionNameMap();
|
||||||
|
|
||||||
parseStrings(commandLine);
|
parseStrings(commandLine);
|
||||||
return {
|
return {
|
||||||
|
@ -337,7 +337,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasProperty(optionNameMap, s)) {
|
if (hasProperty(optionNameMap, s)) {
|
||||||
let opt = optionNameMap[s];
|
const opt = optionNameMap[s];
|
||||||
|
|
||||||
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
|
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
|
||||||
if (!args[i] && opt.type !== "boolean") {
|
if (!args[i] && opt.type !== "boolean") {
|
||||||
|
@ -377,19 +377,19 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseResponseFile(fileName: string) {
|
function parseResponseFile(fileName: string) {
|
||||||
let text = readFile ? readFile(fileName) : sys.readFile(fileName);
|
const text = readFile ? readFile(fileName) : sys.readFile(fileName);
|
||||||
|
|
||||||
if (!text) {
|
if (!text) {
|
||||||
errors.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, fileName));
|
errors.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, fileName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let args: string[] = [];
|
const args: string[] = [];
|
||||||
let pos = 0;
|
let pos = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
while (pos < text.length && text.charCodeAt(pos) <= CharacterCodes.space) pos++;
|
while (pos < text.length && text.charCodeAt(pos) <= CharacterCodes.space) pos++;
|
||||||
if (pos >= text.length) break;
|
if (pos >= text.length) break;
|
||||||
let start = pos;
|
const start = pos;
|
||||||
if (text.charCodeAt(start) === CharacterCodes.doubleQuote) {
|
if (text.charCodeAt(start) === CharacterCodes.doubleQuote) {
|
||||||
pos++;
|
pos++;
|
||||||
while (pos < text.length && text.charCodeAt(pos) !== CharacterCodes.doubleQuote) pos++;
|
while (pos < text.length && text.charCodeAt(pos) !== CharacterCodes.doubleQuote) pos++;
|
||||||
|
@ -432,7 +432,7 @@ namespace ts {
|
||||||
*/
|
*/
|
||||||
export function parseConfigFileTextToJson(fileName: string, jsonText: string): { config?: any; error?: Diagnostic } {
|
export function parseConfigFileTextToJson(fileName: string, jsonText: string): { config?: any; error?: Diagnostic } {
|
||||||
try {
|
try {
|
||||||
let jsonTextWithoutComments = removeComments(jsonText);
|
const jsonTextWithoutComments = removeComments(jsonText);
|
||||||
return { config: /\S/.test(jsonTextWithoutComments) ? JSON.parse(jsonTextWithoutComments) : {} };
|
return { config: /\S/.test(jsonTextWithoutComments) ? JSON.parse(jsonTextWithoutComments) : {} };
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
|
@ -449,7 +449,7 @@ namespace ts {
|
||||||
*/
|
*/
|
||||||
function removeComments(jsonText: string): string {
|
function removeComments(jsonText: string): string {
|
||||||
let output = "";
|
let output = "";
|
||||||
let scanner = createScanner(ScriptTarget.ES5, /* skipTrivia */ false, LanguageVariant.Standard, jsonText);
|
const scanner = createScanner(ScriptTarget.ES5, /* skipTrivia */ false, LanguageVariant.Standard, jsonText);
|
||||||
let token: SyntaxKind;
|
let token: SyntaxKind;
|
||||||
while ((token = scanner.scan()) !== SyntaxKind.EndOfFileToken) {
|
while ((token = scanner.scan()) !== SyntaxKind.EndOfFileToken) {
|
||||||
switch (token) {
|
switch (token) {
|
||||||
|
@ -475,7 +475,7 @@ namespace ts {
|
||||||
* file to. e.g. outDir
|
* file to. e.g. outDir
|
||||||
*/
|
*/
|
||||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string): ParsedCommandLine {
|
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string): ParsedCommandLine {
|
||||||
let { options, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
|
const { options, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
options,
|
options,
|
||||||
|
@ -494,12 +494,12 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let exclude = json["exclude"] instanceof Array ? map(<string[]>json["exclude"], normalizeSlashes) : undefined;
|
const exclude = json["exclude"] instanceof Array ? map(<string[]>json["exclude"], normalizeSlashes) : undefined;
|
||||||
let sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
|
const sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
|
||||||
for (let i = 0; i < sysFiles.length; i++) {
|
for (let i = 0; i < sysFiles.length; i++) {
|
||||||
let name = sysFiles[i];
|
const name = sysFiles[i];
|
||||||
if (fileExtensionIs(name, ".d.ts")) {
|
if (fileExtensionIs(name, ".d.ts")) {
|
||||||
let baseName = name.substr(0, name.length - ".d.ts".length);
|
const baseName = name.substr(0, name.length - ".d.ts".length);
|
||||||
if (!contains(sysFiles, baseName + ".tsx") && !contains(sysFiles, baseName + ".ts")) {
|
if (!contains(sysFiles, baseName + ".tsx") && !contains(sysFiles, baseName + ".ts")) {
|
||||||
fileNames.push(name);
|
fileNames.push(name);
|
||||||
}
|
}
|
||||||
|
@ -519,24 +519,24 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
||||||
let options: CompilerOptions = {};
|
const options: CompilerOptions = {};
|
||||||
let errors: Diagnostic[] = [];
|
const errors: Diagnostic[] = [];
|
||||||
|
|
||||||
if (!jsonOptions) {
|
if (!jsonOptions) {
|
||||||
return { options, errors };
|
return { options, errors };
|
||||||
}
|
}
|
||||||
|
|
||||||
let optionNameMap = arrayToMap(optionDeclarations, opt => opt.name);
|
const optionNameMap = arrayToMap(optionDeclarations, opt => opt.name);
|
||||||
|
|
||||||
for (let id in jsonOptions) {
|
for (const id in jsonOptions) {
|
||||||
if (hasProperty(optionNameMap, id)) {
|
if (hasProperty(optionNameMap, id)) {
|
||||||
let opt = optionNameMap[id];
|
const opt = optionNameMap[id];
|
||||||
let optType = opt.type;
|
const optType = opt.type;
|
||||||
let value = jsonOptions[id];
|
let value = jsonOptions[id];
|
||||||
let expectedType = typeof optType === "string" ? optType : "string";
|
const expectedType = typeof optType === "string" ? optType : "string";
|
||||||
if (typeof value === expectedType) {
|
if (typeof value === expectedType) {
|
||||||
if (typeof optType !== "string") {
|
if (typeof optType !== "string") {
|
||||||
let key = value.toLowerCase();
|
const key = value.toLowerCase();
|
||||||
if (hasProperty(optType, key)) {
|
if (hasProperty(optType, key)) {
|
||||||
value = optType[key];
|
value = optType[key];
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace ts {
|
||||||
};
|
};
|
||||||
|
|
||||||
function forEachValueInMap(f: (key: Path, value: T) => void) {
|
function forEachValueInMap(f: (key: Path, value: T) => void) {
|
||||||
for (let key in files) {
|
for (const key in files) {
|
||||||
f(<Path>key, files[key]);
|
f(<Path>key, files[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace ts {
|
||||||
export function forEach<T, U>(array: T[], callback: (element: T, index: number) => U): U {
|
export function forEach<T, U>(array: T[], callback: (element: T, index: number) => U): U {
|
||||||
if (array) {
|
if (array) {
|
||||||
for (let i = 0, len = array.length; i < len; i++) {
|
for (let i = 0, len = array.length; i < len; i++) {
|
||||||
let result = callback(array[i], i);
|
const result = callback(array[i], i);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ namespace ts {
|
||||||
|
|
||||||
export function contains<T>(array: T[], value: T): boolean {
|
export function contains<T>(array: T[], value: T): boolean {
|
||||||
if (array) {
|
if (array) {
|
||||||
for (let v of array) {
|
for (const v of array) {
|
||||||
if (v === value) {
|
if (v === value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ namespace ts {
|
||||||
export function countWhere<T>(array: T[], predicate: (x: T) => boolean): number {
|
export function countWhere<T>(array: T[], predicate: (x: T) => boolean): number {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
if (array) {
|
if (array) {
|
||||||
for (let v of array) {
|
for (const v of array) {
|
||||||
if (predicate(v)) {
|
if (predicate(v)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ namespace ts {
|
||||||
let result: T[];
|
let result: T[];
|
||||||
if (array) {
|
if (array) {
|
||||||
result = [];
|
result = [];
|
||||||
for (let item of array) {
|
for (const item of array) {
|
||||||
if (f(item)) {
|
if (f(item)) {
|
||||||
result.push(item);
|
result.push(item);
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ namespace ts {
|
||||||
let result: U[];
|
let result: U[];
|
||||||
if (array) {
|
if (array) {
|
||||||
result = [];
|
result = [];
|
||||||
for (let v of array) {
|
for (const v of array) {
|
||||||
result.push(f(v));
|
result.push(f(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ namespace ts {
|
||||||
let result: T[];
|
let result: T[];
|
||||||
if (array) {
|
if (array) {
|
||||||
result = [];
|
result = [];
|
||||||
for (let item of array) {
|
for (const item of array) {
|
||||||
if (!contains(result, item)) {
|
if (!contains(result, item)) {
|
||||||
result.push(item);
|
result.push(item);
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ namespace ts {
|
||||||
|
|
||||||
export function sum(array: any[], prop: string): number {
|
export function sum(array: any[], prop: string): number {
|
||||||
let result = 0;
|
let result = 0;
|
||||||
for (let v of array) {
|
for (const v of array) {
|
||||||
result += v[prop];
|
result += v[prop];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -181,7 +181,7 @@ namespace ts {
|
||||||
|
|
||||||
export function addRange<T>(to: T[], from: T[]): void {
|
export function addRange<T>(to: T[], from: T[]): void {
|
||||||
if (to && from) {
|
if (to && from) {
|
||||||
for (let v of from) {
|
for (const v of from) {
|
||||||
to.push(v);
|
to.push(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,8 +220,8 @@ namespace ts {
|
||||||
let high = array.length - 1;
|
let high = array.length - 1;
|
||||||
|
|
||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
let middle = low + ((high - low) >> 1);
|
const middle = low + ((high - low) >> 1);
|
||||||
let midValue = array[middle];
|
const midValue = array[middle];
|
||||||
|
|
||||||
if (midValue === value) {
|
if (midValue === value) {
|
||||||
return middle;
|
return middle;
|
||||||
|
@ -270,7 +270,7 @@ namespace ts {
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasOwnProperty = Object.prototype.hasOwnProperty;
|
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||||
|
|
||||||
export function hasProperty<T>(map: Map<T>, key: string): boolean {
|
export function hasProperty<T>(map: Map<T>, key: string): boolean {
|
||||||
return hasOwnProperty.call(map, key);
|
return hasOwnProperty.call(map, key);
|
||||||
|
@ -281,7 +281,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isEmpty<T>(map: Map<T>) {
|
export function isEmpty<T>(map: Map<T>) {
|
||||||
for (let id in map) {
|
for (const id in map) {
|
||||||
if (hasProperty(map, id)) {
|
if (hasProperty(map, id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -290,19 +290,19 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clone<T>(object: T): T {
|
export function clone<T>(object: T): T {
|
||||||
let result: any = {};
|
const result: any = {};
|
||||||
for (let id in object) {
|
for (const id in object) {
|
||||||
result[id] = (<any>object)[id];
|
result[id] = (<any>object)[id];
|
||||||
}
|
}
|
||||||
return <T>result;
|
return <T>result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extend<T1, T2>(first: Map<T1>, second: Map<T2>): Map<T1 & T2> {
|
export function extend<T1, T2>(first: Map<T1>, second: Map<T2>): Map<T1 & T2> {
|
||||||
let result: Map<T1 & T2> = {};
|
const result: Map<T1 & T2> = {};
|
||||||
for (let id in first) {
|
for (const id in first) {
|
||||||
(result as any)[id] = first[id];
|
(result as any)[id] = first[id];
|
||||||
}
|
}
|
||||||
for (let id in second) {
|
for (const id in second) {
|
||||||
if (!hasProperty(result, id)) {
|
if (!hasProperty(result, id)) {
|
||||||
(result as any)[id] = second[id];
|
(result as any)[id] = second[id];
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ namespace ts {
|
||||||
|
|
||||||
export function forEachValue<T, U>(map: Map<T>, callback: (value: T) => U): U {
|
export function forEachValue<T, U>(map: Map<T>, callback: (value: T) => U): U {
|
||||||
let result: U;
|
let result: U;
|
||||||
for (let id in map) {
|
for (const id in map) {
|
||||||
if (result = callback(map[id])) break;
|
if (result = callback(map[id])) break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -320,7 +320,7 @@ namespace ts {
|
||||||
|
|
||||||
export function forEachKey<T, U>(map: Map<T>, callback: (key: string) => U): U {
|
export function forEachKey<T, U>(map: Map<T>, callback: (key: string) => U): U {
|
||||||
let result: U;
|
let result: U;
|
||||||
for (let id in map) {
|
for (const id in map) {
|
||||||
if (result = callback(id)) break;
|
if (result = callback(id)) break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -331,7 +331,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function copyMap<T>(source: Map<T>, target: Map<T>): void {
|
export function copyMap<T>(source: Map<T>, target: Map<T>): void {
|
||||||
for (let p in source) {
|
for (const p in source) {
|
||||||
target[p] = source[p];
|
target[p] = source[p];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,7 @@ namespace ts {
|
||||||
* index in the array will be the one associated with the produced key.
|
* index in the array will be the one associated with the produced key.
|
||||||
*/
|
*/
|
||||||
export function arrayToMap<T>(array: T[], makeKey: (value: T) => string): Map<T> {
|
export function arrayToMap<T>(array: T[], makeKey: (value: T) => string): Map<T> {
|
||||||
let result: Map<T> = {};
|
const result: Map<T> = {};
|
||||||
|
|
||||||
forEach(array, value => {
|
forEach(array, value => {
|
||||||
result[makeKey(value)] = value;
|
result[makeKey(value)] = value;
|
||||||
|
@ -383,7 +383,7 @@ namespace ts {
|
||||||
|
|
||||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
|
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
|
||||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
|
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
|
||||||
let end = start + length;
|
const end = start + length;
|
||||||
|
|
||||||
Debug.assert(start >= 0, "start must be non-negative, is " + start);
|
Debug.assert(start >= 0, "start must be non-negative, is " + start);
|
||||||
Debug.assert(length >= 0, "length must be non-negative, is " + length);
|
Debug.assert(length >= 0, "length must be non-negative, is " + length);
|
||||||
|
@ -479,10 +479,10 @@ namespace ts {
|
||||||
function compareMessageText(text1: string | DiagnosticMessageChain, text2: string | DiagnosticMessageChain): Comparison {
|
function compareMessageText(text1: string | DiagnosticMessageChain, text2: string | DiagnosticMessageChain): Comparison {
|
||||||
while (text1 && text2) {
|
while (text1 && text2) {
|
||||||
// We still have both chains.
|
// We still have both chains.
|
||||||
let string1 = typeof text1 === "string" ? text1 : text1.messageText;
|
const string1 = typeof text1 === "string" ? text1 : text1.messageText;
|
||||||
let string2 = typeof text2 === "string" ? text2 : text2.messageText;
|
const string2 = typeof text2 === "string" ? text2 : text2.messageText;
|
||||||
|
|
||||||
let res = compareValues(string1, string2);
|
const res = compareValues(string1, string2);
|
||||||
if (res) {
|
if (res) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -509,11 +509,11 @@ namespace ts {
|
||||||
return diagnostics;
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newDiagnostics = [diagnostics[0]];
|
const newDiagnostics = [diagnostics[0]];
|
||||||
let previousDiagnostic = diagnostics[0];
|
let previousDiagnostic = diagnostics[0];
|
||||||
for (let i = 1; i < diagnostics.length; i++) {
|
for (let i = 1; i < diagnostics.length; i++) {
|
||||||
let currentDiagnostic = diagnostics[i];
|
const currentDiagnostic = diagnostics[i];
|
||||||
let isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === Comparison.EqualTo;
|
const isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === Comparison.EqualTo;
|
||||||
if (!isDupe) {
|
if (!isDupe) {
|
||||||
newDiagnostics.push(currentDiagnostic);
|
newDiagnostics.push(currentDiagnostic);
|
||||||
previousDiagnostic = currentDiagnostic;
|
previousDiagnostic = currentDiagnostic;
|
||||||
|
@ -531,9 +531,9 @@ namespace ts {
|
||||||
export function getRootLength(path: string): number {
|
export function getRootLength(path: string): number {
|
||||||
if (path.charCodeAt(0) === CharacterCodes.slash) {
|
if (path.charCodeAt(0) === CharacterCodes.slash) {
|
||||||
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
|
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
|
||||||
let p1 = path.indexOf("/", 2);
|
const p1 = path.indexOf("/", 2);
|
||||||
if (p1 < 0) return 2;
|
if (p1 < 0) return 2;
|
||||||
let p2 = path.indexOf("/", p1 + 1);
|
const p2 = path.indexOf("/", p1 + 1);
|
||||||
if (p2 < 0) return p1 + 1;
|
if (p2 < 0) return p1 + 1;
|
||||||
return p2 + 1;
|
return p2 + 1;
|
||||||
}
|
}
|
||||||
|
@ -549,7 +549,7 @@ namespace ts {
|
||||||
if (path.lastIndexOf("file:///", 0) === 0) {
|
if (path.lastIndexOf("file:///", 0) === 0) {
|
||||||
return "file:///".length;
|
return "file:///".length;
|
||||||
}
|
}
|
||||||
let idx = path.indexOf("://");
|
const idx = path.indexOf("://");
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
return idx + "://".length;
|
return idx + "://".length;
|
||||||
}
|
}
|
||||||
|
@ -558,9 +558,9 @@ namespace ts {
|
||||||
|
|
||||||
export let directorySeparator = "/";
|
export let directorySeparator = "/";
|
||||||
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
|
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
|
||||||
let parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
|
const parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
|
||||||
let normalized: string[] = [];
|
const normalized: string[] = [];
|
||||||
for (let part of parts) {
|
for (const part of parts) {
|
||||||
if (part !== ".") {
|
if (part !== ".") {
|
||||||
if (part === ".." && normalized.length > 0 && lastOrUndefined(normalized) !== "..") {
|
if (part === ".." && normalized.length > 0 && lastOrUndefined(normalized) !== "..") {
|
||||||
normalized.pop();
|
normalized.pop();
|
||||||
|
@ -580,8 +580,8 @@ namespace ts {
|
||||||
|
|
||||||
export function normalizePath(path: string): string {
|
export function normalizePath(path: string): string {
|
||||||
path = normalizeSlashes(path);
|
path = normalizeSlashes(path);
|
||||||
let rootLength = getRootLength(path);
|
const rootLength = getRootLength(path);
|
||||||
let normalized = getNormalizedParts(path, rootLength);
|
const normalized = getNormalizedParts(path, rootLength);
|
||||||
return path.substr(0, rootLength) + normalized.join(directorySeparator);
|
return path.substr(0, rootLength) + normalized.join(directorySeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +598,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizedPathComponents(path: string, rootLength: number) {
|
function normalizedPathComponents(path: string, rootLength: number) {
|
||||||
let normalizedParts = getNormalizedParts(path, rootLength);
|
const normalizedParts = getNormalizedParts(path, rootLength);
|
||||||
return [path.substr(0, rootLength)].concat(normalizedParts);
|
return [path.substr(0, rootLength)].concat(normalizedParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,7 +629,7 @@ namespace ts {
|
||||||
// In this example the root is: http://www.website.com/
|
// In this example the root is: http://www.website.com/
|
||||||
// normalized path components should be ["http://www.website.com/", "folder1", "folder2"]
|
// normalized path components should be ["http://www.website.com/", "folder1", "folder2"]
|
||||||
|
|
||||||
let urlLength = url.length;
|
const urlLength = url.length;
|
||||||
// Initial root length is http:// part
|
// Initial root length is http:// part
|
||||||
let rootLength = url.indexOf("://") + "://".length;
|
let rootLength = url.indexOf("://") + "://".length;
|
||||||
while (rootLength < urlLength) {
|
while (rootLength < urlLength) {
|
||||||
|
@ -650,7 +650,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the index of "/" after website.com so the root can be http://www.website.com/ (from existing http://)
|
// Find the index of "/" after website.com so the root can be http://www.website.com/ (from existing http://)
|
||||||
let indexOfNextSlash = url.indexOf(directorySeparator, rootLength);
|
const indexOfNextSlash = url.indexOf(directorySeparator, rootLength);
|
||||||
if (indexOfNextSlash !== -1) {
|
if (indexOfNextSlash !== -1) {
|
||||||
// Found the "/" after the website.com so the root is length of http://www.website.com/
|
// Found the "/" after the website.com so the root is length of http://www.website.com/
|
||||||
// and get components afetr the root normally like any other folder components
|
// and get components afetr the root normally like any other folder components
|
||||||
|
@ -676,8 +676,8 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: (fileName: string) => string, isAbsolutePathAnUrl: boolean) {
|
export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: (fileName: string) => string, isAbsolutePathAnUrl: boolean) {
|
||||||
let pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory);
|
const pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory);
|
||||||
let directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory);
|
const directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory);
|
||||||
if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") {
|
if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") {
|
||||||
// If the directory path given was of type test/cases/ then we really need components of directory to be only till its name
|
// If the directory path given was of type test/cases/ then we really need components of directory to be only till its name
|
||||||
// that is ["test", "cases", ""] needs to be actually ["test", "cases"]
|
// that is ["test", "cases", ""] needs to be actually ["test", "cases"]
|
||||||
|
@ -694,7 +694,7 @@ namespace ts {
|
||||||
// Get the relative path
|
// Get the relative path
|
||||||
if (joinStartIndex) {
|
if (joinStartIndex) {
|
||||||
let relativePath = "";
|
let relativePath = "";
|
||||||
let relativePathComponents = pathComponents.slice(joinStartIndex, pathComponents.length);
|
const relativePathComponents = pathComponents.slice(joinStartIndex, pathComponents.length);
|
||||||
for (; joinStartIndex < directoryComponents.length; joinStartIndex++) {
|
for (; joinStartIndex < directoryComponents.length; joinStartIndex++) {
|
||||||
if (directoryComponents[joinStartIndex] !== "") {
|
if (directoryComponents[joinStartIndex] !== "") {
|
||||||
relativePath = relativePath + ".." + directorySeparator;
|
relativePath = relativePath + ".." + directorySeparator;
|
||||||
|
@ -717,7 +717,7 @@ namespace ts {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
let i = path.lastIndexOf(directorySeparator);
|
const i = path.lastIndexOf(directorySeparator);
|
||||||
return i < 0 ? path : path.substring(i + 1);
|
return i < 0 ? path : path.substring(i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,8 +730,8 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fileExtensionIs(path: string, extension: string): boolean {
|
export function fileExtensionIs(path: string, extension: string): boolean {
|
||||||
let pathLen = path.length;
|
const pathLen = path.length;
|
||||||
let extLen = extension.length;
|
const extLen = extension.length;
|
||||||
return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension;
|
return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,7 +749,7 @@ namespace ts {
|
||||||
export function isSupportedSourceFileName(fileName: string) {
|
export function isSupportedSourceFileName(fileName: string) {
|
||||||
if (!fileName) { return false; }
|
if (!fileName) { return false; }
|
||||||
|
|
||||||
for (let extension of supportedExtensions) {
|
for (const extension of supportedExtensions) {
|
||||||
if (fileExtensionIs(fileName, extension)) {
|
if (fileExtensionIs(fileName, extension)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,7 @@ namespace ts {
|
||||||
|
|
||||||
const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"];
|
const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"];
|
||||||
export function removeFileExtension(path: string): string {
|
export function removeFileExtension(path: string): string {
|
||||||
for (let ext of extensionsToRemove) {
|
for (const ext of extensionsToRemove) {
|
||||||
if (fileExtensionIs(path, ext)) {
|
if (fileExtensionIs(path, ext)) {
|
||||||
return path.substr(0, path.length - ext.length);
|
return path.substr(0, path.length - ext.length);
|
||||||
}
|
}
|
||||||
|
@ -767,9 +767,9 @@ namespace ts {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
let backslashOrDoubleQuote = /[\"\\]/g;
|
const backslashOrDoubleQuote = /[\"\\]/g;
|
||||||
let escapedCharsRegExp = /[\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
const escapedCharsRegExp = /[\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||||
let escapedCharsMap: Map<string> = {
|
const escapedCharsMap: Map<string> = {
|
||||||
"\0": "\\0",
|
"\0": "\\0",
|
||||||
"\t": "\\t",
|
"\t": "\\t",
|
||||||
"\v": "\\v",
|
"\v": "\\v",
|
||||||
|
@ -785,7 +785,8 @@ namespace ts {
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ObjectAllocator {
|
export interface ObjectAllocator {
|
||||||
getNodeConstructor(kind: SyntaxKind): new (pos?: number, end?: number) => Node;
|
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
|
||||||
|
getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile;
|
||||||
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
|
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
|
||||||
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
|
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
|
||||||
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
|
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
|
||||||
|
@ -804,17 +805,17 @@ namespace ts {
|
||||||
function Signature(checker: TypeChecker) {
|
function Signature(checker: TypeChecker) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export let objectAllocator: ObjectAllocator = {
|
function Node(kind: SyntaxKind, pos: number, end: number) {
|
||||||
getNodeConstructor: kind => {
|
this.kind = kind;
|
||||||
function Node(pos: number, end: number) {
|
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
this.end = end;
|
this.end = end;
|
||||||
this.flags = NodeFlags.None;
|
this.flags = NodeFlags.None;
|
||||||
this.parent = undefined;
|
this.parent = undefined;
|
||||||
}
|
}
|
||||||
Node.prototype = { kind };
|
|
||||||
return <any>Node;
|
export let objectAllocator: ObjectAllocator = {
|
||||||
},
|
getNodeConstructor: () => <any>Node,
|
||||||
|
getSourceFileConstructor: () => <any>Node,
|
||||||
getSymbolConstructor: () => <any>Symbol,
|
getSymbolConstructor: () => <any>Symbol,
|
||||||
getTypeConstructor: () => <any>Type,
|
getTypeConstructor: () => <any>Type,
|
||||||
getSignatureConstructor: () => <any>Signature
|
getSignatureConstructor: () => <any>Signature
|
||||||
|
@ -828,7 +829,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace Debug {
|
export namespace Debug {
|
||||||
let currentAssertionLevel = AssertionLevel.None;
|
const currentAssertionLevel = AssertionLevel.None;
|
||||||
|
|
||||||
export function shouldAssert(level: AssertionLevel): boolean {
|
export function shouldAssert(level: AssertionLevel): boolean {
|
||||||
return currentAssertionLevel >= level;
|
return currentAssertionLevel >= level;
|
||||||
|
@ -851,8 +852,8 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function copyListRemovingItem<T>(item: T, list: T[]) {
|
export function copyListRemovingItem<T>(item: T, list: T[]) {
|
||||||
let copiedList: T[] = [];
|
const copiedList: T[] = [];
|
||||||
for (let e of list) {
|
for (const e of list) {
|
||||||
if (e !== item) {
|
if (e !== item) {
|
||||||
copiedList.push(e);
|
copiedList.push(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,30 +31,33 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
|
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
|
||||||
let diagnostics: Diagnostic[] = [];
|
const diagnostics: Diagnostic[] = [];
|
||||||
let jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
|
const jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
|
||||||
emitDeclarations(host, resolver, diagnostics, jsFilePath, targetSourceFile);
|
emitDeclarations(host, resolver, diagnostics, jsFilePath, targetSourceFile);
|
||||||
return diagnostics;
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitDeclarations(host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[], jsFilePath: string, root?: SourceFile): DeclarationEmit {
|
function emitDeclarations(host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[], jsFilePath: string, root?: SourceFile): DeclarationEmit {
|
||||||
let newLine = host.getNewLine();
|
const newLine = host.getNewLine();
|
||||||
let compilerOptions = host.getCompilerOptions();
|
const compilerOptions = host.getCompilerOptions();
|
||||||
|
|
||||||
let write: (s: string) => void;
|
let write: (s: string) => void;
|
||||||
let writeLine: () => void;
|
let writeLine: () => void;
|
||||||
let increaseIndent: () => void;
|
let increaseIndent: () => void;
|
||||||
let decreaseIndent: () => void;
|
let decreaseIndent: () => void;
|
||||||
let writeTextOfNode: (sourceFile: SourceFile, node: Node) => void;
|
let writeTextOfNode: (text: string, node: Node) => void;
|
||||||
|
|
||||||
let writer = createAndSetNewTextWriterWithSymbolWriter();
|
let writer = createAndSetNewTextWriterWithSymbolWriter();
|
||||||
|
|
||||||
let enclosingDeclaration: Node;
|
let enclosingDeclaration: Node;
|
||||||
let currentSourceFile: SourceFile;
|
let currentText: string;
|
||||||
|
let currentLineMap: number[];
|
||||||
|
let currentIdentifiers: Map<string>;
|
||||||
|
let isCurrentFileExternalModule: boolean;
|
||||||
let reportedDeclarationError = false;
|
let reportedDeclarationError = false;
|
||||||
let errorNameNode: DeclarationName;
|
let errorNameNode: DeclarationName;
|
||||||
let emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
|
const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
|
||||||
let emit = compilerOptions.stripInternal ? stripInternal : emitNode;
|
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
|
||||||
let noDeclare = !root;
|
let noDeclare = !root;
|
||||||
|
|
||||||
let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||||
|
@ -70,7 +73,7 @@ namespace ts {
|
||||||
if (!compilerOptions.noResolve) {
|
if (!compilerOptions.noResolve) {
|
||||||
let addedGlobalFileReference = false;
|
let addedGlobalFileReference = false;
|
||||||
forEach(root.referencedFiles, fileReference => {
|
forEach(root.referencedFiles, fileReference => {
|
||||||
let referencedFile = tryResolveScriptReference(host, root, fileReference);
|
const referencedFile = tryResolveScriptReference(host, root, fileReference);
|
||||||
|
|
||||||
// All the references that are not going to be part of same file
|
// All the references that are not going to be part of same file
|
||||||
if (referencedFile && ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
|
if (referencedFile && ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
|
||||||
|
@ -89,7 +92,7 @@ namespace ts {
|
||||||
|
|
||||||
// create asynchronous output for the importDeclarations
|
// create asynchronous output for the importDeclarations
|
||||||
if (moduleElementDeclarationEmitInfo.length) {
|
if (moduleElementDeclarationEmitInfo.length) {
|
||||||
let oldWriter = writer;
|
const oldWriter = writer;
|
||||||
forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => {
|
forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => {
|
||||||
if (aliasEmitInfo.isVisible) {
|
if (aliasEmitInfo.isVisible) {
|
||||||
Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration);
|
Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration);
|
||||||
|
@ -104,14 +107,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Emit references corresponding to this file
|
// Emit references corresponding to this file
|
||||||
let emittedReferencedFiles: SourceFile[] = [];
|
const emittedReferencedFiles: SourceFile[] = [];
|
||||||
let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||||
forEach(host.getSourceFiles(), sourceFile => {
|
forEach(host.getSourceFiles(), sourceFile => {
|
||||||
if (!isDeclarationFile(sourceFile)) {
|
if (!isDeclarationFile(sourceFile)) {
|
||||||
// Check what references need to be added
|
// Check what references need to be added
|
||||||
if (!compilerOptions.noResolve) {
|
if (!compilerOptions.noResolve) {
|
||||||
forEach(sourceFile.referencedFiles, fileReference => {
|
forEach(sourceFile.referencedFiles, fileReference => {
|
||||||
let referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
|
const referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
|
||||||
|
|
||||||
// If the reference file is a declaration file, emit that reference
|
// If the reference file is a declaration file, emit that reference
|
||||||
if (referencedFile && (isDeclarationFile(referencedFile) &&
|
if (referencedFile && (isDeclarationFile(referencedFile) &&
|
||||||
|
@ -169,14 +172,13 @@ namespace ts {
|
||||||
};
|
};
|
||||||
|
|
||||||
function hasInternalAnnotation(range: CommentRange) {
|
function hasInternalAnnotation(range: CommentRange) {
|
||||||
let text = currentSourceFile.text;
|
const comment = currentText.substring(range.pos, range.end);
|
||||||
let comment = text.substring(range.pos, range.end);
|
|
||||||
return comment.indexOf("@internal") >= 0;
|
return comment.indexOf("@internal") >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function stripInternal(node: Node) {
|
function stripInternal(node: Node) {
|
||||||
if (node) {
|
if (node) {
|
||||||
let leadingCommentRanges = getLeadingCommentRanges(currentSourceFile.text, node.pos);
|
const leadingCommentRanges = getLeadingCommentRanges(currentText, node.pos);
|
||||||
if (forEach(leadingCommentRanges, hasInternalAnnotation)) {
|
if (forEach(leadingCommentRanges, hasInternalAnnotation)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +188,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAndSetNewTextWriterWithSymbolWriter(): EmitTextWriterWithSymbolWriter {
|
function createAndSetNewTextWriterWithSymbolWriter(): EmitTextWriterWithSymbolWriter {
|
||||||
let writer = <EmitTextWriterWithSymbolWriter>createTextWriter(newLine);
|
const writer = <EmitTextWriterWithSymbolWriter>createTextWriter(newLine);
|
||||||
writer.trackSymbol = trackSymbol;
|
writer.trackSymbol = trackSymbol;
|
||||||
writer.reportInaccessibleThisError = reportInaccessibleThisError;
|
writer.reportInaccessibleThisError = reportInaccessibleThisError;
|
||||||
writer.writeKeyword = writer.write;
|
writer.writeKeyword = writer.write;
|
||||||
|
@ -210,7 +212,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeAsynchronousModuleElements(nodes: Node[]) {
|
function writeAsynchronousModuleElements(nodes: Node[]) {
|
||||||
let oldWriter = writer;
|
const oldWriter = writer;
|
||||||
forEach(nodes, declaration => {
|
forEach(nodes, declaration => {
|
||||||
let nodeToCheck: Node;
|
let nodeToCheck: Node;
|
||||||
if (declaration.kind === SyntaxKind.VariableDeclaration) {
|
if (declaration.kind === SyntaxKind.VariableDeclaration) {
|
||||||
|
@ -273,12 +275,12 @@ namespace ts {
|
||||||
else {
|
else {
|
||||||
// Report error
|
// Report error
|
||||||
reportedDeclarationError = true;
|
reportedDeclarationError = true;
|
||||||
let errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
|
const errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
|
||||||
if (errorInfo) {
|
if (errorInfo) {
|
||||||
if (errorInfo.typeName) {
|
if (errorInfo.typeName) {
|
||||||
diagnostics.push(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
|
diagnostics.push(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
|
||||||
errorInfo.diagnosticMessage,
|
errorInfo.diagnosticMessage,
|
||||||
getSourceTextOfNodeFromSourceFile(currentSourceFile, errorInfo.typeName),
|
getTextOfNodeFromSourceText(currentText, errorInfo.typeName),
|
||||||
symbolAccesibilityResult.errorSymbolName,
|
symbolAccesibilityResult.errorSymbolName,
|
||||||
symbolAccesibilityResult.errorModuleName));
|
symbolAccesibilityResult.errorModuleName));
|
||||||
}
|
}
|
||||||
|
@ -332,14 +334,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitLines(nodes: Node[]) {
|
function emitLines(nodes: Node[]) {
|
||||||
for (let node of nodes) {
|
for (const node of nodes) {
|
||||||
emit(node);
|
emit(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||||
let currentWriterPos = writer.getTextPos();
|
let currentWriterPos = writer.getTextPos();
|
||||||
for (let node of nodes) {
|
for (const node of nodes) {
|
||||||
if (!canEmitFn || canEmitFn(node)) {
|
if (!canEmitFn || canEmitFn(node)) {
|
||||||
if (currentWriterPos !== writer.getTextPos()) {
|
if (currentWriterPos !== writer.getTextPos()) {
|
||||||
write(separator);
|
write(separator);
|
||||||
|
@ -356,10 +358,10 @@ namespace ts {
|
||||||
|
|
||||||
function writeJsDocComments(declaration: Node) {
|
function writeJsDocComments(declaration: Node) {
|
||||||
if (declaration) {
|
if (declaration) {
|
||||||
let jsDocComments = getJsDocComments(declaration, currentSourceFile);
|
const jsDocComments = getJsDocCommentsFromText(declaration, currentText);
|
||||||
emitNewLineBeforeLeadingComments(currentSourceFile, writer, declaration, jsDocComments);
|
emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
|
||||||
// jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
|
// jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||||
emitComments(currentSourceFile, writer, jsDocComments, /*trailingSeparator*/ true, newLine, writeCommentRange);
|
emitComments(currentText, currentLineMap, writer, jsDocComments, /*trailingSeparator*/ true, newLine, writeCommentRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +380,7 @@ namespace ts {
|
||||||
case SyntaxKind.VoidKeyword:
|
case SyntaxKind.VoidKeyword:
|
||||||
case SyntaxKind.ThisKeyword:
|
case SyntaxKind.ThisKeyword:
|
||||||
case SyntaxKind.StringLiteral:
|
case SyntaxKind.StringLiteral:
|
||||||
return writeTextOfNode(currentSourceFile, type);
|
return writeTextOfNode(currentText, type);
|
||||||
case SyntaxKind.ExpressionWithTypeArguments:
|
case SyntaxKind.ExpressionWithTypeArguments:
|
||||||
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>type);
|
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>type);
|
||||||
case SyntaxKind.TypeReference:
|
case SyntaxKind.TypeReference:
|
||||||
|
@ -410,19 +412,19 @@ namespace ts {
|
||||||
|
|
||||||
function writeEntityName(entityName: EntityName | Expression) {
|
function writeEntityName(entityName: EntityName | Expression) {
|
||||||
if (entityName.kind === SyntaxKind.Identifier) {
|
if (entityName.kind === SyntaxKind.Identifier) {
|
||||||
writeTextOfNode(currentSourceFile, entityName);
|
writeTextOfNode(currentText, entityName);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
|
const left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
|
||||||
let right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
|
const right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
|
||||||
writeEntityName(left);
|
writeEntityName(left);
|
||||||
write(".");
|
write(".");
|
||||||
writeTextOfNode(currentSourceFile, right);
|
writeTextOfNode(currentText, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitEntityName(entityName: EntityName | PropertyAccessExpression) {
|
function emitEntityName(entityName: EntityName | PropertyAccessExpression) {
|
||||||
let visibilityResult = resolver.isEntityNameVisible(entityName,
|
const visibilityResult = resolver.isEntityNameVisible(entityName,
|
||||||
// Aliases can be written asynchronously so use correct enclosing declaration
|
// Aliases can be written asynchronously so use correct enclosing declaration
|
||||||
entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration ? entityName.parent : enclosingDeclaration);
|
entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration ? entityName.parent : enclosingDeclaration);
|
||||||
|
|
||||||
|
@ -452,7 +454,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitTypePredicate(type: TypePredicateNode) {
|
function emitTypePredicate(type: TypePredicateNode) {
|
||||||
writeTextOfNode(currentSourceFile, type.parameterName);
|
writeTextOfNode(currentText, type.parameterName);
|
||||||
write(" is ");
|
write(" is ");
|
||||||
emitType(type.type);
|
emitType(type.type);
|
||||||
}
|
}
|
||||||
|
@ -501,9 +503,12 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitSourceFile(node: SourceFile) {
|
function emitSourceFile(node: SourceFile) {
|
||||||
currentSourceFile = node;
|
currentText = node.text;
|
||||||
|
currentLineMap = getLineStarts(node);
|
||||||
|
currentIdentifiers = node.identifiers;
|
||||||
|
isCurrentFileExternalModule = isExternalModule(node);
|
||||||
enclosingDeclaration = node;
|
enclosingDeclaration = node;
|
||||||
emitDetachedComments(currentSourceFile, writer, writeCommentRange, node, newLine, true /* remove comments */);
|
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, true /* remove comments */);
|
||||||
emitLines(node.statements);
|
emitLines(node.statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,14 +517,14 @@ namespace ts {
|
||||||
// Note that export default is only allowed at most once in a module, so we
|
// Note that export default is only allowed at most once in a module, so we
|
||||||
// do not need to keep track of created temp names.
|
// do not need to keep track of created temp names.
|
||||||
function getExportDefaultTempVariableName(): string {
|
function getExportDefaultTempVariableName(): string {
|
||||||
let baseName = "_default";
|
const baseName = "_default";
|
||||||
if (!hasProperty(currentSourceFile.identifiers, baseName)) {
|
if (!hasProperty(currentIdentifiers, baseName)) {
|
||||||
return baseName;
|
return baseName;
|
||||||
}
|
}
|
||||||
let count = 0;
|
let count = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
let name = baseName + "_" + (++count);
|
const name = baseName + "_" + (++count);
|
||||||
if (!hasProperty(currentSourceFile.identifiers, name)) {
|
if (!hasProperty(currentIdentifiers, name)) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,11 +533,11 @@ namespace ts {
|
||||||
function emitExportAssignment(node: ExportAssignment) {
|
function emitExportAssignment(node: ExportAssignment) {
|
||||||
if (node.expression.kind === SyntaxKind.Identifier) {
|
if (node.expression.kind === SyntaxKind.Identifier) {
|
||||||
write(node.isExportEquals ? "export = " : "export default ");
|
write(node.isExportEquals ? "export = " : "export default ");
|
||||||
writeTextOfNode(currentSourceFile, node.expression);
|
writeTextOfNode(currentText, node.expression);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Expression
|
// Expression
|
||||||
let tempVarName = getExportDefaultTempVariableName();
|
const tempVarName = getExportDefaultTempVariableName();
|
||||||
write("declare var ");
|
write("declare var ");
|
||||||
write(tempVarName);
|
write(tempVarName);
|
||||||
write(": ");
|
write(": ");
|
||||||
|
@ -548,7 +553,7 @@ namespace ts {
|
||||||
|
|
||||||
// Make all the declarations visible for the export name
|
// Make all the declarations visible for the export name
|
||||||
if (node.expression.kind === SyntaxKind.Identifier) {
|
if (node.expression.kind === SyntaxKind.Identifier) {
|
||||||
let nodes = resolver.collectLinkedAliases(<Identifier>node.expression);
|
const nodes = resolver.collectLinkedAliases(<Identifier>node.expression);
|
||||||
|
|
||||||
// write each of these declarations asynchronously
|
// write each of these declarations asynchronously
|
||||||
writeAsynchronousModuleElements(nodes);
|
writeAsynchronousModuleElements(nodes);
|
||||||
|
@ -572,7 +577,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
// Import equals declaration in internal module can become visible as part of any emit so lets make sure we add these irrespective
|
// Import equals declaration in internal module can become visible as part of any emit so lets make sure we add these irrespective
|
||||||
else if (node.kind === SyntaxKind.ImportEqualsDeclaration ||
|
else if (node.kind === SyntaxKind.ImportEqualsDeclaration ||
|
||||||
(node.parent.kind === SyntaxKind.SourceFile && isExternalModule(currentSourceFile))) {
|
(node.parent.kind === SyntaxKind.SourceFile && isCurrentFileExternalModule)) {
|
||||||
let isVisible: boolean;
|
let isVisible: boolean;
|
||||||
if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== SyntaxKind.SourceFile) {
|
if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== SyntaxKind.SourceFile) {
|
||||||
// Import declaration of another module that is visited async so lets put it in right spot
|
// Import declaration of another module that is visited async so lets put it in right spot
|
||||||
|
@ -585,7 +590,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (node.kind === SyntaxKind.ImportDeclaration) {
|
if (node.kind === SyntaxKind.ImportDeclaration) {
|
||||||
let importDeclaration = <ImportDeclaration>node;
|
const importDeclaration = <ImportDeclaration>node;
|
||||||
if (importDeclaration.importClause) {
|
if (importDeclaration.importClause) {
|
||||||
isVisible = (importDeclaration.importClause.name && resolver.isDeclarationVisible(importDeclaration.importClause)) ||
|
isVisible = (importDeclaration.importClause.name && resolver.isDeclarationVisible(importDeclaration.importClause)) ||
|
||||||
isVisibleNamedBinding(importDeclaration.importClause.namedBindings);
|
isVisibleNamedBinding(importDeclaration.importClause.namedBindings);
|
||||||
|
@ -628,7 +633,7 @@ namespace ts {
|
||||||
|
|
||||||
function emitModuleElementDeclarationFlags(node: Node) {
|
function emitModuleElementDeclarationFlags(node: Node) {
|
||||||
// If the node is parented in the current source file we need to emit export declare or just export
|
// If the node is parented in the current source file we need to emit export declare or just export
|
||||||
if (node.parent === currentSourceFile) {
|
if (node.parent.kind === SyntaxKind.SourceFile) {
|
||||||
// If the node is exported
|
// If the node is exported
|
||||||
if (node.flags & NodeFlags.Export) {
|
if (node.flags & NodeFlags.Export) {
|
||||||
write("export ");
|
write("export ");
|
||||||
|
@ -667,7 +672,7 @@ namespace ts {
|
||||||
write("export ");
|
write("export ");
|
||||||
}
|
}
|
||||||
write("import ");
|
write("import ");
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
write(" = ");
|
write(" = ");
|
||||||
if (isInternalModuleImportEqualsDeclaration(node)) {
|
if (isInternalModuleImportEqualsDeclaration(node)) {
|
||||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(<EntityName>node.moduleReference, getImportEntityNameVisibilityError);
|
emitTypeWithNewGetSymbolAccessibilityDiagnostic(<EntityName>node.moduleReference, getImportEntityNameVisibilityError);
|
||||||
|
@ -675,7 +680,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
write("require(");
|
write("require(");
|
||||||
writeTextOfNode(currentSourceFile, getExternalModuleImportEqualsDeclarationExpression(node));
|
writeTextOfNode(currentText, getExternalModuleImportEqualsDeclarationExpression(node));
|
||||||
write(");");
|
write(");");
|
||||||
}
|
}
|
||||||
writer.writeLine();
|
writer.writeLine();
|
||||||
|
@ -711,9 +716,9 @@ namespace ts {
|
||||||
}
|
}
|
||||||
write("import ");
|
write("import ");
|
||||||
if (node.importClause) {
|
if (node.importClause) {
|
||||||
let currentWriterPos = writer.getTextPos();
|
const currentWriterPos = writer.getTextPos();
|
||||||
if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
|
if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) {
|
||||||
writeTextOfNode(currentSourceFile, node.importClause.name);
|
writeTextOfNode(currentText, node.importClause.name);
|
||||||
}
|
}
|
||||||
if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
|
if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) {
|
||||||
if (currentWriterPos !== writer.getTextPos()) {
|
if (currentWriterPos !== writer.getTextPos()) {
|
||||||
|
@ -722,7 +727,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
if (node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
if (node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||||
write("* as ");
|
write("* as ");
|
||||||
writeTextOfNode(currentSourceFile, (<NamespaceImport>node.importClause.namedBindings).name);
|
writeTextOfNode(currentText, (<NamespaceImport>node.importClause.namedBindings).name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
write("{ ");
|
write("{ ");
|
||||||
|
@ -748,22 +753,22 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeTextOfNode(currentSourceFile, moduleSpecifier);
|
writeTextOfNode(currentText, moduleSpecifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) {
|
function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) {
|
||||||
if (node.propertyName) {
|
if (node.propertyName) {
|
||||||
writeTextOfNode(currentSourceFile, node.propertyName);
|
writeTextOfNode(currentText, node.propertyName);
|
||||||
write(" as ");
|
write(" as ");
|
||||||
}
|
}
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitExportSpecifier(node: ExportSpecifier) {
|
function emitExportSpecifier(node: ExportSpecifier) {
|
||||||
emitImportOrExportSpecifier(node);
|
emitImportOrExportSpecifier(node);
|
||||||
|
|
||||||
// Make all the declarations visible for the export name
|
// Make all the declarations visible for the export name
|
||||||
let nodes = resolver.collectLinkedAliases(node.propertyName || node.name);
|
const nodes = resolver.collectLinkedAliases(node.propertyName || node.name);
|
||||||
|
|
||||||
// write each of these declarations asynchronously
|
// write each of these declarations asynchronously
|
||||||
writeAsynchronousModuleElements(nodes);
|
writeAsynchronousModuleElements(nodes);
|
||||||
|
@ -797,13 +802,13 @@ namespace ts {
|
||||||
else {
|
else {
|
||||||
write("module ");
|
write("module ");
|
||||||
}
|
}
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
while (node.body.kind !== SyntaxKind.ModuleBlock) {
|
while (node.body.kind !== SyntaxKind.ModuleBlock) {
|
||||||
node = <ModuleDeclaration>node.body;
|
node = <ModuleDeclaration>node.body;
|
||||||
write(".");
|
write(".");
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
}
|
}
|
||||||
let prevEnclosingDeclaration = enclosingDeclaration;
|
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||||
enclosingDeclaration = node;
|
enclosingDeclaration = node;
|
||||||
write(" {");
|
write(" {");
|
||||||
writeLine();
|
writeLine();
|
||||||
|
@ -816,12 +821,12 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTypeAliasDeclaration(node: TypeAliasDeclaration) {
|
function writeTypeAliasDeclaration(node: TypeAliasDeclaration) {
|
||||||
let prevEnclosingDeclaration = enclosingDeclaration;
|
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||||
enclosingDeclaration = node;
|
enclosingDeclaration = node;
|
||||||
emitJsDocComments(node);
|
emitJsDocComments(node);
|
||||||
emitModuleElementDeclarationFlags(node);
|
emitModuleElementDeclarationFlags(node);
|
||||||
write("type ");
|
write("type ");
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
emitTypeParameters(node.typeParameters);
|
emitTypeParameters(node.typeParameters);
|
||||||
write(" = ");
|
write(" = ");
|
||||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
|
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
|
||||||
|
@ -845,7 +850,7 @@ namespace ts {
|
||||||
write("const ");
|
write("const ");
|
||||||
}
|
}
|
||||||
write("enum ");
|
write("enum ");
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
write(" {");
|
write(" {");
|
||||||
writeLine();
|
writeLine();
|
||||||
increaseIndent();
|
increaseIndent();
|
||||||
|
@ -857,8 +862,8 @@ namespace ts {
|
||||||
|
|
||||||
function emitEnumMemberDeclaration(node: EnumMember) {
|
function emitEnumMemberDeclaration(node: EnumMember) {
|
||||||
emitJsDocComments(node);
|
emitJsDocComments(node);
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
let enumMemberValue = resolver.getConstantValue(node);
|
const enumMemberValue = resolver.getConstantValue(node);
|
||||||
if (enumMemberValue !== undefined) {
|
if (enumMemberValue !== undefined) {
|
||||||
write(" = ");
|
write(" = ");
|
||||||
write(enumMemberValue.toString());
|
write(enumMemberValue.toString());
|
||||||
|
@ -876,7 +881,7 @@ namespace ts {
|
||||||
increaseIndent();
|
increaseIndent();
|
||||||
emitJsDocComments(node);
|
emitJsDocComments(node);
|
||||||
decreaseIndent();
|
decreaseIndent();
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
// If there is constraint present and this is not a type parameter of the private method emit the constraint
|
// If there is constraint present and this is not a type parameter of the private method emit the constraint
|
||||||
if (node.constraint && !isPrivateMethodTypeParameter(node)) {
|
if (node.constraint && !isPrivateMethodTypeParameter(node)) {
|
||||||
write(" extends ");
|
write(" extends ");
|
||||||
|
@ -1007,11 +1012,11 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
write("class ");
|
write("class ");
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
let prevEnclosingDeclaration = enclosingDeclaration;
|
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||||
enclosingDeclaration = node;
|
enclosingDeclaration = node;
|
||||||
emitTypeParameters(node.typeParameters);
|
emitTypeParameters(node.typeParameters);
|
||||||
let baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||||
if (baseTypeNode) {
|
if (baseTypeNode) {
|
||||||
emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
|
emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
|
||||||
}
|
}
|
||||||
|
@ -1031,8 +1036,8 @@ namespace ts {
|
||||||
emitJsDocComments(node);
|
emitJsDocComments(node);
|
||||||
emitModuleElementDeclarationFlags(node);
|
emitModuleElementDeclarationFlags(node);
|
||||||
write("interface ");
|
write("interface ");
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
let prevEnclosingDeclaration = enclosingDeclaration;
|
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||||
enclosingDeclaration = node;
|
enclosingDeclaration = node;
|
||||||
emitTypeParameters(node.typeParameters);
|
emitTypeParameters(node.typeParameters);
|
||||||
emitHeritageClause(getInterfaceBaseTypeNodes(node), /*isImplementsList*/ false);
|
emitHeritageClause(getInterfaceBaseTypeNodes(node), /*isImplementsList*/ false);
|
||||||
|
@ -1069,7 +1074,7 @@ namespace ts {
|
||||||
// If this node is a computed name, it can only be a symbol, because we've already skipped
|
// If this node is a computed name, it can only be a symbol, because we've already skipped
|
||||||
// it if it's not a well known symbol. In that case, the text of the name will be exactly
|
// it if it's not a well known symbol. In that case, the text of the name will be exactly
|
||||||
// what we want, namely the name expression enclosed in brackets.
|
// what we want, namely the name expression enclosed in brackets.
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
// If optional property emit ?
|
// If optional property emit ?
|
||||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) {
|
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) {
|
||||||
write("?");
|
write("?");
|
||||||
|
@ -1118,7 +1123,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVariableDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
function getVariableDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||||
let diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
const diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||||
return diagnosticMessage !== undefined ? {
|
return diagnosticMessage !== undefined ? {
|
||||||
diagnosticMessage,
|
diagnosticMessage,
|
||||||
errorNode: node,
|
errorNode: node,
|
||||||
|
@ -1132,8 +1137,8 @@ namespace ts {
|
||||||
// For example:
|
// For example:
|
||||||
// original: var [, c,,] = [ 2,3,4]
|
// original: var [, c,,] = [ 2,3,4]
|
||||||
// emitted: declare var c: number; // instead of declare var c:number, ;
|
// emitted: declare var c: number; // instead of declare var c:number, ;
|
||||||
let elements: Node[] = [];
|
const elements: Node[] = [];
|
||||||
for (let element of bindingPattern.elements) {
|
for (const element of bindingPattern.elements) {
|
||||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||||
elements.push(element);
|
elements.push(element);
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1148,7 @@ namespace ts {
|
||||||
|
|
||||||
function emitBindingElement(bindingElement: BindingElement) {
|
function emitBindingElement(bindingElement: BindingElement) {
|
||||||
function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||||
let diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
const diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||||
return diagnosticMessage !== undefined ? {
|
return diagnosticMessage !== undefined ? {
|
||||||
diagnosticMessage,
|
diagnosticMessage,
|
||||||
errorNode: bindingElement,
|
errorNode: bindingElement,
|
||||||
|
@ -1156,7 +1161,7 @@ namespace ts {
|
||||||
emitBindingPattern(<BindingPattern>bindingElement.name);
|
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
writeTextOfNode(currentSourceFile, bindingElement.name);
|
writeTextOfNode(currentText, bindingElement.name);
|
||||||
writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError);
|
writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1199,20 +1204,20 @@ namespace ts {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let accessors = getAllAccessorDeclarations((<ClassDeclaration>node.parent).members, node);
|
const accessors = getAllAccessorDeclarations((<ClassDeclaration>node.parent).members, node);
|
||||||
let accessorWithTypeAnnotation: AccessorDeclaration;
|
let accessorWithTypeAnnotation: AccessorDeclaration;
|
||||||
|
|
||||||
if (node === accessors.firstAccessor) {
|
if (node === accessors.firstAccessor) {
|
||||||
emitJsDocComments(accessors.getAccessor);
|
emitJsDocComments(accessors.getAccessor);
|
||||||
emitJsDocComments(accessors.setAccessor);
|
emitJsDocComments(accessors.setAccessor);
|
||||||
emitClassMemberDeclarationFlags(node);
|
emitClassMemberDeclarationFlags(node);
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
if (!(node.flags & NodeFlags.Private)) {
|
if (!(node.flags & NodeFlags.Private)) {
|
||||||
accessorWithTypeAnnotation = node;
|
accessorWithTypeAnnotation = node;
|
||||||
let type = getTypeAnnotationFromAccessor(node);
|
let type = getTypeAnnotationFromAccessor(node);
|
||||||
if (!type) {
|
if (!type) {
|
||||||
// couldn't get type for the first accessor, try the another one
|
// couldn't get type for the first accessor, try the another one
|
||||||
let anotherAccessor = node.kind === SyntaxKind.GetAccessor ? accessors.setAccessor : accessors.getAccessor;
|
const anotherAccessor = node.kind === SyntaxKind.GetAccessor ? accessors.setAccessor : accessors.getAccessor;
|
||||||
type = getTypeAnnotationFromAccessor(anotherAccessor);
|
type = getTypeAnnotationFromAccessor(anotherAccessor);
|
||||||
if (type) {
|
if (type) {
|
||||||
accessorWithTypeAnnotation = anotherAccessor;
|
accessorWithTypeAnnotation = anotherAccessor;
|
||||||
|
@ -1296,13 +1301,13 @@ namespace ts {
|
||||||
}
|
}
|
||||||
if (node.kind === SyntaxKind.FunctionDeclaration) {
|
if (node.kind === SyntaxKind.FunctionDeclaration) {
|
||||||
write("function ");
|
write("function ");
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
}
|
}
|
||||||
else if (node.kind === SyntaxKind.Constructor) {
|
else if (node.kind === SyntaxKind.Constructor) {
|
||||||
write("constructor");
|
write("constructor");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
if (hasQuestionToken(node)) {
|
if (hasQuestionToken(node)) {
|
||||||
write("?");
|
write("?");
|
||||||
}
|
}
|
||||||
|
@ -1329,7 +1334,7 @@ namespace ts {
|
||||||
write("(");
|
write("(");
|
||||||
}
|
}
|
||||||
|
|
||||||
let prevEnclosingDeclaration = enclosingDeclaration;
|
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||||
enclosingDeclaration = node;
|
enclosingDeclaration = node;
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
|
@ -1343,7 +1348,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is not a constructor and is not private, emit the return type
|
// If this is not a constructor and is not private, emit the return type
|
||||||
let isFunctionTypeOrConstructorType = node.kind === SyntaxKind.FunctionType || node.kind === SyntaxKind.ConstructorType;
|
const isFunctionTypeOrConstructorType = node.kind === SyntaxKind.FunctionType || node.kind === SyntaxKind.ConstructorType;
|
||||||
if (isFunctionTypeOrConstructorType || node.parent.kind === SyntaxKind.TypeLiteral) {
|
if (isFunctionTypeOrConstructorType || node.parent.kind === SyntaxKind.TypeLiteral) {
|
||||||
// Emit type literal signature return type only if specified
|
// Emit type literal signature return type only if specified
|
||||||
if (node.type) {
|
if (node.type) {
|
||||||
|
@ -1442,7 +1447,7 @@ namespace ts {
|
||||||
emitBindingPattern(<BindingPattern>node.name);
|
emitBindingPattern(<BindingPattern>node.name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentText, node.name);
|
||||||
}
|
}
|
||||||
if (resolver.isOptionalParameter(node)) {
|
if (resolver.isOptionalParameter(node)) {
|
||||||
write("?");
|
write("?");
|
||||||
|
@ -1459,7 +1464,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getParameterDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
function getParameterDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||||
let diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
const diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||||
return diagnosticMessage !== undefined ? {
|
return diagnosticMessage !== undefined ? {
|
||||||
diagnosticMessage,
|
diagnosticMessage,
|
||||||
errorNode: node,
|
errorNode: node,
|
||||||
|
@ -1532,7 +1537,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) {
|
else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) {
|
||||||
write("[");
|
write("[");
|
||||||
let elements = bindingPattern.elements;
|
const elements = bindingPattern.elements;
|
||||||
emitCommaList(elements, emitBindingElement);
|
emitCommaList(elements, emitBindingElement);
|
||||||
if (elements && elements.hasTrailingComma) {
|
if (elements && elements.hasTrailingComma) {
|
||||||
write(", ");
|
write(", ");
|
||||||
|
@ -1543,7 +1548,7 @@ namespace ts {
|
||||||
|
|
||||||
function emitBindingElement(bindingElement: BindingElement) {
|
function emitBindingElement(bindingElement: BindingElement) {
|
||||||
function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||||
let diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
const diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||||
return diagnosticMessage !== undefined ? {
|
return diagnosticMessage !== undefined ? {
|
||||||
diagnosticMessage,
|
diagnosticMessage,
|
||||||
errorNode: bindingElement,
|
errorNode: bindingElement,
|
||||||
|
@ -1568,7 +1573,7 @@ namespace ts {
|
||||||
// Example:
|
// Example:
|
||||||
// original: function foo({y: [a,b,c]}) {}
|
// original: function foo({y: [a,b,c]}) {}
|
||||||
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
|
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
|
||||||
writeTextOfNode(currentSourceFile, bindingElement.propertyName);
|
writeTextOfNode(currentText, bindingElement.propertyName);
|
||||||
write(": ");
|
write(": ");
|
||||||
}
|
}
|
||||||
if (bindingElement.name) {
|
if (bindingElement.name) {
|
||||||
|
@ -1591,7 +1596,7 @@ namespace ts {
|
||||||
if (bindingElement.dotDotDotToken) {
|
if (bindingElement.dotDotDotToken) {
|
||||||
write("...");
|
write("...");
|
||||||
}
|
}
|
||||||
writeTextOfNode(currentSourceFile, bindingElement.name);
|
writeTextOfNode(currentText, bindingElement.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1658,11 +1663,11 @@ namespace ts {
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
export function writeDeclarationFile(jsFilePath: string, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[]) {
|
export function writeDeclarationFile(jsFilePath: string, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[]) {
|
||||||
let emitDeclarationResult = emitDeclarations(host, resolver, diagnostics, jsFilePath, sourceFile);
|
const emitDeclarationResult = emitDeclarations(host, resolver, diagnostics, jsFilePath, sourceFile);
|
||||||
// TODO(shkamat): Should we not write any declaration file if any of them can produce error,
|
// TODO(shkamat): Should we not write any declaration file if any of them can produce error,
|
||||||
// or should we just not write this file like we are doing now
|
// or should we just not write this file like we are doing now
|
||||||
if (!emitDeclarationResult.reportedDeclarationError) {
|
if (!emitDeclarationResult.reportedDeclarationError) {
|
||||||
let declarationOutput = emitDeclarationResult.referencePathsOutput
|
const declarationOutput = emitDeclarationResult.referencePathsOutput
|
||||||
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
|
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
|
||||||
writeFile(host, diagnostics, removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, host.getCompilerOptions().emitBOM);
|
writeFile(host, diagnostics, removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, host.getCompilerOptions().emitBOM);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@ namespace ts {
|
||||||
|
|
||||||
/** The version of the TypeScript compiler release */
|
/** The version of the TypeScript compiler release */
|
||||||
|
|
||||||
let emptyArray: any[] = [];
|
const emptyArray: any[] = [];
|
||||||
|
|
||||||
export const version = "1.8.0";
|
export const version = "1.8.0";
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace ts {
|
||||||
if (sys.fileExists(fileName)) {
|
if (sys.fileExists(fileName)) {
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
let parentPath = getDirectoryPath(searchPath);
|
const parentPath = getDirectoryPath(searchPath);
|
||||||
if (parentPath === searchPath) {
|
if (parentPath === searchPath) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,13 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveTripleslashReference(moduleName: string, containingFile: string): string {
|
export function resolveTripleslashReference(moduleName: string, containingFile: string): string {
|
||||||
let basePath = getDirectoryPath(containingFile);
|
const basePath = getDirectoryPath(containingFile);
|
||||||
let referencedFileName = isRootedDiskPath(moduleName) ? moduleName : combinePaths(basePath, moduleName);
|
const referencedFileName = isRootedDiskPath(moduleName) ? moduleName : combinePaths(basePath, moduleName);
|
||||||
return normalizePath(referencedFileName);
|
return normalizePath(referencedFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||||
let moduleResolution = compilerOptions.moduleResolution !== undefined
|
const moduleResolution = compilerOptions.moduleResolution !== undefined
|
||||||
? compilerOptions.moduleResolution
|
? compilerOptions.moduleResolution
|
||||||
: compilerOptions.module === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
|
: compilerOptions.module === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
|
||||||
|
|
||||||
|
@ -48,11 +48,11 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
export function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||||
let containingDirectory = getDirectoryPath(containingFile);
|
const containingDirectory = getDirectoryPath(containingFile);
|
||||||
|
|
||||||
if (getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
|
if (getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
|
||||||
let failedLookupLocations: string[] = [];
|
const failedLookupLocations: string[] = [];
|
||||||
let candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||||
let resolvedFileName = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
|
let resolvedFileName = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
|
||||||
|
|
||||||
if (resolvedFileName) {
|
if (resolvedFileName) {
|
||||||
|
@ -73,7 +73,7 @@ namespace ts {
|
||||||
return forEach(moduleFileExtensions, tryLoad);
|
return forEach(moduleFileExtensions, tryLoad);
|
||||||
|
|
||||||
function tryLoad(ext: string): string {
|
function tryLoad(ext: string): string {
|
||||||
let fileName = fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
|
const fileName = fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
|
||||||
if (host.fileExists(fileName)) {
|
if (host.fileExists(fileName)) {
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
@ -85,13 +85,13 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadNodeModuleFromDirectory(candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
|
function loadNodeModuleFromDirectory(candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
|
||||||
let packageJsonPath = combinePaths(candidate, "package.json");
|
const packageJsonPath = combinePaths(candidate, "package.json");
|
||||||
if (host.fileExists(packageJsonPath)) {
|
if (host.fileExists(packageJsonPath)) {
|
||||||
|
|
||||||
let jsonContent: { typings?: string };
|
let jsonContent: { typings?: string };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let jsonText = host.readFile(packageJsonPath);
|
const jsonText = host.readFile(packageJsonPath);
|
||||||
jsonContent = jsonText ? <{ typings?: string }>JSON.parse(jsonText) : { typings: undefined };
|
jsonContent = jsonText ? <{ typings?: string }>JSON.parse(jsonText) : { typings: undefined };
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
|
@ -100,7 +100,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jsonContent.typings) {
|
if (jsonContent.typings) {
|
||||||
let result = loadNodeModuleFromFile(normalizePath(combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
|
const result = loadNodeModuleFromFile(normalizePath(combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -115,13 +115,13 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||||
let failedLookupLocations: string[] = [];
|
const failedLookupLocations: string[] = [];
|
||||||
directory = normalizeSlashes(directory);
|
directory = normalizeSlashes(directory);
|
||||||
while (true) {
|
while (true) {
|
||||||
let baseName = getBaseFileName(directory);
|
const baseName = getBaseFileName(directory);
|
||||||
if (baseName !== "node_modules") {
|
if (baseName !== "node_modules") {
|
||||||
let nodeModulesFolder = combinePaths(directory, "node_modules");
|
const nodeModulesFolder = combinePaths(directory, "node_modules");
|
||||||
let candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
|
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
|
||||||
let result = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
|
let result = loadNodeModuleFromFile(candidate, failedLookupLocations, host);
|
||||||
if (result) {
|
if (result) {
|
||||||
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
|
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
|
||||||
|
@ -133,7 +133,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let parentPath = getDirectoryPath(directory);
|
const parentPath = getDirectoryPath(directory);
|
||||||
if (parentPath === directory) {
|
if (parentPath === directory) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function nameStartsWithDotSlashOrDotDotSlash(name: string) {
|
function nameStartsWithDotSlashOrDotDotSlash(name: string) {
|
||||||
let i = name.lastIndexOf("./", 1);
|
const i = name.lastIndexOf("./", 1);
|
||||||
return i === 0 || (i === 1 && name.charCodeAt(0) === CharacterCodes.dot);
|
return i === 0 || (i === 1 && name.charCodeAt(0) === CharacterCodes.dot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ namespace ts {
|
||||||
let searchPath = getDirectoryPath(containingFile);
|
let searchPath = getDirectoryPath(containingFile);
|
||||||
let searchName: string;
|
let searchName: string;
|
||||||
|
|
||||||
let failedLookupLocations: string[] = [];
|
const failedLookupLocations: string[] = [];
|
||||||
|
|
||||||
let referencedSourceFile: string;
|
let referencedSourceFile: string;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -171,7 +171,7 @@ namespace ts {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let candidate = searchName + extension;
|
const candidate = searchName + extension;
|
||||||
if (host.fileExists(candidate)) {
|
if (host.fileExists(candidate)) {
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ namespace ts {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let parentPath = getDirectoryPath(searchPath);
|
const parentPath = getDirectoryPath(searchPath);
|
||||||
if (parentPath === searchPath) {
|
if (parentPath === searchPath) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -199,15 +199,13 @@ namespace ts {
|
||||||
/* @internal */
|
/* @internal */
|
||||||
export const defaultInitCompilerOptions: CompilerOptions = {
|
export const defaultInitCompilerOptions: CompilerOptions = {
|
||||||
module: ModuleKind.CommonJS,
|
module: ModuleKind.CommonJS,
|
||||||
target: ScriptTarget.ES3,
|
target: ScriptTarget.ES5,
|
||||||
noImplicitAny: false,
|
noImplicitAny: false,
|
||||||
outDir: "built",
|
|
||||||
rootDir: ".",
|
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost {
|
export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost {
|
||||||
let existingDirectories: Map<boolean> = {};
|
const existingDirectories: Map<boolean> = {};
|
||||||
|
|
||||||
function getCanonicalFileName(fileName: string): string {
|
function getCanonicalFileName(fileName: string): string {
|
||||||
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
|
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
|
||||||
|
@ -216,12 +214,12 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// returned by CScript sys environment
|
// returned by CScript sys environment
|
||||||
let unsupportedFileEncodingErrorCode = -2147024809;
|
const unsupportedFileEncodingErrorCode = -2147024809;
|
||||||
|
|
||||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||||
let text: string;
|
let text: string;
|
||||||
try {
|
try {
|
||||||
let start = new Date().getTime();
|
const start = new Date().getTime();
|
||||||
text = sys.readFile(fileName, options.charset);
|
text = sys.readFile(fileName, options.charset);
|
||||||
ioReadTime += new Date().getTime() - start;
|
ioReadTime += new Date().getTime() - start;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +248,7 @@ namespace ts {
|
||||||
|
|
||||||
function ensureDirectoriesExist(directoryPath: string) {
|
function ensureDirectoriesExist(directoryPath: string) {
|
||||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||||
let parentDirectory = getDirectoryPath(directoryPath);
|
const parentDirectory = getDirectoryPath(directoryPath);
|
||||||
ensureDirectoriesExist(parentDirectory);
|
ensureDirectoriesExist(parentDirectory);
|
||||||
sys.createDirectory(directoryPath);
|
sys.createDirectory(directoryPath);
|
||||||
}
|
}
|
||||||
|
@ -258,7 +256,7 @@ namespace ts {
|
||||||
|
|
||||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||||
try {
|
try {
|
||||||
let start = new Date().getTime();
|
const start = new Date().getTime();
|
||||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||||
sys.writeFile(fileName, data, writeByteOrderMark);
|
sys.writeFile(fileName, data, writeByteOrderMark);
|
||||||
ioWriteTime += new Date().getTime() - start;
|
ioWriteTime += new Date().getTime() - start;
|
||||||
|
@ -286,7 +284,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
|
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
|
||||||
let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
const diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||||
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||||
program.getGlobalDiagnostics(cancellationToken),
|
program.getGlobalDiagnostics(cancellationToken),
|
||||||
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
||||||
|
@ -328,7 +326,7 @@ namespace ts {
|
||||||
let program: Program;
|
let program: Program;
|
||||||
let files: SourceFile[] = [];
|
let files: SourceFile[] = [];
|
||||||
let fileProcessingDiagnostics = createDiagnosticCollection();
|
let fileProcessingDiagnostics = createDiagnosticCollection();
|
||||||
let programDiagnostics = createDiagnosticCollection();
|
const programDiagnostics = createDiagnosticCollection();
|
||||||
|
|
||||||
let commonSourceDirectory: string;
|
let commonSourceDirectory: string;
|
||||||
let diagnosticsProducingTypeChecker: TypeChecker;
|
let diagnosticsProducingTypeChecker: TypeChecker;
|
||||||
|
@ -337,7 +335,7 @@ namespace ts {
|
||||||
|
|
||||||
let skipDefaultLib = options.noLib;
|
let skipDefaultLib = options.noLib;
|
||||||
|
|
||||||
let start = new Date().getTime();
|
const start = new Date().getTime();
|
||||||
|
|
||||||
host = host || createCompilerHost(options);
|
host = host || createCompilerHost(options);
|
||||||
|
|
||||||
|
@ -346,15 +344,15 @@ namespace ts {
|
||||||
? ((moduleNames: string[], containingFile: string) => host.resolveModuleNames(moduleNames, containingFile))
|
? ((moduleNames: string[], containingFile: string) => host.resolveModuleNames(moduleNames, containingFile))
|
||||||
: ((moduleNames: string[], containingFile: string) => map(moduleNames, moduleName => resolveModuleName(moduleName, containingFile, options, host).resolvedModule));
|
: ((moduleNames: string[], containingFile: string) => map(moduleNames, moduleName => resolveModuleName(moduleName, containingFile, options, host).resolvedModule));
|
||||||
|
|
||||||
let filesByName = createFileMap<SourceFile>();
|
const filesByName = createFileMap<SourceFile>();
|
||||||
// stores 'filename -> file association' ignoring case
|
// stores 'filename -> file association' ignoring case
|
||||||
// used to track cases when two file names differ only in casing
|
// used to track cases when two file names differ only in casing
|
||||||
let filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createFileMap<SourceFile>(fileName => fileName.toLowerCase()) : undefined;
|
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createFileMap<SourceFile>(fileName => fileName.toLowerCase()) : undefined;
|
||||||
|
|
||||||
if (oldProgram) {
|
if (oldProgram) {
|
||||||
// check properties that can affect structure of the program or module resolution strategy
|
// check properties that can affect structure of the program or module resolution strategy
|
||||||
// if any of these properties has changed - structure cannot be reused
|
// if any of these properties has changed - structure cannot be reused
|
||||||
let oldOptions = oldProgram.getCompilerOptions();
|
const oldOptions = oldProgram.getCompilerOptions();
|
||||||
if ((oldOptions.module !== options.module) ||
|
if ((oldOptions.module !== options.module) ||
|
||||||
(oldOptions.noResolve !== options.noResolve) ||
|
(oldOptions.noResolve !== options.noResolve) ||
|
||||||
(oldOptions.target !== options.target) ||
|
(oldOptions.target !== options.target) ||
|
||||||
|
@ -412,7 +410,7 @@ namespace ts {
|
||||||
getTypeChecker();
|
getTypeChecker();
|
||||||
classifiableNames = {};
|
classifiableNames = {};
|
||||||
|
|
||||||
for (let sourceFile of files) {
|
for (const sourceFile of files) {
|
||||||
copyMap(sourceFile.classifiableNames, classifiableNames);
|
copyMap(sourceFile.classifiableNames, classifiableNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,17 +426,17 @@ namespace ts {
|
||||||
Debug.assert(!oldProgram.structureIsReused);
|
Debug.assert(!oldProgram.structureIsReused);
|
||||||
|
|
||||||
// there is an old program, check if we can reuse its structure
|
// there is an old program, check if we can reuse its structure
|
||||||
let oldRootNames = oldProgram.getRootFileNames();
|
const oldRootNames = oldProgram.getRootFileNames();
|
||||||
if (!arrayIsEqualTo(oldRootNames, rootNames)) {
|
if (!arrayIsEqualTo(oldRootNames, rootNames)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if program source files has changed in the way that can affect structure of the program
|
// check if program source files has changed in the way that can affect structure of the program
|
||||||
let newSourceFiles: SourceFile[] = [];
|
const newSourceFiles: SourceFile[] = [];
|
||||||
let filePaths: Path[] = [];
|
const filePaths: Path[] = [];
|
||||||
let modifiedSourceFiles: SourceFile[] = [];
|
const modifiedSourceFiles: SourceFile[] = [];
|
||||||
|
|
||||||
for (let oldSourceFile of oldProgram.getSourceFiles()) {
|
for (const oldSourceFile of oldProgram.getSourceFiles()) {
|
||||||
let newSourceFile = host.getSourceFile(oldSourceFile.fileName, options.target);
|
let newSourceFile = host.getSourceFile(oldSourceFile.fileName, options.target);
|
||||||
if (!newSourceFile) {
|
if (!newSourceFile) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -468,13 +466,13 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolveModuleNamesWorker) {
|
if (resolveModuleNamesWorker) {
|
||||||
let moduleNames = map(newSourceFile.imports, name => name.text);
|
const moduleNames = map(newSourceFile.imports, name => name.text);
|
||||||
let resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory));
|
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory));
|
||||||
// ensure that module resolution results are still correct
|
// ensure that module resolution results are still correct
|
||||||
for (let i = 0; i < moduleNames.length; ++i) {
|
for (let i = 0; i < moduleNames.length; ++i) {
|
||||||
let newResolution = resolutions[i];
|
const newResolution = resolutions[i];
|
||||||
let oldResolution = getResolvedModule(oldSourceFile, moduleNames[i]);
|
const oldResolution = getResolvedModule(oldSourceFile, moduleNames[i]);
|
||||||
let resolutionChanged = oldResolution
|
const resolutionChanged = oldResolution
|
||||||
? !newResolution ||
|
? !newResolution ||
|
||||||
oldResolution.resolvedFileName !== newResolution.resolvedFileName ||
|
oldResolution.resolvedFileName !== newResolution.resolvedFileName ||
|
||||||
!!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport
|
!!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport
|
||||||
|
@ -506,7 +504,7 @@ namespace ts {
|
||||||
files = newSourceFiles;
|
files = newSourceFiles;
|
||||||
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
|
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
|
||||||
|
|
||||||
for (let modifiedFile of modifiedSourceFiles) {
|
for (const modifiedFile of modifiedSourceFiles) {
|
||||||
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile);
|
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile);
|
||||||
}
|
}
|
||||||
oldProgram.structureIsReused = true;
|
oldProgram.structureIsReused = true;
|
||||||
|
@ -556,11 +554,11 @@ namespace ts {
|
||||||
// This is because in the -out scenario all files need to be emitted, and therefore all
|
// This is because in the -out scenario all files need to be emitted, and therefore all
|
||||||
// files need to be type checked. And the way to specify that all files need to be type
|
// files need to be type checked. And the way to specify that all files need to be type
|
||||||
// checked is to not pass the file to getEmitResolver.
|
// checked is to not pass the file to getEmitResolver.
|
||||||
let emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
|
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
|
||||||
|
|
||||||
let start = new Date().getTime();
|
const start = new Date().getTime();
|
||||||
|
|
||||||
let emitResult = emitFiles(
|
const emitResult = emitFiles(
|
||||||
emitResolver,
|
emitResolver,
|
||||||
getEmitHost(writeFileCallback),
|
getEmitHost(writeFileCallback),
|
||||||
sourceFile);
|
sourceFile);
|
||||||
|
@ -581,7 +579,7 @@ namespace ts {
|
||||||
return getDiagnostics(sourceFile, cancellationToken);
|
return getDiagnostics(sourceFile, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
let allDiagnostics: Diagnostic[] = [];
|
const allDiagnostics: Diagnostic[] = [];
|
||||||
forEach(program.getSourceFiles(), sourceFile => {
|
forEach(program.getSourceFiles(), sourceFile => {
|
||||||
if (cancellationToken) {
|
if (cancellationToken) {
|
||||||
cancellationToken.throwIfCancellationRequested();
|
cancellationToken.throwIfCancellationRequested();
|
||||||
|
@ -633,13 +631,13 @@ namespace ts {
|
||||||
|
|
||||||
function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||||
return runWithCancellationToken(() => {
|
return runWithCancellationToken(() => {
|
||||||
let typeChecker = getDiagnosticsProducingTypeChecker();
|
const typeChecker = getDiagnosticsProducingTypeChecker();
|
||||||
|
|
||||||
Debug.assert(!!sourceFile.bindDiagnostics);
|
Debug.assert(!!sourceFile.bindDiagnostics);
|
||||||
let bindDiagnostics = sourceFile.bindDiagnostics;
|
const bindDiagnostics = sourceFile.bindDiagnostics;
|
||||||
let checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
const checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||||
let fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||||
let programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||||
|
|
||||||
return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile);
|
return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile);
|
||||||
});
|
});
|
||||||
|
@ -648,23 +646,23 @@ namespace ts {
|
||||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||||
return runWithCancellationToken(() => {
|
return runWithCancellationToken(() => {
|
||||||
if (!isDeclarationFile(sourceFile)) {
|
if (!isDeclarationFile(sourceFile)) {
|
||||||
let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
|
const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
|
||||||
// Don't actually write any files since we're just getting diagnostics.
|
// Don't actually write any files since we're just getting diagnostics.
|
||||||
let writeFile: WriteFileCallback = () => { };
|
const writeFile: WriteFileCallback = () => { };
|
||||||
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
|
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOptionsDiagnostics(): Diagnostic[] {
|
function getOptionsDiagnostics(): Diagnostic[] {
|
||||||
let allDiagnostics: Diagnostic[] = [];
|
const allDiagnostics: Diagnostic[] = [];
|
||||||
addRange(allDiagnostics, fileProcessingDiagnostics.getGlobalDiagnostics());
|
addRange(allDiagnostics, fileProcessingDiagnostics.getGlobalDiagnostics());
|
||||||
addRange(allDiagnostics, programDiagnostics.getGlobalDiagnostics());
|
addRange(allDiagnostics, programDiagnostics.getGlobalDiagnostics());
|
||||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGlobalDiagnostics(): Diagnostic[] {
|
function getGlobalDiagnostics(): Diagnostic[] {
|
||||||
let allDiagnostics: Diagnostic[] = [];
|
const allDiagnostics: Diagnostic[] = [];
|
||||||
addRange(allDiagnostics, getDiagnosticsProducingTypeChecker().getGlobalDiagnostics());
|
addRange(allDiagnostics, getDiagnosticsProducingTypeChecker().getGlobalDiagnostics());
|
||||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||||
}
|
}
|
||||||
|
@ -691,7 +689,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
let imports: LiteralExpression[];
|
let imports: LiteralExpression[];
|
||||||
for (let node of file.statements) {
|
for (const node of file.statements) {
|
||||||
collect(node, /* allowRelativeModuleNames */ true);
|
collect(node, /* allowRelativeModuleNames */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,7 +749,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd);
|
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd);
|
||||||
if (!nonTsFile) {
|
if (!nonTsFile) {
|
||||||
if (options.allowNonTsExtensions) {
|
if (options.allowNonTsExtensions) {
|
||||||
diagnostic = Diagnostics.File_0_not_found;
|
diagnostic = Diagnostics.File_0_not_found;
|
||||||
|
@ -799,7 +797,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We haven't looked for this file, do so now and cache result
|
// We haven't looked for this file, do so now and cache result
|
||||||
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
|
const file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
|
||||||
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
|
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
|
||||||
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
|
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
|
||||||
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
|
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
|
||||||
|
@ -826,7 +824,7 @@ namespace ts {
|
||||||
|
|
||||||
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
|
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
|
||||||
|
|
||||||
let basePath = getDirectoryPath(fileName);
|
const basePath = getDirectoryPath(fileName);
|
||||||
if (!options.noResolve) {
|
if (!options.noResolve) {
|
||||||
processReferencedFiles(file, basePath);
|
processReferencedFiles(file, basePath);
|
||||||
}
|
}
|
||||||
|
@ -848,7 +846,7 @@ namespace ts {
|
||||||
|
|
||||||
function processReferencedFiles(file: SourceFile, basePath: string) {
|
function processReferencedFiles(file: SourceFile, basePath: string) {
|
||||||
forEach(file.referencedFiles, ref => {
|
forEach(file.referencedFiles, ref => {
|
||||||
let referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -861,21 +859,21 @@ namespace ts {
|
||||||
collectExternalModuleReferences(file);
|
collectExternalModuleReferences(file);
|
||||||
if (file.imports.length) {
|
if (file.imports.length) {
|
||||||
file.resolvedModules = {};
|
file.resolvedModules = {};
|
||||||
let moduleNames = map(file.imports, name => name.text);
|
const moduleNames = map(file.imports, name => name.text);
|
||||||
let resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
|
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
|
||||||
for (let i = 0; i < file.imports.length; ++i) {
|
for (let i = 0; i < file.imports.length; ++i) {
|
||||||
let resolution = resolutions[i];
|
const resolution = resolutions[i];
|
||||||
setResolvedModule(file, moduleNames[i], resolution);
|
setResolvedModule(file, moduleNames[i], resolution);
|
||||||
if (resolution && !options.noResolve) {
|
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 (importedFile && resolution.isExternalLibraryImport) {
|
||||||
if (!isExternalModule(importedFile)) {
|
if (!isExternalModule(importedFile)) {
|
||||||
let start = getTokenPosOfNode(file.imports[i], file);
|
const start = getTokenPosOfNode(file.imports[i], file);
|
||||||
fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName));
|
fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName));
|
||||||
}
|
}
|
||||||
else if (importedFile.referencedFiles.length) {
|
else if (importedFile.referencedFiles.length) {
|
||||||
let firstRef = importedFile.referencedFiles[0];
|
const firstRef = importedFile.referencedFiles[0];
|
||||||
fileProcessingDiagnostics.add(createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition));
|
fileProcessingDiagnostics.add(createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -897,7 +895,7 @@ namespace ts {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sourcePathComponents = getNormalizedPathComponents(sourceFile.fileName, currentDirectory);
|
const sourcePathComponents = getNormalizedPathComponents(sourceFile.fileName, currentDirectory);
|
||||||
sourcePathComponents.pop(); // The base file name is not part of the common directory path
|
sourcePathComponents.pop(); // The base file name is not part of the common directory path
|
||||||
|
|
||||||
if (!commonPathComponents) {
|
if (!commonPathComponents) {
|
||||||
|
@ -935,11 +933,11 @@ namespace ts {
|
||||||
function checkSourceFilesBelongToPath(sourceFiles: SourceFile[], rootDirectory: string): boolean {
|
function checkSourceFilesBelongToPath(sourceFiles: SourceFile[], rootDirectory: string): boolean {
|
||||||
let allFilesBelongToPath = true;
|
let allFilesBelongToPath = true;
|
||||||
if (sourceFiles) {
|
if (sourceFiles) {
|
||||||
let absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
|
const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
|
||||||
|
|
||||||
for (var sourceFile of sourceFiles) {
|
for (var sourceFile of sourceFiles) {
|
||||||
if (!isDeclarationFile(sourceFile)) {
|
if (!isDeclarationFile(sourceFile)) {
|
||||||
let absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
|
const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
|
||||||
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
|
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
|
||||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
|
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
|
||||||
allFilesBelongToPath = false;
|
allFilesBelongToPath = false;
|
||||||
|
@ -1004,24 +1002,24 @@ namespace ts {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let languageVersion = options.target || ScriptTarget.ES3;
|
const languageVersion = options.target || ScriptTarget.ES3;
|
||||||
let outFile = options.outFile || options.out;
|
const outFile = options.outFile || options.out;
|
||||||
|
|
||||||
let firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined);
|
const firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined);
|
||||||
if (options.isolatedModules) {
|
if (options.isolatedModules) {
|
||||||
if (!options.module && languageVersion < ScriptTarget.ES6) {
|
if (!options.module && languageVersion < ScriptTarget.ES6) {
|
||||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher));
|
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher));
|
||||||
}
|
}
|
||||||
|
|
||||||
let firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !isDeclarationFile(f) ? f : undefined);
|
const firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !isDeclarationFile(f) ? f : undefined);
|
||||||
if (firstNonExternalModuleSourceFile) {
|
if (firstNonExternalModuleSourceFile) {
|
||||||
let span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
|
const span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
|
||||||
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
|
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (firstExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && !options.module) {
|
else if (firstExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && !options.module) {
|
||||||
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
||||||
let span = getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
|
const span = getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
|
||||||
programDiagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided));
|
programDiagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -51,15 +51,15 @@ namespace ts {
|
||||||
|
|
||||||
function getWScriptSystem(): System {
|
function getWScriptSystem(): System {
|
||||||
|
|
||||||
let fso = new ActiveXObject("Scripting.FileSystemObject");
|
const fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||||
|
|
||||||
let fileStream = new ActiveXObject("ADODB.Stream");
|
const fileStream = new ActiveXObject("ADODB.Stream");
|
||||||
fileStream.Type = 2 /*text*/;
|
fileStream.Type = 2 /*text*/;
|
||||||
|
|
||||||
let binaryStream = new ActiveXObject("ADODB.Stream");
|
const binaryStream = new ActiveXObject("ADODB.Stream");
|
||||||
binaryStream.Type = 1 /*binary*/;
|
binaryStream.Type = 1 /*binary*/;
|
||||||
|
|
||||||
let args: string[] = [];
|
const args: string[] = [];
|
||||||
for (let i = 0; i < WScript.Arguments.length; i++) {
|
for (let i = 0; i < WScript.Arguments.length; i++) {
|
||||||
args[i] = WScript.Arguments.Item(i);
|
args[i] = WScript.Arguments.Item(i);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ namespace ts {
|
||||||
// Load file and read the first two bytes into a string with no interpretation
|
// Load file and read the first two bytes into a string with no interpretation
|
||||||
fileStream.Charset = "x-ansi";
|
fileStream.Charset = "x-ansi";
|
||||||
fileStream.LoadFromFile(fileName);
|
fileStream.LoadFromFile(fileName);
|
||||||
let bom = fileStream.ReadText(2) || "";
|
const bom = fileStream.ReadText(2) || "";
|
||||||
// Position must be at 0 before encoding can be changed
|
// Position must be at 0 before encoding can be changed
|
||||||
fileStream.Position = 0;
|
fileStream.Position = 0;
|
||||||
// [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8
|
// [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8
|
||||||
|
@ -124,7 +124,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNames(collection: any): string[] {
|
function getNames(collection: any): string[] {
|
||||||
let result: string[] = [];
|
const result: string[] = [];
|
||||||
for (let e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
|
for (let e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
|
||||||
result.push(e.item().Name);
|
result.push(e.item().Name);
|
||||||
}
|
}
|
||||||
|
@ -132,22 +132,22 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function readDirectory(path: string, extension?: string, exclude?: string[]): string[] {
|
function readDirectory(path: string, extension?: string, exclude?: string[]): string[] {
|
||||||
let result: string[] = [];
|
const result: string[] = [];
|
||||||
exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s)));
|
exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s)));
|
||||||
visitDirectory(path);
|
visitDirectory(path);
|
||||||
return result;
|
return result;
|
||||||
function visitDirectory(path: string) {
|
function visitDirectory(path: string) {
|
||||||
let folder = fso.GetFolder(path || ".");
|
const folder = fso.GetFolder(path || ".");
|
||||||
let files = getNames(folder.files);
|
const files = getNames(folder.files);
|
||||||
for (let current of files) {
|
for (const current of files) {
|
||||||
let name = combinePaths(path, current);
|
const name = combinePaths(path, current);
|
||||||
if ((!extension || fileExtensionIs(name, extension)) && !contains(exclude, getCanonicalPath(name))) {
|
if ((!extension || fileExtensionIs(name, extension)) && !contains(exclude, getCanonicalPath(name))) {
|
||||||
result.push(name);
|
result.push(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let subfolders = getNames(folder.subfolders);
|
const subfolders = getNames(folder.subfolders);
|
||||||
for (let current of subfolders) {
|
for (const current of subfolders) {
|
||||||
let name = combinePaths(path, current);
|
const name = combinePaths(path, current);
|
||||||
if (!contains(exclude, getCanonicalPath(name))) {
|
if (!contains(exclude, getCanonicalPath(name))) {
|
||||||
visitDirectory(name);
|
visitDirectory(name);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function poll(checkedIndex: number) {
|
function poll(checkedIndex: number) {
|
||||||
let watchedFile = watchedFiles[checkedIndex];
|
const watchedFile = watchedFiles[checkedIndex];
|
||||||
if (!watchedFile) {
|
if (!watchedFile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addFile(fileName: string, callback: (fileName: string, removed?: boolean) => void): WatchedFile {
|
function addFile(fileName: string, callback: (fileName: string, removed?: boolean) => void): WatchedFile {
|
||||||
let file: WatchedFile = {
|
const file: WatchedFile = {
|
||||||
fileName,
|
fileName,
|
||||||
callback,
|
callback,
|
||||||
mtime: getModifiedTime(fileName)
|
mtime: getModifiedTime(fileName)
|
||||||
|
@ -291,7 +291,7 @@ namespace ts {
|
||||||
// changes for large reference sets? If so, do we want
|
// changes for large reference sets? If so, do we want
|
||||||
// to increase the chunk size or decrease the interval
|
// to increase the chunk size or decrease the interval
|
||||||
// time dynamically to match the large reference set?
|
// time dynamically to match the large reference set?
|
||||||
let watchedFileSet = createWatchedFileSet();
|
const watchedFileSet = createWatchedFileSet();
|
||||||
|
|
||||||
function isNode4OrLater(): Boolean {
|
function isNode4OrLater(): Boolean {
|
||||||
return parseInt(process.version.charAt(1)) >= 4;
|
return parseInt(process.version.charAt(1)) >= 4;
|
||||||
|
@ -305,14 +305,14 @@ namespace ts {
|
||||||
if (!_fs.existsSync(fileName)) {
|
if (!_fs.existsSync(fileName)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
let buffer = _fs.readFileSync(fileName);
|
const buffer = _fs.readFileSync(fileName);
|
||||||
let len = buffer.length;
|
let len = buffer.length;
|
||||||
if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
|
if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
|
||||||
// Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
|
// Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
|
||||||
// flip all byte pairs and treat as little endian.
|
// flip all byte pairs and treat as little endian.
|
||||||
len &= ~1;
|
len &= ~1;
|
||||||
for (let i = 0; i < len; i += 2) {
|
for (let i = 0; i < len; i += 2) {
|
||||||
let temp = buffer[i];
|
const temp = buffer[i];
|
||||||
buffer[i] = buffer[i + 1];
|
buffer[i] = buffer[i + 1];
|
||||||
buffer[i + 1] = temp;
|
buffer[i + 1] = temp;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,17 @@ namespace ts {
|
||||||
data = "\uFEFF" + data;
|
data = "\uFEFF" + data;
|
||||||
}
|
}
|
||||||
|
|
||||||
_fs.writeFileSync(fileName, data, "utf8");
|
let fd: number;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fd = _fs.openSync(fileName, "w");
|
||||||
|
_fs.writeSync(fd, data, undefined, "utf8");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (fd !== undefined) {
|
||||||
|
_fs.closeSync(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCanonicalPath(path: string): string {
|
function getCanonicalPath(path: string): string {
|
||||||
|
@ -344,17 +354,17 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function readDirectory(path: string, extension?: string, exclude?: string[]): string[] {
|
function readDirectory(path: string, extension?: string, exclude?: string[]): string[] {
|
||||||
let result: string[] = [];
|
const result: string[] = [];
|
||||||
exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s)));
|
exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s)));
|
||||||
visitDirectory(path);
|
visitDirectory(path);
|
||||||
return result;
|
return result;
|
||||||
function visitDirectory(path: string) {
|
function visitDirectory(path: string) {
|
||||||
let files = _fs.readdirSync(path || ".").sort();
|
const files = _fs.readdirSync(path || ".").sort();
|
||||||
let directories: string[] = [];
|
const directories: string[] = [];
|
||||||
for (let current of files) {
|
for (const current of files) {
|
||||||
let name = combinePaths(path, current);
|
const name = combinePaths(path, current);
|
||||||
if (!contains(exclude, getCanonicalPath(name))) {
|
if (!contains(exclude, getCanonicalPath(name))) {
|
||||||
let stat = _fs.statSync(name);
|
const stat = _fs.statSync(name);
|
||||||
if (stat.isFile()) {
|
if (stat.isFile()) {
|
||||||
if (!extension || fileExtensionIs(name, extension)) {
|
if (!extension || fileExtensionIs(name, extension)) {
|
||||||
result.push(name);
|
result.push(name);
|
||||||
|
@ -365,7 +375,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let current of directories) {
|
for (const current of directories) {
|
||||||
visitDirectory(current);
|
visitDirectory(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,7 +400,7 @@ namespace ts {
|
||||||
return _fs.watch(fileName, (eventName: string, relativeFileName: string) => callback(fileName));
|
return _fs.watch(fileName, (eventName: string, relativeFileName: string) => callback(fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
let watchedFile = watchedFileSet.addFile(fileName, callback);
|
const watchedFile = watchedFileSet.addFile(fileName, callback);
|
||||||
return {
|
return {
|
||||||
close: () => watchedFileSet.removeFile(watchedFile)
|
close: () => watchedFileSet.removeFile(watchedFile)
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace ts {
|
||||||
let reportDiagnostic = reportDiagnosticSimply;
|
let reportDiagnostic = reportDiagnosticSimply;
|
||||||
|
|
||||||
function reportDiagnostics(diagnostics: Diagnostic[], host: CompilerHost): void {
|
function reportDiagnostics(diagnostics: Diagnostic[], host: CompilerHost): void {
|
||||||
for (let diagnostic of diagnostics) {
|
for (const diagnostic of diagnostics) {
|
||||||
reportDiagnostic(diagnostic, host);
|
reportDiagnostic(diagnostic, host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,15 +19,15 @@ namespace ts {
|
||||||
* and if it is, attempts to set the appropriate language.
|
* and if it is, attempts to set the appropriate language.
|
||||||
*/
|
*/
|
||||||
function validateLocaleAndSetLanguage(locale: string, errors: Diagnostic[]): boolean {
|
function validateLocaleAndSetLanguage(locale: string, errors: Diagnostic[]): boolean {
|
||||||
let matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
|
const matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
|
||||||
|
|
||||||
if (!matchResult) {
|
if (!matchResult) {
|
||||||
errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
|
errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let language = matchResult[1];
|
const language = matchResult[1];
|
||||||
let territory = matchResult[3];
|
const territory = matchResult[3];
|
||||||
|
|
||||||
// First try the entire locale, then fall back to just language if that's all we have.
|
// First try the entire locale, then fall back to just language if that's all we have.
|
||||||
if (!trySetLanguageAndTerritory(language, territory, errors) &&
|
if (!trySetLanguageAndTerritory(language, territory, errors) &&
|
||||||
|
@ -41,8 +41,8 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function trySetLanguageAndTerritory(language: string, territory: string, errors: Diagnostic[]): boolean {
|
function trySetLanguageAndTerritory(language: string, territory: string, errors: Diagnostic[]): boolean {
|
||||||
let compilerFilePath = normalizePath(sys.getExecutingFilePath());
|
const compilerFilePath = normalizePath(sys.getExecutingFilePath());
|
||||||
let containingDirectoryPath = getDirectoryPath(compilerFilePath);
|
const containingDirectoryPath = getDirectoryPath(compilerFilePath);
|
||||||
|
|
||||||
let filePath = combinePaths(containingDirectoryPath, language);
|
let filePath = combinePaths(containingDirectoryPath, language);
|
||||||
|
|
||||||
|
@ -85,23 +85,24 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDiagnosticText(message: DiagnosticMessage, ...args: any[]): string {
|
function getDiagnosticText(message: DiagnosticMessage, ...args: any[]): string {
|
||||||
let diagnostic = createCompilerDiagnostic.apply(undefined, arguments);
|
const diagnostic = createCompilerDiagnostic.apply(undefined, arguments);
|
||||||
return <string>diagnostic.messageText;
|
return <string>diagnostic.messageText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRelativeFileName(fileName: string, host: CompilerHost): string {
|
||||||
|
return host ? convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)) : fileName;
|
||||||
|
}
|
||||||
|
|
||||||
function reportDiagnosticSimply(diagnostic: Diagnostic, host: CompilerHost): void {
|
function reportDiagnosticSimply(diagnostic: Diagnostic, host: CompilerHost): void {
|
||||||
let output = "";
|
let output = "";
|
||||||
|
|
||||||
if (diagnostic.file) {
|
if (diagnostic.file) {
|
||||||
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||||
const relativeFileName = host
|
const relativeFileName = getRelativeFileName(diagnostic.file.fileName, host);
|
||||||
? convertToRelativePath(diagnostic.file.fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName))
|
output += `${ relativeFileName }(${ line + 1 },${ character + 1 }): `;
|
||||||
: diagnostic.file.fileName;
|
|
||||||
|
|
||||||
output += `${ diagnostic.file.fileName }(${ line + 1 },${ character + 1 }): `;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||||
output += `${ category } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }${ sys.newLine }`;
|
output += `${ category } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }${ sys.newLine }`;
|
||||||
|
|
||||||
sys.write(output);
|
sys.write(output);
|
||||||
|
@ -129,12 +130,13 @@ namespace ts {
|
||||||
let output = "";
|
let output = "";
|
||||||
|
|
||||||
if (diagnostic.file) {
|
if (diagnostic.file) {
|
||||||
let { start, length, file } = diagnostic;
|
const { start, length, file } = diagnostic;
|
||||||
let { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start);
|
const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start);
|
||||||
let { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start + length);
|
const { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start + length);
|
||||||
const lastLineInFile = getLineAndCharacterOfPosition(file, file.text.length).line;
|
const lastLineInFile = getLineAndCharacterOfPosition(file, file.text.length).line;
|
||||||
|
const relativeFileName = getRelativeFileName(file.fileName, host);
|
||||||
|
|
||||||
let hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
|
const hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
|
||||||
let gutterWidth = (lastLine + 1 + "").length;
|
let gutterWidth = (lastLine + 1 + "").length;
|
||||||
if (hasMoreThanFiveLines) {
|
if (hasMoreThanFiveLines) {
|
||||||
gutterWidth = Math.max(elipsis.length, gutterWidth);
|
gutterWidth = Math.max(elipsis.length, gutterWidth);
|
||||||
|
@ -149,8 +151,8 @@ namespace ts {
|
||||||
i = lastLine - 1;
|
i = lastLine - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lineStart = getPositionOfLineAndCharacter(file, i, 0);
|
const lineStart = getPositionOfLineAndCharacter(file, i, 0);
|
||||||
let lineEnd = i < lastLineInFile ? getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
|
const lineEnd = i < lastLineInFile ? getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
|
||||||
let lineContent = file.text.slice(lineStart, lineEnd);
|
let lineContent = file.text.slice(lineStart, lineEnd);
|
||||||
lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
|
lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
|
||||||
lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
|
lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
|
||||||
|
@ -183,7 +185,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
output += sys.newLine;
|
output += sys.newLine;
|
||||||
output += `${ file.fileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
||||||
}
|
}
|
||||||
|
|
||||||
const categoryColor = categoryFormatMap[diagnostic.category];
|
const categoryColor = categoryFormatMap[diagnostic.category];
|
||||||
|
@ -198,7 +200,7 @@ namespace ts {
|
||||||
let output = new Date().toLocaleTimeString() + " - ";
|
let output = new Date().toLocaleTimeString() + " - ";
|
||||||
|
|
||||||
if (diagnostic.file) {
|
if (diagnostic.file) {
|
||||||
let loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
const loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||||
output += `${ diagnostic.file.fileName }(${ loc.line + 1 },${ loc.character + 1 }): `;
|
output += `${ diagnostic.file.fileName }(${ loc.line + 1 },${ loc.character + 1 }): `;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +241,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function executeCommandLine(args: string[]): void {
|
export function executeCommandLine(args: string[]): void {
|
||||||
let commandLine = parseCommandLine(args);
|
const commandLine = parseCommandLine(args);
|
||||||
let configFileName: string; // Configuration file name (if any)
|
let configFileName: string; // Configuration file name (if any)
|
||||||
let cachedConfigFileText: string; // Cached configuration file text, used for reparsing (if any)
|
let cachedConfigFileText: string; // Cached configuration file text, used for reparsing (if any)
|
||||||
let configFileWatcher: FileWatcher; // Configuration file watcher
|
let configFileWatcher: FileWatcher; // Configuration file watcher
|
||||||
|
@ -300,7 +302,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
|
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
|
||||||
let searchPath = normalizePath(sys.getCurrentDirectory());
|
const searchPath = normalizePath(sys.getCurrentDirectory());
|
||||||
configFileName = findConfigFile(searchPath);
|
configFileName = findConfigFile(searchPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +322,7 @@ namespace ts {
|
||||||
configFileWatcher = sys.watchFile(configFileName, configFileChanged);
|
configFileWatcher = sys.watchFile(configFileName, configFileChanged);
|
||||||
}
|
}
|
||||||
if (sys.watchDirectory && configFileName) {
|
if (sys.watchDirectory && configFileName) {
|
||||||
let directory = ts.getDirectoryPath(configFileName);
|
const directory = ts.getDirectoryPath(configFileName);
|
||||||
directoryWatcher = sys.watchDirectory(
|
directoryWatcher = sys.watchDirectory(
|
||||||
// When the configFileName is just "tsconfig.json", the watched directory should be
|
// When the configFileName is just "tsconfig.json", the watched directory should be
|
||||||
// the current direcotry; if there is a given "project" parameter, then the configFileName
|
// the current direcotry; if there is a given "project" parameter, then the configFileName
|
||||||
|
@ -338,16 +340,16 @@ namespace ts {
|
||||||
cachedConfigFileText = sys.readFile(configFileName);
|
cachedConfigFileText = sys.readFile(configFileName);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
let error = createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
|
const error = createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
|
||||||
reportWatchDiagnostic(error);
|
reportWatchDiagnostic(error);
|
||||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = parseConfigFileTextToJson(configFileName, cachedConfigFileText);
|
const result = parseConfigFileTextToJson(configFileName, cachedConfigFileText);
|
||||||
let configObject = result.config;
|
const configObject = result.config;
|
||||||
let configParseResult = parseJsonConfigFileContent(configObject, sys, getDirectoryPath(configFileName));
|
const configParseResult = parseJsonConfigFileContent(configObject, sys, getDirectoryPath(configFileName));
|
||||||
if (configParseResult.errors.length > 0) {
|
if (configParseResult.errors.length > 0) {
|
||||||
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
||||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||||
|
@ -361,7 +363,7 @@ namespace ts {
|
||||||
|
|
||||||
if (!cachedProgram) {
|
if (!cachedProgram) {
|
||||||
if (configFileName) {
|
if (configFileName) {
|
||||||
let configParseResult = parseConfigFile();
|
const configParseResult = parseConfigFile();
|
||||||
rootFileNames = configParseResult.fileNames;
|
rootFileNames = configParseResult.fileNames;
|
||||||
compilerOptions = extend(commandLine.options, configParseResult.options);
|
compilerOptions = extend(commandLine.options, configParseResult.options);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +386,7 @@ namespace ts {
|
||||||
// reset the cache of existing files
|
// reset the cache of existing files
|
||||||
cachedExistingFiles = {};
|
cachedExistingFiles = {};
|
||||||
|
|
||||||
let compileResult = compile(rootFileNames, compilerOptions, compilerHost);
|
const compileResult = compile(rootFileNames, compilerOptions, compilerHost);
|
||||||
|
|
||||||
if (!compilerOptions.watch) {
|
if (!compilerOptions.watch) {
|
||||||
return sys.exit(compileResult.exitStatus);
|
return sys.exit(compileResult.exitStatus);
|
||||||
|
@ -404,14 +406,14 @@ namespace ts {
|
||||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) {
|
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) {
|
||||||
// Return existing SourceFile object if one is available
|
// Return existing SourceFile object if one is available
|
||||||
if (cachedProgram) {
|
if (cachedProgram) {
|
||||||
let sourceFile = cachedProgram.getSourceFile(fileName);
|
const sourceFile = cachedProgram.getSourceFile(fileName);
|
||||||
// A modified source file has no watcher and should not be reused
|
// A modified source file has no watcher and should not be reused
|
||||||
if (sourceFile && sourceFile.fileWatcher) {
|
if (sourceFile && sourceFile.fileWatcher) {
|
||||||
return sourceFile;
|
return sourceFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use default host function
|
// Use default host function
|
||||||
let sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
|
const sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
|
||||||
if (sourceFile && compilerOptions.watch) {
|
if (sourceFile && compilerOptions.watch) {
|
||||||
// Attach a file watcher
|
// Attach a file watcher
|
||||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||||
|
@ -422,7 +424,7 @@ namespace ts {
|
||||||
// Change cached program to the given program
|
// Change cached program to the given program
|
||||||
function setCachedProgram(program: Program) {
|
function setCachedProgram(program: Program) {
|
||||||
if (cachedProgram) {
|
if (cachedProgram) {
|
||||||
let newSourceFiles = program ? program.getSourceFiles() : undefined;
|
const newSourceFiles = program ? program.getSourceFiles() : undefined;
|
||||||
forEach(cachedProgram.getSourceFiles(), sourceFile => {
|
forEach(cachedProgram.getSourceFiles(), sourceFile => {
|
||||||
if (!(newSourceFiles && contains(newSourceFiles, sourceFile))) {
|
if (!(newSourceFiles && contains(newSourceFiles, sourceFile))) {
|
||||||
if (sourceFile.fileWatcher) {
|
if (sourceFile.fileWatcher) {
|
||||||
|
@ -440,7 +442,7 @@ namespace ts {
|
||||||
sourceFile.fileWatcher.close();
|
sourceFile.fileWatcher.close();
|
||||||
sourceFile.fileWatcher = undefined;
|
sourceFile.fileWatcher = undefined;
|
||||||
if (removed) {
|
if (removed) {
|
||||||
let index = rootFileNames.indexOf(sourceFile.fileName);
|
const index = rootFileNames.indexOf(sourceFile.fileName);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
rootFileNames.splice(index, 1);
|
rootFileNames.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
@ -471,9 +473,9 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function directoryChangeHandler() {
|
function directoryChangeHandler() {
|
||||||
let parsedCommandLine = parseConfigFile();
|
const parsedCommandLine = parseConfigFile();
|
||||||
let newFileNames = ts.map(parsedCommandLine.fileNames, compilerHost.getCanonicalFileName);
|
const newFileNames = ts.map(parsedCommandLine.fileNames, compilerHost.getCanonicalFileName);
|
||||||
let canonicalRootFileNames = ts.map(rootFileNames, compilerHost.getCanonicalFileName);
|
const canonicalRootFileNames = ts.map(rootFileNames, compilerHost.getCanonicalFileName);
|
||||||
|
|
||||||
// We check if the project file list has changed. If so, we just throw away the old program and start fresh.
|
// We check if the project file list has changed. If so, we just throw away the old program and start fresh.
|
||||||
if (!arrayIsEqualTo(newFileNames && newFileNames.sort(), canonicalRootFileNames && canonicalRootFileNames.sort())) {
|
if (!arrayIsEqualTo(newFileNames && newFileNames.sort(), canonicalRootFileNames && canonicalRootFileNames.sort())) {
|
||||||
|
@ -507,8 +509,8 @@ namespace ts {
|
||||||
checkTime = 0;
|
checkTime = 0;
|
||||||
emitTime = 0;
|
emitTime = 0;
|
||||||
|
|
||||||
let program = createProgram(fileNames, compilerOptions, compilerHost);
|
const program = createProgram(fileNames, compilerOptions, compilerHost);
|
||||||
let exitStatus = compileProgram();
|
const exitStatus = compileProgram();
|
||||||
|
|
||||||
if (compilerOptions.listFiles) {
|
if (compilerOptions.listFiles) {
|
||||||
forEach(program.getSourceFiles(), file => {
|
forEach(program.getSourceFiles(), file => {
|
||||||
|
@ -517,7 +519,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compilerOptions.diagnostics) {
|
if (compilerOptions.diagnostics) {
|
||||||
let memoryUsed = sys.getMemoryUsage ? sys.getMemoryUsage() : -1;
|
const memoryUsed = sys.getMemoryUsage ? sys.getMemoryUsage() : -1;
|
||||||
reportCountStatistic("Files", program.getSourceFiles().length);
|
reportCountStatistic("Files", program.getSourceFiles().length);
|
||||||
reportCountStatistic("Lines", countLines(program));
|
reportCountStatistic("Lines", countLines(program));
|
||||||
reportCountStatistic("Nodes", program.getNodeCount());
|
reportCountStatistic("Nodes", program.getNodeCount());
|
||||||
|
@ -570,7 +572,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, emit and report any errors we ran into.
|
// Otherwise, emit and report any errors we ran into.
|
||||||
let emitOutput = program.emit();
|
const emitOutput = program.emit();
|
||||||
reportDiagnostics(emitOutput.diagnostics, compilerHost);
|
reportDiagnostics(emitOutput.diagnostics, compilerHost);
|
||||||
|
|
||||||
// If the emitter didn't emit anything, then pass that value along.
|
// If the emitter didn't emit anything, then pass that value along.
|
||||||
|
@ -596,8 +598,8 @@ namespace ts {
|
||||||
let output = "";
|
let output = "";
|
||||||
|
|
||||||
// We want to align our "syntax" and "examples" commands to a certain margin.
|
// We want to align our "syntax" and "examples" commands to a certain margin.
|
||||||
let syntaxLength = getDiagnosticText(Diagnostics.Syntax_Colon_0, "").length;
|
const syntaxLength = getDiagnosticText(Diagnostics.Syntax_Colon_0, "").length;
|
||||||
let examplesLength = getDiagnosticText(Diagnostics.Examples_Colon_0, "").length;
|
const examplesLength = getDiagnosticText(Diagnostics.Examples_Colon_0, "").length;
|
||||||
let marginLength = Math.max(syntaxLength, examplesLength);
|
let marginLength = Math.max(syntaxLength, examplesLength);
|
||||||
|
|
||||||
// Build up the syntactic skeleton.
|
// Build up the syntactic skeleton.
|
||||||
|
@ -608,7 +610,7 @@ namespace ts {
|
||||||
output += sys.newLine + sys.newLine;
|
output += sys.newLine + sys.newLine;
|
||||||
|
|
||||||
// Build up the list of examples.
|
// Build up the list of examples.
|
||||||
let padding = makePadding(marginLength);
|
const padding = makePadding(marginLength);
|
||||||
output += getDiagnosticText(Diagnostics.Examples_Colon_0, makePadding(marginLength - examplesLength) + "tsc hello.ts") + sys.newLine;
|
output += getDiagnosticText(Diagnostics.Examples_Colon_0, makePadding(marginLength - examplesLength) + "tsc hello.ts") + sys.newLine;
|
||||||
output += padding + "tsc --out file.js file.ts" + sys.newLine;
|
output += padding + "tsc --out file.js file.ts" + sys.newLine;
|
||||||
output += padding + "tsc @args.txt" + sys.newLine;
|
output += padding + "tsc @args.txt" + sys.newLine;
|
||||||
|
@ -617,17 +619,17 @@ namespace ts {
|
||||||
output += getDiagnosticText(Diagnostics.Options_Colon) + sys.newLine;
|
output += getDiagnosticText(Diagnostics.Options_Colon) + sys.newLine;
|
||||||
|
|
||||||
// Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch")
|
// Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch")
|
||||||
let optsList = filter(optionDeclarations.slice(), v => !v.experimental);
|
const optsList = filter(optionDeclarations.slice(), v => !v.experimental);
|
||||||
optsList.sort((a, b) => compareValues<string>(a.name.toLowerCase(), b.name.toLowerCase()));
|
optsList.sort((a, b) => compareValues<string>(a.name.toLowerCase(), b.name.toLowerCase()));
|
||||||
|
|
||||||
// We want our descriptions to align at the same column in our output,
|
// We want our descriptions to align at the same column in our output,
|
||||||
// so we keep track of the longest option usage string.
|
// so we keep track of the longest option usage string.
|
||||||
marginLength = 0;
|
marginLength = 0;
|
||||||
let usageColumn: string[] = []; // Things like "-d, --declaration" go in here.
|
const usageColumn: string[] = []; // Things like "-d, --declaration" go in here.
|
||||||
let descriptionColumn: string[] = [];
|
const descriptionColumn: string[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < optsList.length; i++) {
|
for (let i = 0; i < optsList.length; i++) {
|
||||||
let option = optsList[i];
|
const option = optsList[i];
|
||||||
|
|
||||||
// If an option lacks a description,
|
// If an option lacks a description,
|
||||||
// it is not officially supported.
|
// it is not officially supported.
|
||||||
|
@ -653,15 +655,15 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case that can't fit in the loop.
|
// Special case that can't fit in the loop.
|
||||||
let usageText = " @<" + getDiagnosticText(Diagnostics.file) + ">";
|
const usageText = " @<" + getDiagnosticText(Diagnostics.file) + ">";
|
||||||
usageColumn.push(usageText);
|
usageColumn.push(usageText);
|
||||||
descriptionColumn.push(getDiagnosticText(Diagnostics.Insert_command_line_options_and_files_from_a_file));
|
descriptionColumn.push(getDiagnosticText(Diagnostics.Insert_command_line_options_and_files_from_a_file));
|
||||||
marginLength = Math.max(usageText.length, marginLength);
|
marginLength = Math.max(usageText.length, marginLength);
|
||||||
|
|
||||||
// Print out each row, aligning all the descriptions on the same column.
|
// Print out each row, aligning all the descriptions on the same column.
|
||||||
for (let i = 0; i < usageColumn.length; i++) {
|
for (let i = 0; i < usageColumn.length; i++) {
|
||||||
let usage = usageColumn[i];
|
const usage = usageColumn[i];
|
||||||
let description = descriptionColumn[i];
|
const description = descriptionColumn[i];
|
||||||
output += usage + makePadding(marginLength - usage.length + 2) + description + sys.newLine;
|
output += usage + makePadding(marginLength - usage.length + 2) + description + sys.newLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,14 +683,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeConfigFile(options: CompilerOptions, fileNames: string[]) {
|
function writeConfigFile(options: CompilerOptions, fileNames: string[]) {
|
||||||
let currentDirectory = sys.getCurrentDirectory();
|
const currentDirectory = sys.getCurrentDirectory();
|
||||||
let file = normalizePath(combinePaths(currentDirectory, "tsconfig.json"));
|
const file = normalizePath(combinePaths(currentDirectory, "tsconfig.json"));
|
||||||
if (sys.fileExists(file)) {
|
if (sys.fileExists(file)) {
|
||||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* compilerHost */ undefined);
|
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* compilerHost */ undefined);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let compilerOptions = extend(options, defaultInitCompilerOptions);
|
const compilerOptions = extend(options, defaultInitCompilerOptions);
|
||||||
let configurations: any = {
|
const configurations: any = {
|
||||||
compilerOptions: serializeCompilerOptions(compilerOptions),
|
compilerOptions: serializeCompilerOptions(compilerOptions),
|
||||||
exclude: ["node_modules"]
|
exclude: ["node_modules"]
|
||||||
};
|
};
|
||||||
|
@ -705,12 +707,12 @@ namespace ts {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function serializeCompilerOptions(options: CompilerOptions): Map<string | number | boolean> {
|
function serializeCompilerOptions(options: CompilerOptions): Map<string | number | boolean> {
|
||||||
let result: Map<string | number | boolean> = {};
|
const result: Map<string | number | boolean> = {};
|
||||||
let optionsNameMap = getOptionNameMap().optionNameMap;
|
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||||
|
|
||||||
for (let name in options) {
|
for (const name in options) {
|
||||||
if (hasProperty(options, name)) {
|
if (hasProperty(options, name)) {
|
||||||
let value = options[name];
|
const value = options[name];
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "init":
|
case "init":
|
||||||
case "watch":
|
case "watch":
|
||||||
|
@ -727,8 +729,8 @@ namespace ts {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Enum
|
// Enum
|
||||||
let typeMap = <Map<number>>optionDefinition.type;
|
const typeMap = <Map<number>>optionDefinition.type;
|
||||||
for (let key in typeMap) {
|
for (const key in typeMap) {
|
||||||
if (hasProperty(typeMap, key)) {
|
if (hasProperty(typeMap, key)) {
|
||||||
if (typeMap[key] === value)
|
if (typeMap[key] === value)
|
||||||
result[name] = key;
|
result[name] = key;
|
||||||
|
|
|
@ -1957,6 +1957,8 @@ namespace ts {
|
||||||
target?: TypeParameter; // Instantiation target
|
target?: TypeParameter; // Instantiation target
|
||||||
/* @internal */
|
/* @internal */
|
||||||
mapper?: TypeMapper; // Instantiation mapper
|
mapper?: TypeMapper; // Instantiation mapper
|
||||||
|
/* @internal */
|
||||||
|
resolvedApparentType: Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum SignatureKind {
|
export const enum SignatureKind {
|
||||||
|
|
|
@ -16,9 +16,9 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration {
|
export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration {
|
||||||
let declarations = symbol.declarations;
|
const declarations = symbol.declarations;
|
||||||
if (declarations) {
|
if (declarations) {
|
||||||
for (let declaration of declarations) {
|
for (const declaration of declarations) {
|
||||||
if (declaration.kind === kind) {
|
if (declaration.kind === kind) {
|
||||||
return declaration;
|
return declaration;
|
||||||
}
|
}
|
||||||
|
@ -43,12 +43,12 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pool writers to avoid needing to allocate them for every symbol we write.
|
// Pool writers to avoid needing to allocate them for every symbol we write.
|
||||||
let stringWriters: StringSymbolWriter[] = [];
|
const stringWriters: StringSymbolWriter[] = [];
|
||||||
export function getSingleLineStringWriter(): StringSymbolWriter {
|
export function getSingleLineStringWriter(): StringSymbolWriter {
|
||||||
if (stringWriters.length === 0) {
|
if (stringWriters.length === 0) {
|
||||||
let str = "";
|
let str = "";
|
||||||
|
|
||||||
let writeText: (text: string) => void = text => str += text;
|
const writeText: (text: string) => void = text => str += text;
|
||||||
return {
|
return {
|
||||||
string: () => str,
|
string: () => str,
|
||||||
writeKeyword: writeText,
|
writeKeyword: writeText,
|
||||||
|
@ -92,7 +92,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < array1.length; ++i) {
|
for (let i = 0; i < array1.length; ++i) {
|
||||||
let equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
|
const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
|
||||||
if (!equals) {
|
if (!equals) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ namespace ts {
|
||||||
// A node is considered to contain a parse error if:
|
// A node is considered to contain a parse error if:
|
||||||
// a) the parser explicitly marked that it had an error
|
// a) the parser explicitly marked that it had an error
|
||||||
// b) any of it's children reported that it had an error.
|
// b) any of it's children reported that it had an error.
|
||||||
let thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & ParserContextFlags.ThisNodeHasError) !== 0) ||
|
const thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & ParserContextFlags.ThisNodeHasError) !== 0) ||
|
||||||
forEachChild(node, containsParseError);
|
forEachChild(node, containsParseError);
|
||||||
|
|
||||||
// If so, mark ourselves accordingly.
|
// If so, mark ourselves accordingly.
|
||||||
|
@ -157,8 +157,8 @@ namespace ts {
|
||||||
|
|
||||||
// This is a useful function for debugging purposes.
|
// This is a useful function for debugging purposes.
|
||||||
export function nodePosToString(node: Node): string {
|
export function nodePosToString(node: Node): string {
|
||||||
let file = getSourceFileOfNode(node);
|
const file = getSourceFileOfNode(node);
|
||||||
let loc = getLineAndCharacterOfPosition(file, node.pos);
|
const loc = getLineAndCharacterOfPosition(file, node.pos);
|
||||||
return `${ file.fileName }(${ loc.line + 1 },${ loc.character + 1 })`;
|
return `${ file.fileName }(${ loc.line + 1 },${ loc.character + 1 })`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ namespace ts {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = sourceFile.text;
|
const text = sourceFile.text;
|
||||||
return text.substring(includeTrivia ? node.pos : skipTrivia(text, node.pos), node.end);
|
return text.substring(includeTrivia ? node.pos : skipTrivia(text, node.pos), node.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,14 +294,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
|
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
|
||||||
let sourceFile = getSourceFileOfNode(node);
|
const sourceFile = getSourceFileOfNode(node);
|
||||||
let span = getErrorSpanForNode(sourceFile, node);
|
const span = getErrorSpanForNode(sourceFile, node);
|
||||||
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
|
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): Diagnostic {
|
export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): Diagnostic {
|
||||||
let sourceFile = getSourceFileOfNode(node);
|
const sourceFile = getSourceFileOfNode(node);
|
||||||
let span = getErrorSpanForNode(sourceFile, node);
|
const span = getErrorSpanForNode(sourceFile, node);
|
||||||
return {
|
return {
|
||||||
file: sourceFile,
|
file: sourceFile,
|
||||||
start: span.start,
|
start: span.start,
|
||||||
|
@ -313,9 +313,9 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSpanOfTokenAtPosition(sourceFile: SourceFile, pos: number): TextSpan {
|
export function getSpanOfTokenAtPosition(sourceFile: SourceFile, pos: number): TextSpan {
|
||||||
let scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
|
const scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
|
||||||
scanner.scan();
|
scanner.scan();
|
||||||
let start = scanner.getTokenPos();
|
const start = scanner.getTokenPos();
|
||||||
return createTextSpanFromBounds(start, scanner.getTextPos());
|
return createTextSpanFromBounds(start, scanner.getTextPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ namespace ts {
|
||||||
return getSpanOfTokenAtPosition(sourceFile, node.pos);
|
return getSpanOfTokenAtPosition(sourceFile, node.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pos = nodeIsMissing(errorNode)
|
const pos = nodeIsMissing(errorNode)
|
||||||
? errorNode.pos
|
? errorNode.pos
|
||||||
: skipTrivia(sourceFile.text, errorNode.pos);
|
: skipTrivia(sourceFile.text, errorNode.pos);
|
||||||
|
|
||||||
|
@ -421,18 +421,26 @@ namespace ts {
|
||||||
return getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
|
return getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLeadingCommentRangesOfNodeFromText(node: Node, text: string) {
|
||||||
|
return getLeadingCommentRanges(text, node.pos);
|
||||||
|
}
|
||||||
|
|
||||||
export function getJsDocComments(node: Node, sourceFileOfNode: SourceFile) {
|
export function getJsDocComments(node: Node, sourceFileOfNode: SourceFile) {
|
||||||
let commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ?
|
return getJsDocCommentsFromText(node, sourceFileOfNode.text);
|
||||||
concatenate(getTrailingCommentRanges(sourceFileOfNode.text, node.pos),
|
}
|
||||||
getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) :
|
|
||||||
getLeadingCommentRangesOfNode(node, sourceFileOfNode);
|
export function getJsDocCommentsFromText(node: Node, text: string) {
|
||||||
|
const commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ?
|
||||||
|
concatenate(getTrailingCommentRanges(text, node.pos),
|
||||||
|
getLeadingCommentRanges(text, node.pos)) :
|
||||||
|
getLeadingCommentRangesOfNodeFromText(node, text);
|
||||||
return filter(commentRanges, isJsDocComment);
|
return filter(commentRanges, isJsDocComment);
|
||||||
|
|
||||||
function isJsDocComment(comment: CommentRange) {
|
function isJsDocComment(comment: CommentRange) {
|
||||||
// True if the comment starts with '/**' but not if it is '/**/'
|
// True if the comment starts with '/**' but not if it is '/**/'
|
||||||
return sourceFileOfNode.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
|
return text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
|
||||||
sourceFileOfNode.text.charCodeAt(comment.pos + 2) === CharacterCodes.asterisk &&
|
text.charCodeAt(comment.pos + 2) === CharacterCodes.asterisk &&
|
||||||
sourceFileOfNode.text.charCodeAt(comment.pos + 3) !== CharacterCodes.slash;
|
text.charCodeAt(comment.pos + 3) !== CharacterCodes.slash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +587,7 @@ namespace ts {
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
if (isFunctionLike(node)) {
|
if (isFunctionLike(node)) {
|
||||||
let name = (<FunctionLikeDeclaration>node).name;
|
const name = (<FunctionLikeDeclaration>node).name;
|
||||||
if (name && name.kind === SyntaxKind.ComputedPropertyName) {
|
if (name && name.kind === SyntaxKind.ComputedPropertyName) {
|
||||||
// Note that we will not include methods/accessors of a class because they would require
|
// Note that we will not include methods/accessors of a class because they would require
|
||||||
// first descending into the class. This is by design.
|
// first descending into the class. This is by design.
|
||||||
|
@ -1030,7 +1038,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
|
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
|
||||||
let moduleState = getModuleInstanceState(node);
|
const moduleState = getModuleInstanceState(node);
|
||||||
return moduleState === ModuleInstanceState.Instantiated ||
|
return moduleState === ModuleInstanceState.Instantiated ||
|
||||||
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
|
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +1061,7 @@ namespace ts {
|
||||||
return (<ImportDeclaration>node).moduleSpecifier;
|
return (<ImportDeclaration>node).moduleSpecifier;
|
||||||
}
|
}
|
||||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||||
let reference = (<ImportEqualsDeclaration>node).moduleReference;
|
const reference = (<ImportEqualsDeclaration>node).moduleReference;
|
||||||
if (reference.kind === SyntaxKind.ExternalModuleReference) {
|
if (reference.kind === SyntaxKind.ExternalModuleReference) {
|
||||||
return (<ExternalModuleReference>reference).expression;
|
return (<ExternalModuleReference>reference).expression;
|
||||||
}
|
}
|
||||||
|
@ -1088,7 +1096,7 @@ namespace ts {
|
||||||
|
|
||||||
function getJSDocTag(node: Node, kind: SyntaxKind): JSDocTag {
|
function getJSDocTag(node: Node, kind: SyntaxKind): JSDocTag {
|
||||||
if (node && node.jsDocComment) {
|
if (node && node.jsDocComment) {
|
||||||
for (let tag of node.jsDocComment.tags) {
|
for (const tag of node.jsDocComment.tags) {
|
||||||
if (tag.kind === kind) {
|
if (tag.kind === kind) {
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
@ -1112,14 +1120,14 @@ namespace ts {
|
||||||
if (parameter.name && parameter.name.kind === SyntaxKind.Identifier) {
|
if (parameter.name && parameter.name.kind === SyntaxKind.Identifier) {
|
||||||
// If it's a parameter, see if the parent has a jsdoc comment with an @param
|
// If it's a parameter, see if the parent has a jsdoc comment with an @param
|
||||||
// annotation.
|
// annotation.
|
||||||
let parameterName = (<Identifier>parameter.name).text;
|
const parameterName = (<Identifier>parameter.name).text;
|
||||||
|
|
||||||
let docComment = parameter.parent.jsDocComment;
|
const docComment = parameter.parent.jsDocComment;
|
||||||
if (docComment) {
|
if (docComment) {
|
||||||
return <JSDocParameterTag>forEach(docComment.tags, t => {
|
return <JSDocParameterTag>forEach(docComment.tags, t => {
|
||||||
if (t.kind === SyntaxKind.JSDocParameterTag) {
|
if (t.kind === SyntaxKind.JSDocParameterTag) {
|
||||||
let parameterTag = <JSDocParameterTag>t;
|
const parameterTag = <JSDocParameterTag>t;
|
||||||
let name = parameterTag.preParameterName || parameterTag.postParameterName;
|
const name = parameterTag.preParameterName || parameterTag.postParameterName;
|
||||||
if (name.text === parameterName) {
|
if (name.text === parameterName) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -1140,7 +1148,7 @@ namespace ts {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let paramTag = getCorrespondingJSDocParameterTag(node);
|
const paramTag = getCorrespondingJSDocParameterTag(node);
|
||||||
if (paramTag && paramTag.typeExpression) {
|
if (paramTag && paramTag.typeExpression) {
|
||||||
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
|
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
|
||||||
}
|
}
|
||||||
|
@ -1270,7 +1278,7 @@ namespace ts {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent = name.parent;
|
const parent = name.parent;
|
||||||
if (parent.kind === SyntaxKind.ImportSpecifier || parent.kind === SyntaxKind.ExportSpecifier) {
|
if (parent.kind === SyntaxKind.ImportSpecifier || parent.kind === SyntaxKind.ExportSpecifier) {
|
||||||
if ((<ImportOrExportSpecifier>parent).propertyName) {
|
if ((<ImportOrExportSpecifier>parent).propertyName) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1337,23 +1345,23 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration) {
|
export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration) {
|
||||||
let heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword);
|
const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword);
|
||||||
return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
|
return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration) {
|
export function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration) {
|
||||||
let heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword);
|
const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword);
|
||||||
return heritageClause ? heritageClause.types : undefined;
|
return heritageClause ? heritageClause.types : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInterfaceBaseTypeNodes(node: InterfaceDeclaration) {
|
export function getInterfaceBaseTypeNodes(node: InterfaceDeclaration) {
|
||||||
let heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword);
|
const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword);
|
||||||
return heritageClause ? heritageClause.types : undefined;
|
return heritageClause ? heritageClause.types : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getHeritageClause(clauses: NodeArray<HeritageClause>, kind: SyntaxKind) {
|
export function getHeritageClause(clauses: NodeArray<HeritageClause>, kind: SyntaxKind) {
|
||||||
if (clauses) {
|
if (clauses) {
|
||||||
for (let clause of clauses) {
|
for (const clause of clauses) {
|
||||||
if (clause.token === kind) {
|
if (clause.token === kind) {
|
||||||
return clause;
|
return clause;
|
||||||
}
|
}
|
||||||
|
@ -1365,7 +1373,7 @@ namespace ts {
|
||||||
|
|
||||||
export function tryResolveScriptReference(host: ScriptReferenceHost, sourceFile: SourceFile, reference: FileReference) {
|
export function tryResolveScriptReference(host: ScriptReferenceHost, sourceFile: SourceFile, reference: FileReference) {
|
||||||
if (!host.getCompilerOptions().noResolve) {
|
if (!host.getCompilerOptions().noResolve) {
|
||||||
let referenceFileName = isRootedDiskPath(reference.fileName) ? reference.fileName : combinePaths(getDirectoryPath(sourceFile.fileName), reference.fileName);
|
const referenceFileName = isRootedDiskPath(reference.fileName) ? reference.fileName : combinePaths(getDirectoryPath(sourceFile.fileName), reference.fileName);
|
||||||
return host.getSourceFile(referenceFileName);
|
return host.getSourceFile(referenceFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1381,19 +1389,19 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFileReferenceFromReferencePath(comment: string, commentRange: CommentRange): ReferencePathMatchResult {
|
export function getFileReferenceFromReferencePath(comment: string, commentRange: CommentRange): ReferencePathMatchResult {
|
||||||
let simpleReferenceRegEx = /^\/\/\/\s*<reference\s+/gim;
|
const simpleReferenceRegEx = /^\/\/\/\s*<reference\s+/gim;
|
||||||
let isNoDefaultLibRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/gim;
|
const isNoDefaultLibRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/gim;
|
||||||
if (simpleReferenceRegEx.exec(comment)) {
|
if (simpleReferenceRegEx.test(comment)) {
|
||||||
if (isNoDefaultLibRegEx.exec(comment)) {
|
if (isNoDefaultLibRegEx.test(comment)) {
|
||||||
return {
|
return {
|
||||||
isNoDefaultLib: true
|
isNoDefaultLib: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let matchResult = fullTripleSlashReferencePathRegEx.exec(comment);
|
const matchResult = fullTripleSlashReferencePathRegEx.exec(comment);
|
||||||
if (matchResult) {
|
if (matchResult) {
|
||||||
let start = commentRange.pos;
|
const start = commentRange.pos;
|
||||||
let end = commentRange.end;
|
const end = commentRange.end;
|
||||||
return {
|
return {
|
||||||
fileReference: {
|
fileReference: {
|
||||||
pos: start,
|
pos: start,
|
||||||
|
@ -1454,9 +1462,9 @@ namespace ts {
|
||||||
return (<Identifier | LiteralExpression>name).text;
|
return (<Identifier | LiteralExpression>name).text;
|
||||||
}
|
}
|
||||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||||
let nameExpression = (<ComputedPropertyName>name).expression;
|
const nameExpression = (<ComputedPropertyName>name).expression;
|
||||||
if (isWellKnownSymbolSyntactically(nameExpression)) {
|
if (isWellKnownSymbolSyntactically(nameExpression)) {
|
||||||
let rightHandSideName = (<PropertyAccessExpression>nameExpression).name.text;
|
const rightHandSideName = (<PropertyAccessExpression>nameExpression).name.text;
|
||||||
return getPropertyNameForKnownSymbolName(rightHandSideName);
|
return getPropertyNameForKnownSymbolName(rightHandSideName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1493,7 +1501,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isParameterDeclaration(node: VariableLikeDeclaration) {
|
export function isParameterDeclaration(node: VariableLikeDeclaration) {
|
||||||
let root = getRootDeclaration(node);
|
const root = getRootDeclaration(node);
|
||||||
return root.kind === SyntaxKind.Parameter;
|
return root.kind === SyntaxKind.Parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1510,12 +1518,12 @@ namespace ts {
|
||||||
|
|
||||||
export function cloneEntityName(node: EntityName): EntityName {
|
export function cloneEntityName(node: EntityName): EntityName {
|
||||||
if (node.kind === SyntaxKind.Identifier) {
|
if (node.kind === SyntaxKind.Identifier) {
|
||||||
let clone = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
const clone = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
||||||
clone.text = (<Identifier>node).text;
|
clone.text = (<Identifier>node).text;
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let clone = <QualifiedName>createSynthesizedNode(SyntaxKind.QualifiedName);
|
const clone = <QualifiedName>createSynthesizedNode(SyntaxKind.QualifiedName);
|
||||||
clone.left = cloneEntityName((<QualifiedName>node).left);
|
clone.left = cloneEntityName((<QualifiedName>node).left);
|
||||||
clone.left.parent = clone;
|
clone.left.parent = clone;
|
||||||
clone.right = <Identifier>cloneEntityName((<QualifiedName>node).right);
|
clone.right = <Identifier>cloneEntityName((<QualifiedName>node).right);
|
||||||
|
@ -1529,13 +1537,13 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node {
|
export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node {
|
||||||
let node = <SynthesizedNode>createNode(kind, /* pos */ -1, /* end */ -1);
|
const node = <SynthesizedNode>createNode(kind, /* pos */ -1, /* end */ -1);
|
||||||
node.startsOnNewLine = startsOnNewLine;
|
node.startsOnNewLine = startsOnNewLine;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSynthesizedNodeArray(): NodeArray<any> {
|
export function createSynthesizedNodeArray(): NodeArray<any> {
|
||||||
let array = <NodeArray<any>>[];
|
const array = <NodeArray<any>>[];
|
||||||
array.pos = -1;
|
array.pos = -1;
|
||||||
array.end = -1;
|
array.end = -1;
|
||||||
return array;
|
return array;
|
||||||
|
@ -1543,7 +1551,7 @@ namespace ts {
|
||||||
|
|
||||||
export function createDiagnosticCollection(): DiagnosticCollection {
|
export function createDiagnosticCollection(): DiagnosticCollection {
|
||||||
let nonFileDiagnostics: Diagnostic[] = [];
|
let nonFileDiagnostics: Diagnostic[] = [];
|
||||||
let fileDiagnostics: Map<Diagnostic[]> = {};
|
const fileDiagnostics: Map<Diagnostic[]> = {};
|
||||||
|
|
||||||
let diagnosticsModified = false;
|
let diagnosticsModified = false;
|
||||||
let modificationCount = 0;
|
let modificationCount = 0;
|
||||||
|
@ -1565,7 +1573,7 @@ namespace ts {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let diagnostic of fileDiagnostics[newFile.fileName]) {
|
for (const diagnostic of fileDiagnostics[newFile.fileName]) {
|
||||||
diagnostic.file = newFile;
|
diagnostic.file = newFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1599,14 +1607,14 @@ namespace ts {
|
||||||
return fileDiagnostics[fileName] || [];
|
return fileDiagnostics[fileName] || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let allDiagnostics: Diagnostic[] = [];
|
const allDiagnostics: Diagnostic[] = [];
|
||||||
function pushDiagnostic(d: Diagnostic) {
|
function pushDiagnostic(d: Diagnostic) {
|
||||||
allDiagnostics.push(d);
|
allDiagnostics.push(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
forEach(nonFileDiagnostics, pushDiagnostic);
|
forEach(nonFileDiagnostics, pushDiagnostic);
|
||||||
|
|
||||||
for (let key in fileDiagnostics) {
|
for (const key in fileDiagnostics) {
|
||||||
if (hasProperty(fileDiagnostics, key)) {
|
if (hasProperty(fileDiagnostics, key)) {
|
||||||
forEach(fileDiagnostics[key], pushDiagnostic);
|
forEach(fileDiagnostics[key], pushDiagnostic);
|
||||||
}
|
}
|
||||||
|
@ -1623,7 +1631,7 @@ namespace ts {
|
||||||
diagnosticsModified = false;
|
diagnosticsModified = false;
|
||||||
nonFileDiagnostics = sortAndDeduplicateDiagnostics(nonFileDiagnostics);
|
nonFileDiagnostics = sortAndDeduplicateDiagnostics(nonFileDiagnostics);
|
||||||
|
|
||||||
for (let key in fileDiagnostics) {
|
for (const key in fileDiagnostics) {
|
||||||
if (hasProperty(fileDiagnostics, key)) {
|
if (hasProperty(fileDiagnostics, key)) {
|
||||||
fileDiagnostics[key] = sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
|
fileDiagnostics[key] = sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
|
||||||
}
|
}
|
||||||
|
@ -1636,8 +1644,8 @@ namespace ts {
|
||||||
// the language service. These characters should be escaped when printing, and if any characters are added,
|
// the language service. These characters should be escaped when printing, and if any characters are added,
|
||||||
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
||||||
// There is no reason for this other than that JSON.stringify does not handle it either.
|
// There is no reason for this other than that JSON.stringify does not handle it either.
|
||||||
let escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
const escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||||
let escapedCharsMap: Map<string> = {
|
const escapedCharsMap: Map<string> = {
|
||||||
"\0": "\\0",
|
"\0": "\\0",
|
||||||
"\t": "\\t",
|
"\t": "\\t",
|
||||||
"\v": "\\v",
|
"\v": "\\v",
|
||||||
|
@ -1669,17 +1677,17 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isIntrinsicJsxName(name: string) {
|
export function isIntrinsicJsxName(name: string) {
|
||||||
let ch = name.substr(0, 1);
|
const ch = name.substr(0, 1);
|
||||||
return ch.toLowerCase() === ch;
|
return ch.toLowerCase() === ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get16BitUnicodeEscapeSequence(charCode: number): string {
|
function get16BitUnicodeEscapeSequence(charCode: number): string {
|
||||||
let hexCharCode = charCode.toString(16).toUpperCase();
|
const hexCharCode = charCode.toString(16).toUpperCase();
|
||||||
let paddedHexCode = ("0000" + hexCharCode).slice(-4);
|
const paddedHexCode = ("0000" + hexCharCode).slice(-4);
|
||||||
return "\\u" + paddedHexCode;
|
return "\\u" + paddedHexCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
let nonAsciiCharacters = /[^\u0000-\u007F]/g;
|
const nonAsciiCharacters = /[^\u0000-\u007F]/g;
|
||||||
export function escapeNonAsciiCharacters(s: string): string {
|
export function escapeNonAsciiCharacters(s: string): string {
|
||||||
// Replace non-ASCII characters with '\uNNNN' escapes if any exist.
|
// Replace non-ASCII characters with '\uNNNN' escapes if any exist.
|
||||||
// Otherwise just return the original string.
|
// Otherwise just return the original string.
|
||||||
|
@ -1690,7 +1698,7 @@ namespace ts {
|
||||||
|
|
||||||
export interface EmitTextWriter {
|
export interface EmitTextWriter {
|
||||||
write(s: string): void;
|
write(s: string): void;
|
||||||
writeTextOfNode(sourceFile: SourceFile, node: Node): void;
|
writeTextOfNode(text: string, node: Node): void;
|
||||||
writeLine(): void;
|
writeLine(): void;
|
||||||
increaseIndent(): void;
|
increaseIndent(): void;
|
||||||
decreaseIndent(): void;
|
decreaseIndent(): void;
|
||||||
|
@ -1701,9 +1709,10 @@ namespace ts {
|
||||||
getLine(): number;
|
getLine(): number;
|
||||||
getColumn(): number;
|
getColumn(): number;
|
||||||
getIndent(): number;
|
getIndent(): number;
|
||||||
|
reset(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
let indentStrings: string[] = ["", " "];
|
const indentStrings: string[] = ["", " "];
|
||||||
export function getIndentString(level: number) {
|
export function getIndentString(level: number) {
|
||||||
if (indentStrings[level] === undefined) {
|
if (indentStrings[level] === undefined) {
|
||||||
indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
|
indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
|
||||||
|
@ -1716,11 +1725,11 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTextWriter(newLine: String): EmitTextWriter {
|
export function createTextWriter(newLine: String): EmitTextWriter {
|
||||||
let output = "";
|
let output: string;
|
||||||
let indent = 0;
|
let indent: number;
|
||||||
let lineStart = true;
|
let lineStart: boolean;
|
||||||
let lineCount = 0;
|
let lineCount: number;
|
||||||
let linePos = 0;
|
let linePos: number;
|
||||||
|
|
||||||
function write(s: string) {
|
function write(s: string) {
|
||||||
if (s && s.length) {
|
if (s && s.length) {
|
||||||
|
@ -1732,6 +1741,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reset(): void {
|
||||||
|
output = "";
|
||||||
|
indent = 0;
|
||||||
|
lineStart = true;
|
||||||
|
lineCount = 0;
|
||||||
|
linePos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
function rawWrite(s: string) {
|
function rawWrite(s: string) {
|
||||||
if (s !== undefined) {
|
if (s !== undefined) {
|
||||||
if (lineStart) {
|
if (lineStart) {
|
||||||
|
@ -1744,7 +1761,7 @@ namespace ts {
|
||||||
function writeLiteral(s: string) {
|
function writeLiteral(s: string) {
|
||||||
if (s && s.length) {
|
if (s && s.length) {
|
||||||
write(s);
|
write(s);
|
||||||
let lineStartsOfS = computeLineStarts(s);
|
const lineStartsOfS = computeLineStarts(s);
|
||||||
if (lineStartsOfS.length > 1) {
|
if (lineStartsOfS.length > 1) {
|
||||||
lineCount = lineCount + lineStartsOfS.length - 1;
|
lineCount = lineCount + lineStartsOfS.length - 1;
|
||||||
linePos = output.length - s.length + lastOrUndefined(lineStartsOfS);
|
linePos = output.length - s.length + lastOrUndefined(lineStartsOfS);
|
||||||
|
@ -1761,10 +1778,12 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTextOfNode(sourceFile: SourceFile, node: Node) {
|
function writeTextOfNode(text: string, node: Node) {
|
||||||
write(getSourceTextOfNodeFromSourceFile(sourceFile, node));
|
write(getTextOfNodeFromSourceText(text, node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
write,
|
write,
|
||||||
rawWrite,
|
rawWrite,
|
||||||
|
@ -1778,6 +1797,7 @@ namespace ts {
|
||||||
getLine: () => lineCount + 1,
|
getLine: () => lineCount + 1,
|
||||||
getColumn: () => lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1,
|
getColumn: () => lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1,
|
||||||
getText: () => output,
|
getText: () => output,
|
||||||
|
reset
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1791,7 +1811,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOwnEmitOutputFilePath(sourceFile: SourceFile, host: EmitHost, extension: string) {
|
export function getOwnEmitOutputFilePath(sourceFile: SourceFile, host: EmitHost, extension: string) {
|
||||||
let compilerOptions = host.getCompilerOptions();
|
const compilerOptions = host.getCompilerOptions();
|
||||||
let emitOutputFilePathWithoutExtension: string;
|
let emitOutputFilePathWithoutExtension: string;
|
||||||
if (compilerOptions.outDir) {
|
if (compilerOptions.outDir) {
|
||||||
emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir));
|
emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir));
|
||||||
|
@ -1819,6 +1839,10 @@ namespace ts {
|
||||||
return getLineAndCharacterOfPosition(currentSourceFile, pos).line;
|
return getLineAndCharacterOfPosition(currentSourceFile, pos).line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLineOfLocalPositionFromLineMap(lineMap: number[], pos: number) {
|
||||||
|
return computeLineAndCharacterOfPosition(lineMap, pos).line;
|
||||||
|
}
|
||||||
|
|
||||||
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration {
|
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration {
|
||||||
return forEach(node.members, member => {
|
return forEach(node.members, member => {
|
||||||
if (member.kind === SyntaxKind.Constructor && nodeIsPresent((<ConstructorDeclaration>member).body)) {
|
if (member.kind === SyntaxKind.Constructor && nodeIsPresent((<ConstructorDeclaration>member).body)) {
|
||||||
|
@ -1864,8 +1888,8 @@ namespace ts {
|
||||||
forEach(declarations, (member: Declaration) => {
|
forEach(declarations, (member: Declaration) => {
|
||||||
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
|
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
|
||||||
&& (member.flags & NodeFlags.Static) === (accessor.flags & NodeFlags.Static)) {
|
&& (member.flags & NodeFlags.Static) === (accessor.flags & NodeFlags.Static)) {
|
||||||
let memberName = getPropertyNameForPropertyNameNode(member.name);
|
const memberName = getPropertyNameForPropertyNameNode(member.name);
|
||||||
let accessorName = getPropertyNameForPropertyNameNode(accessor.name);
|
const accessorName = getPropertyNameForPropertyNameNode(accessor.name);
|
||||||
if (memberName === accessorName) {
|
if (memberName === accessorName) {
|
||||||
if (!firstAccessor) {
|
if (!firstAccessor) {
|
||||||
firstAccessor = <AccessorDeclaration>member;
|
firstAccessor = <AccessorDeclaration>member;
|
||||||
|
@ -1893,23 +1917,23 @@ namespace ts {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emitNewLineBeforeLeadingComments(currentSourceFile: SourceFile, writer: EmitTextWriter, node: TextRange, leadingComments: CommentRange[]) {
|
export function emitNewLineBeforeLeadingComments(lineMap: number[], writer: EmitTextWriter, node: TextRange, leadingComments: CommentRange[]) {
|
||||||
// If the leading comments start on different line than the start of node, write new line
|
// If the leading comments start on different line than the start of node, write new line
|
||||||
if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
|
if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
|
||||||
getLineOfLocalPosition(currentSourceFile, node.pos) !== getLineOfLocalPosition(currentSourceFile, leadingComments[0].pos)) {
|
getLineOfLocalPositionFromLineMap(lineMap, node.pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
|
||||||
writer.writeLine();
|
writer.writeLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emitComments(currentSourceFile: SourceFile, writer: EmitTextWriter, comments: CommentRange[], trailingSeparator: boolean, newLine: string,
|
export function emitComments(text: string, lineMap: number[], writer: EmitTextWriter, comments: CommentRange[], trailingSeparator: boolean, newLine: string,
|
||||||
writeComment: (currentSourceFile: SourceFile, writer: EmitTextWriter, comment: CommentRange, newLine: string) => void) {
|
writeComment: (text: string, lineMap: number[], writer: EmitTextWriter, comment: CommentRange, newLine: string) => void) {
|
||||||
let emitLeadingSpace = !trailingSeparator;
|
let emitLeadingSpace = !trailingSeparator;
|
||||||
forEach(comments, comment => {
|
forEach(comments, comment => {
|
||||||
if (emitLeadingSpace) {
|
if (emitLeadingSpace) {
|
||||||
writer.write(" ");
|
writer.write(" ");
|
||||||
emitLeadingSpace = false;
|
emitLeadingSpace = false;
|
||||||
}
|
}
|
||||||
writeComment(currentSourceFile, writer, comment, newLine);
|
writeComment(text, lineMap, writer, comment, newLine);
|
||||||
if (comment.hasTrailingNewLine) {
|
if (comment.hasTrailingNewLine) {
|
||||||
writer.writeLine();
|
writer.writeLine();
|
||||||
}
|
}
|
||||||
|
@ -1927,8 +1951,8 @@ namespace ts {
|
||||||
* Detached comment is a comment at the top of file or function body that is separated from
|
* Detached comment is a comment at the top of file or function body that is separated from
|
||||||
* the next statement by space.
|
* the next statement by space.
|
||||||
*/
|
*/
|
||||||
export function emitDetachedComments(currentSourceFile: SourceFile, writer: EmitTextWriter,
|
export function emitDetachedComments(text: string, lineMap: number[], writer: EmitTextWriter,
|
||||||
writeComment: (currentSourceFile: SourceFile, writer: EmitTextWriter, comment: CommentRange, newLine: string) => void,
|
writeComment: (text: string, lineMap: number[], writer: EmitTextWriter, comment: CommentRange, newLine: string) => void,
|
||||||
node: TextRange, newLine: string, removeComments: boolean) {
|
node: TextRange, newLine: string, removeComments: boolean) {
|
||||||
let leadingComments: CommentRange[];
|
let leadingComments: CommentRange[];
|
||||||
let currentDetachedCommentInfo: {nodePos: number, detachedCommentEndPos: number};
|
let currentDetachedCommentInfo: {nodePos: number, detachedCommentEndPos: number};
|
||||||
|
@ -1939,22 +1963,22 @@ namespace ts {
|
||||||
//
|
//
|
||||||
// var x = 10;
|
// var x = 10;
|
||||||
if (node.pos === 0) {
|
if (node.pos === 0) {
|
||||||
leadingComments = filter(getLeadingCommentRanges(currentSourceFile.text, node.pos), isPinnedComment);
|
leadingComments = filter(getLeadingCommentRanges(text, node.pos), isPinnedComment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// removeComments is false, just get detached as normal and bypass the process to filter comment
|
// removeComments is false, just get detached as normal and bypass the process to filter comment
|
||||||
leadingComments = getLeadingCommentRanges(currentSourceFile.text, node.pos);
|
leadingComments = getLeadingCommentRanges(text, node.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leadingComments) {
|
if (leadingComments) {
|
||||||
let detachedComments: CommentRange[] = [];
|
const detachedComments: CommentRange[] = [];
|
||||||
let lastComment: CommentRange;
|
let lastComment: CommentRange;
|
||||||
|
|
||||||
for (let comment of leadingComments) {
|
for (const comment of leadingComments) {
|
||||||
if (lastComment) {
|
if (lastComment) {
|
||||||
let lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
|
const lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
|
||||||
let commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
|
const commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
|
||||||
|
|
||||||
if (commentLine >= lastCommentLine + 2) {
|
if (commentLine >= lastCommentLine + 2) {
|
||||||
// There was a blank line between the last comment and this comment. This
|
// There was a blank line between the last comment and this comment. This
|
||||||
|
@ -1972,12 +1996,12 @@ namespace ts {
|
||||||
// All comments look like they could have been part of the copyright header. Make
|
// All comments look like they could have been part of the copyright header. Make
|
||||||
// sure there is at least one blank line between it and the node. If not, it's not
|
// sure there is at least one blank line between it and the node. If not, it's not
|
||||||
// a copyright header.
|
// a copyright header.
|
||||||
let lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastOrUndefined(detachedComments).end);
|
const lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastOrUndefined(detachedComments).end);
|
||||||
let nodeLine = getLineOfLocalPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.pos));
|
const nodeLine = getLineOfLocalPositionFromLineMap(lineMap, skipTrivia(text, node.pos));
|
||||||
if (nodeLine >= lastCommentLine + 2) {
|
if (nodeLine >= lastCommentLine + 2) {
|
||||||
// Valid detachedComments
|
// Valid detachedComments
|
||||||
emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
|
emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
|
||||||
emitComments(currentSourceFile, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
|
emitComments(text, lineMap, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||||
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end };
|
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1986,29 +2010,30 @@ namespace ts {
|
||||||
return currentDetachedCommentInfo;
|
return currentDetachedCommentInfo;
|
||||||
|
|
||||||
function isPinnedComment(comment: CommentRange) {
|
function isPinnedComment(comment: CommentRange) {
|
||||||
return currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
|
return text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
|
||||||
currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.exclamation;
|
text.charCodeAt(comment.pos + 2) === CharacterCodes.exclamation;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function writeCommentRange(currentSourceFile: SourceFile, writer: EmitTextWriter, comment: CommentRange, newLine: string) {
|
}
|
||||||
if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) {
|
|
||||||
let firstCommentLineAndCharacter = getLineAndCharacterOfPosition(currentSourceFile, comment.pos);
|
export function writeCommentRange(text: string, lineMap: number[], writer: EmitTextWriter, comment: CommentRange, newLine: string) {
|
||||||
let lineCount = getLineStarts(currentSourceFile).length;
|
if (text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) {
|
||||||
|
const firstCommentLineAndCharacter = computeLineAndCharacterOfPosition(lineMap, comment.pos);
|
||||||
|
const lineCount = lineMap.length;
|
||||||
let firstCommentLineIndent: number;
|
let firstCommentLineIndent: number;
|
||||||
for (let pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
|
for (let pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
|
||||||
let nextLineStart = (currentLine + 1) === lineCount
|
const nextLineStart = (currentLine + 1) === lineCount
|
||||||
? currentSourceFile.text.length + 1
|
? text.length + 1
|
||||||
: getStartPositionOfLine(currentLine + 1, currentSourceFile);
|
: lineMap[currentLine + 1];
|
||||||
|
|
||||||
if (pos !== comment.pos) {
|
if (pos !== comment.pos) {
|
||||||
// If we are not emitting first line, we need to write the spaces to adjust the alignment
|
// If we are not emitting first line, we need to write the spaces to adjust the alignment
|
||||||
if (firstCommentLineIndent === undefined) {
|
if (firstCommentLineIndent === undefined) {
|
||||||
firstCommentLineIndent = calculateIndent(getStartPositionOfLine(firstCommentLineAndCharacter.line, currentSourceFile), comment.pos);
|
firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], comment.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are number of spaces writer is going to write at current indent
|
// These are number of spaces writer is going to write at current indent
|
||||||
let currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
|
const currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
|
||||||
|
|
||||||
// Number of spaces we want to be writing
|
// Number of spaces we want to be writing
|
||||||
// eg: Assume writer indent
|
// eg: Assume writer indent
|
||||||
|
@ -2024,10 +2049,10 @@ namespace ts {
|
||||||
// More right indented comment */ --4 = 8 - 4 + 11
|
// More right indented comment */ --4 = 8 - 4 + 11
|
||||||
// class c { }
|
// class c { }
|
||||||
// }
|
// }
|
||||||
let spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(pos, nextLineStart);
|
const spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
|
||||||
if (spacesToEmit > 0) {
|
if (spacesToEmit > 0) {
|
||||||
let numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
|
let numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
|
||||||
let indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
|
const indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
|
||||||
|
|
||||||
// Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces
|
// Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces
|
||||||
writer.rawWrite(indentSizeSpaceString);
|
writer.rawWrite(indentSizeSpaceString);
|
||||||
|
@ -2045,19 +2070,20 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the comment line text
|
// Write the comment line text
|
||||||
writeTrimmedCurrentLine(pos, nextLineStart);
|
writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart);
|
||||||
|
|
||||||
pos = nextLineStart;
|
pos = nextLineStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Single line comment of style //....
|
// Single line comment of style //....
|
||||||
writer.write(currentSourceFile.text.substring(comment.pos, comment.end));
|
writer.write(text.substring(comment.pos, comment.end));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTrimmedCurrentLine(pos: number, nextLineStart: number) {
|
function writeTrimmedCurrentLine(text: string, comment: CommentRange, writer: EmitTextWriter, newLine: string, pos: number, nextLineStart: number) {
|
||||||
let end = Math.min(comment.end, nextLineStart - 1);
|
const end = Math.min(comment.end, nextLineStart - 1);
|
||||||
let currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, "");
|
const currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
|
||||||
if (currentLineText) {
|
if (currentLineText) {
|
||||||
// trimmed forward and ending spaces text
|
// trimmed forward and ending spaces text
|
||||||
writer.write(currentLineText);
|
writer.write(currentLineText);
|
||||||
|
@ -2071,10 +2097,10 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateIndent(pos: number, end: number) {
|
function calculateIndent(text: string, pos: number, end: number) {
|
||||||
let currentLineIndent = 0;
|
let currentLineIndent = 0;
|
||||||
for (; pos < end && isWhiteSpace(currentSourceFile.text.charCodeAt(pos)); pos++) {
|
for (; pos < end && isWhiteSpace(text.charCodeAt(pos)); pos++) {
|
||||||
if (currentSourceFile.text.charCodeAt(pos) === CharacterCodes.tab) {
|
if (text.charCodeAt(pos) === CharacterCodes.tab) {
|
||||||
// Tabs = TabSize = indent size and go to next tabStop
|
// Tabs = TabSize = indent size and go to next tabStop
|
||||||
currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
|
currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
|
||||||
}
|
}
|
||||||
|
@ -2086,7 +2112,6 @@ namespace ts {
|
||||||
|
|
||||||
return currentLineIndent;
|
return currentLineIndent;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export function modifierToFlag(token: SyntaxKind): NodeFlags {
|
export function modifierToFlag(token: SyntaxKind): NodeFlags {
|
||||||
switch (token) {
|
switch (token) {
|
||||||
|
@ -2171,7 +2196,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isEmptyObjectLiteralOrArrayLiteral(expression: Node): boolean {
|
export function isEmptyObjectLiteralOrArrayLiteral(expression: Node): boolean {
|
||||||
let kind = expression.kind;
|
const kind = expression.kind;
|
||||||
if (kind === SyntaxKind.ObjectLiteralExpression) {
|
if (kind === SyntaxKind.ObjectLiteralExpression) {
|
||||||
return (<ObjectLiteralExpression>expression).properties.length === 0;
|
return (<ObjectLiteralExpression>expression).properties.length === 0;
|
||||||
}
|
}
|
||||||
|
@ -2198,11 +2223,11 @@ namespace ts {
|
||||||
* representing the UTF-8 encoding of the character, and return the expanded char code list.
|
* representing the UTF-8 encoding of the character, and return the expanded char code list.
|
||||||
*/
|
*/
|
||||||
function getExpandedCharCodes(input: string): number[] {
|
function getExpandedCharCodes(input: string): number[] {
|
||||||
let output: number[] = [];
|
const output: number[] = [];
|
||||||
let length = input.length;
|
const length = input.length;
|
||||||
|
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
let charCode = input.charCodeAt(i);
|
const charCode = input.charCodeAt(i);
|
||||||
|
|
||||||
// handel utf8
|
// handel utf8
|
||||||
if (charCode < 0x80) {
|
if (charCode < 0x80) {
|
||||||
|
@ -2238,9 +2263,9 @@ namespace ts {
|
||||||
*/
|
*/
|
||||||
export function convertToBase64(input: string): string {
|
export function convertToBase64(input: string): string {
|
||||||
let result = "";
|
let result = "";
|
||||||
let charCodes = getExpandedCharCodes(input);
|
const charCodes = getExpandedCharCodes(input);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let length = charCodes.length;
|
const length = charCodes.length;
|
||||||
let byte1: number, byte2: number, byte3: number, byte4: number;
|
let byte1: number, byte2: number, byte3: number, byte4: number;
|
||||||
|
|
||||||
while (i < length) {
|
while (i < length) {
|
||||||
|
@ -2314,14 +2339,14 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function textSpanOverlapsWith(span: TextSpan, other: TextSpan) {
|
export function textSpanOverlapsWith(span: TextSpan, other: TextSpan) {
|
||||||
let overlapStart = Math.max(span.start, other.start);
|
const overlapStart = Math.max(span.start, other.start);
|
||||||
let overlapEnd = Math.min(textSpanEnd(span), textSpanEnd(other));
|
const overlapEnd = Math.min(textSpanEnd(span), textSpanEnd(other));
|
||||||
return overlapStart < overlapEnd;
|
return overlapStart < overlapEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function textSpanOverlap(span1: TextSpan, span2: TextSpan) {
|
export function textSpanOverlap(span1: TextSpan, span2: TextSpan) {
|
||||||
let overlapStart = Math.max(span1.start, span2.start);
|
const overlapStart = Math.max(span1.start, span2.start);
|
||||||
let overlapEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
|
const overlapEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
|
||||||
if (overlapStart < overlapEnd) {
|
if (overlapStart < overlapEnd) {
|
||||||
return createTextSpanFromBounds(overlapStart, overlapEnd);
|
return createTextSpanFromBounds(overlapStart, overlapEnd);
|
||||||
}
|
}
|
||||||
|
@ -2333,13 +2358,13 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function textSpanIntersectsWith(span: TextSpan, start: number, length: number) {
|
export function textSpanIntersectsWith(span: TextSpan, start: number, length: number) {
|
||||||
let end = start + length;
|
const end = start + length;
|
||||||
return start <= textSpanEnd(span) && end >= span.start;
|
return start <= textSpanEnd(span) && end >= span.start;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodedTextSpanIntersectsWith(start1: number, length1: number, start2: number, length2: number) {
|
export function decodedTextSpanIntersectsWith(start1: number, length1: number, start2: number, length2: number) {
|
||||||
let end1 = start1 + length1;
|
const end1 = start1 + length1;
|
||||||
let end2 = start2 + length2;
|
const end2 = start2 + length2;
|
||||||
return start2 <= end1 && end2 >= start1;
|
return start2 <= end1 && end2 >= start1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2348,8 +2373,8 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function textSpanIntersection(span1: TextSpan, span2: TextSpan) {
|
export function textSpanIntersection(span1: TextSpan, span2: TextSpan) {
|
||||||
let intersectStart = Math.max(span1.start, span2.start);
|
const intersectStart = Math.max(span1.start, span2.start);
|
||||||
let intersectEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
|
const intersectEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2));
|
||||||
if (intersectStart <= intersectEnd) {
|
if (intersectStart <= intersectEnd) {
|
||||||
return createTextSpanFromBounds(intersectStart, intersectEnd);
|
return createTextSpanFromBounds(intersectStart, intersectEnd);
|
||||||
}
|
}
|
||||||
|
@ -2408,14 +2433,14 @@ namespace ts {
|
||||||
|
|
||||||
// We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd }
|
// We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd }
|
||||||
// as it makes things much easier to reason about.
|
// as it makes things much easier to reason about.
|
||||||
let change0 = changes[0];
|
const change0 = changes[0];
|
||||||
|
|
||||||
let oldStartN = change0.span.start;
|
let oldStartN = change0.span.start;
|
||||||
let oldEndN = textSpanEnd(change0.span);
|
let oldEndN = textSpanEnd(change0.span);
|
||||||
let newEndN = oldStartN + change0.newLength;
|
let newEndN = oldStartN + change0.newLength;
|
||||||
|
|
||||||
for (let i = 1; i < changes.length; i++) {
|
for (let i = 1; i < changes.length; i++) {
|
||||||
let nextChange = changes[i];
|
const nextChange = changes[i];
|
||||||
|
|
||||||
// Consider the following case:
|
// Consider the following case:
|
||||||
// i.e. two edits. The first represents the text change range { { 10, 50 }, 30 }. i.e. The span starting
|
// i.e. two edits. The first represents the text change range { { 10, 50 }, 30 }. i.e. The span starting
|
||||||
|
@ -2497,13 +2522,13 @@ namespace ts {
|
||||||
// newEnd3 : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
|
// newEnd3 : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let oldStart1 = oldStartN;
|
const oldStart1 = oldStartN;
|
||||||
let oldEnd1 = oldEndN;
|
const oldEnd1 = oldEndN;
|
||||||
let newEnd1 = newEndN;
|
const newEnd1 = newEndN;
|
||||||
|
|
||||||
let oldStart2 = nextChange.span.start;
|
const oldStart2 = nextChange.span.start;
|
||||||
let oldEnd2 = textSpanEnd(nextChange.span);
|
const oldEnd2 = textSpanEnd(nextChange.span);
|
||||||
let newEnd2 = oldStart2 + nextChange.newLength;
|
const newEnd2 = oldStart2 + nextChange.newLength;
|
||||||
|
|
||||||
oldStartN = Math.min(oldStart1, oldStart2);
|
oldStartN = Math.min(oldStart1, oldStart2);
|
||||||
oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
|
oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
|
||||||
|
|
|
@ -140,7 +140,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
it("Correct sourcemap content for " + fileName, () => {
|
it("Correct sourcemap content for " + fileName, () => {
|
||||||
if (options.sourceMap || options.inlineSourceMap) {
|
if (options.sourceMap || options.inlineSourceMap) {
|
||||||
Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
|
Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
|
||||||
let record = result.getSourceMapRecord();
|
const record = result.getSourceMapRecord();
|
||||||
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
|
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
|
||||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn"t required.
|
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn"t required.
|
||||||
return null;
|
return null;
|
||||||
|
@ -159,7 +159,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
// check js output
|
// check js output
|
||||||
Harness.Baseline.runBaseline("Correct JS output for " + fileName, justName.replace(/\.tsx?/, ".js"), () => {
|
Harness.Baseline.runBaseline("Correct JS output for " + fileName, justName.replace(/\.tsx?/, ".js"), () => {
|
||||||
let tsCode = "";
|
let tsCode = "";
|
||||||
let tsSources = otherFiles.concat(toBeCompiled);
|
const tsSources = otherFiles.concat(toBeCompiled);
|
||||||
if (tsSources.length > 1) {
|
if (tsSources.length > 1) {
|
||||||
tsCode += "//// [" + fileName + "] ////\r\n\r\n";
|
tsCode += "//// [" + fileName + "] ////\r\n\r\n";
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
|
const declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
|
||||||
harnessCompiler.setCompilerSettings(tcSettings);
|
harnessCompiler.setCompilerSettings(tcSettings);
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
|
@ -257,15 +257,15 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
// These types are equivalent, but depend on what order the compiler observed
|
// These types are equivalent, but depend on what order the compiler observed
|
||||||
// certain parts of the program.
|
// certain parts of the program.
|
||||||
|
|
||||||
let allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName));
|
const allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName));
|
||||||
|
|
||||||
let fullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ true);
|
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ true);
|
||||||
let pullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ false);
|
const pullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ false);
|
||||||
|
|
||||||
let fullResults: ts.Map<TypeWriterResult[]> = {};
|
const fullResults: ts.Map<TypeWriterResult[]> = {};
|
||||||
let pullResults: ts.Map<TypeWriterResult[]> = {};
|
const pullResults: ts.Map<TypeWriterResult[]> = {};
|
||||||
|
|
||||||
for (let sourceFile of allFiles) {
|
for (const sourceFile of allFiles) {
|
||||||
fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||||
pullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
pullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||||
}
|
}
|
||||||
|
@ -294,11 +294,11 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function checkBaseLines(isSymbolBaseLine: boolean) {
|
function checkBaseLines(isSymbolBaseLine: boolean) {
|
||||||
let fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
|
const fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
|
||||||
let pullBaseLine = generateBaseLine(pullResults, isSymbolBaseLine);
|
const pullBaseLine = generateBaseLine(pullResults, isSymbolBaseLine);
|
||||||
|
|
||||||
let fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
|
const fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
|
||||||
let pullExtension = isSymbolBaseLine ? ".symbols.pull" : ".types.pull";
|
const pullExtension = isSymbolBaseLine ? ".symbols.pull" : ".types.pull";
|
||||||
|
|
||||||
if (fullBaseLine !== pullBaseLine) {
|
if (fullBaseLine !== pullBaseLine) {
|
||||||
Harness.Baseline.runBaseline("Correct full information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
Harness.Baseline.runBaseline("Correct full information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
||||||
|
@ -310,24 +310,24 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||||
let typeLines: string[] = [];
|
const typeLines: string[] = [];
|
||||||
let typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
const typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||||
|
|
||||||
allFiles.forEach(file => {
|
allFiles.forEach(file => {
|
||||||
let codeLines = file.content.split("\n");
|
const codeLines = file.content.split("\n");
|
||||||
typeWriterResults[file.unitName].forEach(result => {
|
typeWriterResults[file.unitName].forEach(result => {
|
||||||
if (isSymbolBaseline && !result.symbol) {
|
if (isSymbolBaseline && !result.symbol) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type;
|
const typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type;
|
||||||
let formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString;
|
const formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString;
|
||||||
if (!typeMap[file.unitName]) {
|
if (!typeMap[file.unitName]) {
|
||||||
typeMap[file.unitName] = {};
|
typeMap[file.unitName] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
let typeInfo = [formattedLine];
|
let typeInfo = [formattedLine];
|
||||||
let existingTypeInfo = typeMap[file.unitName][result.line];
|
const existingTypeInfo = typeMap[file.unitName][result.line];
|
||||||
if (existingTypeInfo) {
|
if (existingTypeInfo) {
|
||||||
typeInfo = existingTypeInfo.concat(typeInfo);
|
typeInfo = existingTypeInfo.concat(typeInfo);
|
||||||
}
|
}
|
||||||
|
@ -336,10 +336,10 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
|
|
||||||
typeLines.push("=== " + file.unitName + " ===\r\n");
|
typeLines.push("=== " + file.unitName + " ===\r\n");
|
||||||
for (let i = 0; i < codeLines.length; i++) {
|
for (let i = 0; i < codeLines.length; i++) {
|
||||||
let currentCodeLine = codeLines[i];
|
const currentCodeLine = codeLines[i];
|
||||||
typeLines.push(currentCodeLine + "\r\n");
|
typeLines.push(currentCodeLine + "\r\n");
|
||||||
if (typeMap[file.unitName]) {
|
if (typeMap[file.unitName]) {
|
||||||
let typeInfo = typeMap[file.unitName][i];
|
const typeInfo = typeMap[file.unitName][i];
|
||||||
if (typeInfo) {
|
if (typeInfo) {
|
||||||
typeInfo.forEach(ty => {
|
typeInfo.forEach(ty => {
|
||||||
typeLines.push(">" + ty + "\r\n");
|
typeLines.push(">" + ty + "\r\n");
|
||||||
|
@ -367,13 +367,13 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
public initializeTests() {
|
public initializeTests() {
|
||||||
describe(this.testSuiteName + " tests", () => {
|
describe(this.testSuiteName + " tests", () => {
|
||||||
describe("Setup compiler for compiler baselines", () => {
|
describe("Setup compiler for compiler baselines", () => {
|
||||||
let harnessCompiler = Harness.Compiler.getCompiler();
|
const harnessCompiler = Harness.Compiler.getCompiler();
|
||||||
this.parseOptions();
|
this.parseOptions();
|
||||||
});
|
});
|
||||||
|
|
||||||
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
|
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
|
||||||
if (this.tests.length === 0) {
|
if (this.tests.length === 0) {
|
||||||
let testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true });
|
const testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true });
|
||||||
testFiles.forEach(fn => {
|
testFiles.forEach(fn => {
|
||||||
fn = fn.replace(/\\/g, "/");
|
fn = fn.replace(/\\/g, "/");
|
||||||
this.checkTestCodeOutput(fn);
|
this.checkTestCodeOutput(fn);
|
||||||
|
@ -392,7 +392,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||||
this.decl = false;
|
this.decl = false;
|
||||||
this.output = false;
|
this.output = false;
|
||||||
|
|
||||||
let opts = this.options.split(",");
|
const opts = this.options.split(",");
|
||||||
for (let i = 0; i < opts.length; i++) {
|
for (let i = 0; i < opts.length; i++) {
|
||||||
switch (opts[i]) {
|
switch (opts[i]) {
|
||||||
case "error":
|
case "error":
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -45,10 +45,10 @@ class FourSlashRunner extends RunnerBase {
|
||||||
this.tests.forEach((fn: string) => {
|
this.tests.forEach((fn: string) => {
|
||||||
describe(fn, () => {
|
describe(fn, () => {
|
||||||
fn = ts.normalizeSlashes(fn);
|
fn = ts.normalizeSlashes(fn);
|
||||||
let justName = fn.replace(/^.*[\\\/]/, "");
|
const justName = fn.replace(/^.*[\\\/]/, "");
|
||||||
|
|
||||||
// Convert to relative path
|
// Convert to relative path
|
||||||
let testIndex = fn.indexOf("tests/");
|
const testIndex = fn.indexOf("tests/");
|
||||||
if (testIndex >= 0) fn = fn.substr(testIndex);
|
if (testIndex >= 0) fn = fn.substr(testIndex);
|
||||||
|
|
||||||
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) {
|
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) {
|
||||||
|
@ -60,21 +60,21 @@ class FourSlashRunner extends RunnerBase {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Generate Tao XML", () => {
|
describe("Generate Tao XML", () => {
|
||||||
let invalidReasons: any = {};
|
const invalidReasons: any = {};
|
||||||
FourSlash.xmlData.forEach(xml => {
|
FourSlash.xmlData.forEach(xml => {
|
||||||
if (xml.invalidReason !== null) {
|
if (xml.invalidReason !== null) {
|
||||||
invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1;
|
invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let invalidReport: { reason: string; count: number }[] = [];
|
const invalidReport: { reason: string; count: number }[] = [];
|
||||||
for (let reason in invalidReasons) {
|
for (const reason in invalidReasons) {
|
||||||
if (invalidReasons.hasOwnProperty(reason)) {
|
if (invalidReasons.hasOwnProperty(reason)) {
|
||||||
invalidReport.push({ reason: reason, count: invalidReasons[reason] });
|
invalidReport.push({ reason: reason, count: invalidReasons[reason] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
|
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
|
||||||
|
|
||||||
let lines: string[] = [];
|
const lines: string[] = [];
|
||||||
lines.push("<!-- Blocked Test Report");
|
lines.push("<!-- Blocked Test Report");
|
||||||
invalidReport.forEach((reasonAndCount) => {
|
invalidReport.forEach((reasonAndCount) => {
|
||||||
lines.push(reasonAndCount.count + " tests blocked by " + reasonAndCount.reason);
|
lines.push(reasonAndCount.count + " tests blocked by " + reasonAndCount.reason);
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function evalFile(fileContents: string, fileName: string, nodeContext?: any) {
|
export function evalFile(fileContents: string, fileName: string, nodeContext?: any) {
|
||||||
let environment = getExecutionEnvironment();
|
const environment = getExecutionEnvironment();
|
||||||
switch (environment) {
|
switch (environment) {
|
||||||
case ExecutionEnvironment.CScript:
|
case ExecutionEnvironment.CScript:
|
||||||
case ExecutionEnvironment.Browser:
|
case ExecutionEnvironment.Browser:
|
||||||
|
@ -121,11 +121,11 @@ namespace Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function memoize<T extends Function>(f: T): T {
|
export function memoize<T extends Function>(f: T): T {
|
||||||
let cache: { [idx: string]: any } = {};
|
const cache: { [idx: string]: any } = {};
|
||||||
|
|
||||||
return <any>(function () {
|
return <any>(function () {
|
||||||
let key = Array.prototype.join.call(arguments);
|
const key = Array.prototype.join.call(arguments);
|
||||||
let cachedResult = cache[key];
|
const cachedResult = cache[key];
|
||||||
if (cachedResult) {
|
if (cachedResult) {
|
||||||
return cachedResult;
|
return cachedResult;
|
||||||
}
|
}
|
||||||
|
@ -172,14 +172,14 @@ namespace Utils {
|
||||||
currentPos = array.end;
|
currentPos = array.end;
|
||||||
});
|
});
|
||||||
|
|
||||||
let childNodesAndArrays: any[] = [];
|
const childNodesAndArrays: any[] = [];
|
||||||
ts.forEachChild(node, child => { childNodesAndArrays.push(child); }, array => { childNodesAndArrays.push(array); });
|
ts.forEachChild(node, child => { childNodesAndArrays.push(child); }, array => { childNodesAndArrays.push(array); });
|
||||||
|
|
||||||
for (let childName in node) {
|
for (const childName in node) {
|
||||||
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator") {
|
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let child = (<any>node)[childName];
|
const child = (<any>node)[childName];
|
||||||
if (isNodeOrArray(child)) {
|
if (isNodeOrArray(child)) {
|
||||||
assert.isFalse(childNodesAndArrays.indexOf(child) < 0,
|
assert.isFalse(childNodesAndArrays.indexOf(child) < 0,
|
||||||
"Missing child when forEach'ing over node: " + (<any>ts).SyntaxKind[node.kind] + "-" + childName);
|
"Missing child when forEach'ing over node: " + (<any>ts).SyntaxKind[node.kind] + "-" + childName);
|
||||||
|
@ -247,7 +247,7 @@ namespace Utils {
|
||||||
function getParserContextFlagName(f: number) { return getFlagName((<any>ts).ParserContextFlags, f); }
|
function getParserContextFlagName(f: number) { return getFlagName((<any>ts).ParserContextFlags, f); }
|
||||||
|
|
||||||
function serializeNode(n: ts.Node): any {
|
function serializeNode(n: ts.Node): any {
|
||||||
let o: any = { kind: getKindName(n.kind) };
|
const o: any = { kind: getKindName(n.kind) };
|
||||||
if (ts.containsParseError(n)) {
|
if (ts.containsParseError(n)) {
|
||||||
o.containsParseError = true;
|
o.containsParseError = true;
|
||||||
}
|
}
|
||||||
|
@ -329,8 +329,8 @@ namespace Utils {
|
||||||
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
|
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
|
||||||
|
|
||||||
for (let i = 0, n = array1.length; i < n; i++) {
|
for (let i = 0, n = array1.length; i < n; i++) {
|
||||||
let d1 = array1[i];
|
const d1 = array1[i];
|
||||||
let d2 = array2[i];
|
const d2 = array2[i];
|
||||||
|
|
||||||
assert.equal(d1.start, d2.start, "d1.start !== d2.start");
|
assert.equal(d1.start, d2.start, "d1.start !== d2.start");
|
||||||
assert.equal(d1.length, d2.length, "d1.length !== d2.length");
|
assert.equal(d1.length, d2.length, "d1.length !== d2.length");
|
||||||
|
@ -361,14 +361,14 @@ namespace Utils {
|
||||||
|
|
||||||
ts.forEachChild(node1,
|
ts.forEachChild(node1,
|
||||||
child1 => {
|
child1 => {
|
||||||
let childName = findChildName(node1, child1);
|
const childName = findChildName(node1, child1);
|
||||||
let child2: ts.Node = (<any>node2)[childName];
|
const child2: ts.Node = (<any>node2)[childName];
|
||||||
|
|
||||||
assertStructuralEquals(child1, child2);
|
assertStructuralEquals(child1, child2);
|
||||||
},
|
},
|
||||||
(array1: ts.NodeArray<ts.Node>) => {
|
(array1: ts.NodeArray<ts.Node>) => {
|
||||||
let childName = findChildName(node1, array1);
|
const childName = findChildName(node1, array1);
|
||||||
let array2: ts.NodeArray<ts.Node> = (<any>node2)[childName];
|
const array2: ts.NodeArray<ts.Node> = (<any>node2)[childName];
|
||||||
|
|
||||||
assertArrayStructuralEquals(array1, array2);
|
assertArrayStructuralEquals(array1, array2);
|
||||||
});
|
});
|
||||||
|
@ -391,7 +391,7 @@ namespace Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
function findChildName(parent: any, child: any) {
|
function findChildName(parent: any, child: any) {
|
||||||
for (let name in parent) {
|
for (const name in parent) {
|
||||||
if (parent.hasOwnProperty(name) && parent[name] === child) {
|
if (parent.hasOwnProperty(name) && parent[name] === child) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -408,8 +408,8 @@ namespace Harness.Path {
|
||||||
|
|
||||||
export function filePath(fullPath: string) {
|
export function filePath(fullPath: string) {
|
||||||
fullPath = ts.normalizeSlashes(fullPath);
|
fullPath = ts.normalizeSlashes(fullPath);
|
||||||
let components = fullPath.split("/");
|
const components = fullPath.split("/");
|
||||||
let path: string[] = components.slice(0, components.length - 1);
|
const path: string[] = components.slice(0, components.length - 1);
|
||||||
return path.join("/") + "/";
|
return path.join("/") + "/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,15 +510,15 @@ namespace Harness {
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
let folder: any = fso.GetFolder(path);
|
const folder: any = fso.GetFolder(path);
|
||||||
let paths: string[] = [];
|
const paths: string[] = [];
|
||||||
|
|
||||||
return filesInFolder(folder, path);
|
return filesInFolder(folder, path);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace Node {
|
export namespace Node {
|
||||||
declare let require: any;
|
declare const require: any;
|
||||||
let fs: any, pathModule: any;
|
let fs: any, pathModule: any;
|
||||||
if (require) {
|
if (require) {
|
||||||
fs = require("fs");
|
fs = require("fs");
|
||||||
|
@ -579,10 +579,10 @@ namespace Harness {
|
||||||
function filesInFolder(folder: string): string[] {
|
function filesInFolder(folder: string): string[] {
|
||||||
let paths: string[] = [];
|
let paths: string[] = [];
|
||||||
|
|
||||||
let files = fs.readdirSync(folder);
|
const files = fs.readdirSync(folder);
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
let pathToFile = pathModule.join(folder, files[i]);
|
const pathToFile = pathModule.join(folder, files[i]);
|
||||||
let stat = fs.statSync(pathToFile);
|
const stat = fs.statSync(pathToFile);
|
||||||
if (options.recursive && stat.isDirectory()) {
|
if (options.recursive && stat.isDirectory()) {
|
||||||
paths = paths.concat(filesInFolder(pathToFile));
|
paths = paths.concat(filesInFolder(pathToFile));
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace Network {
|
export namespace Network {
|
||||||
let serverRoot = "http://localhost:8888/";
|
const serverRoot = "http://localhost:8888/";
|
||||||
|
|
||||||
export const newLine = () => harnessNewLine;
|
export const newLine = () => harnessNewLine;
|
||||||
export const useCaseSensitiveFileNames = () => false;
|
export const useCaseSensitiveFileNames = () => false;
|
||||||
|
@ -615,7 +615,7 @@ namespace Harness {
|
||||||
export const getExecutingFilePath = () => "";
|
export const getExecutingFilePath = () => "";
|
||||||
export const exit = (exitCode: number) => {};
|
export const exit = (exitCode: number) => {};
|
||||||
|
|
||||||
let supportsCodePage = () => false;
|
const supportsCodePage = () => false;
|
||||||
export let log = (s: string) => console.log(s);
|
export let log = (s: string) => console.log(s);
|
||||||
|
|
||||||
namespace Http {
|
namespace Http {
|
||||||
|
@ -626,7 +626,7 @@ namespace Harness {
|
||||||
|
|
||||||
/// Ask the server to use node's path.resolve to resolve the given path
|
/// Ask the server to use node's path.resolve to resolve the given path
|
||||||
function getResolvedPathFromServer(path: string) {
|
function getResolvedPathFromServer(path: string) {
|
||||||
let xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
try {
|
try {
|
||||||
xhr.open("GET", path + "?resolve", false);
|
xhr.open("GET", path + "?resolve", false);
|
||||||
xhr.send();
|
xhr.send();
|
||||||
|
@ -645,7 +645,7 @@ namespace Harness {
|
||||||
|
|
||||||
/// Ask the server for the contents of the file at the given URL via a simple GET request
|
/// Ask the server for the contents of the file at the given URL via a simple GET request
|
||||||
export function getFileFromServerSync(url: string): XHRResponse {
|
export function getFileFromServerSync(url: string): XHRResponse {
|
||||||
let xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
try {
|
try {
|
||||||
xhr.open("GET", url, false);
|
xhr.open("GET", url, false);
|
||||||
xhr.send();
|
xhr.send();
|
||||||
|
@ -659,9 +659,9 @@ namespace Harness {
|
||||||
|
|
||||||
/// Submit a POST request to the server to do the given action (ex WRITE, DELETE) on the provided URL
|
/// Submit a POST request to the server to do the given action (ex WRITE, DELETE) on the provided URL
|
||||||
export function writeToServerSync(url: string, action: string, contents?: string): XHRResponse {
|
export function writeToServerSync(url: string, action: string, contents?: string): XHRResponse {
|
||||||
let xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
try {
|
try {
|
||||||
let actionMsg = "?action=" + action;
|
const actionMsg = "?action=" + action;
|
||||||
xhr.open("POST", url + actionMsg, false);
|
xhr.open("POST", url + actionMsg, false);
|
||||||
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
|
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
|
||||||
xhr.send(contents);
|
xhr.send(contents);
|
||||||
|
@ -712,14 +712,14 @@ namespace Harness {
|
||||||
export const resolvePath = (path: string) => directoryName(path);
|
export const resolvePath = (path: string) => directoryName(path);
|
||||||
|
|
||||||
export function fileExists(path: string): boolean {
|
export function fileExists(path: string): boolean {
|
||||||
let response = Http.getFileFromServerSync(serverRoot + path);
|
const response = Http.getFileFromServerSync(serverRoot + path);
|
||||||
return response.status === 200;
|
return response.status === 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _listFilesImpl(path: string, spec?: RegExp, options?: any) {
|
export function _listFilesImpl(path: string, spec?: RegExp, options?: any) {
|
||||||
let response = Http.getFileFromServerSync(serverRoot + path);
|
const response = Http.getFileFromServerSync(serverRoot + path);
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
let results = response.responseText.split(",");
|
const results = response.responseText.split(",");
|
||||||
if (spec) {
|
if (spec) {
|
||||||
return results.filter(file => spec.test(file));
|
return results.filter(file => spec.test(file));
|
||||||
}
|
}
|
||||||
|
@ -734,7 +734,7 @@ namespace Harness {
|
||||||
export let listFiles = Utils.memoize(_listFilesImpl);
|
export let listFiles = Utils.memoize(_listFilesImpl);
|
||||||
|
|
||||||
export function readFile(file: string) {
|
export function readFile(file: string) {
|
||||||
let response = Http.getFileFromServerSync(serverRoot + file);
|
const response = Http.getFileFromServerSync(serverRoot + file);
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
return response.responseText;
|
return response.responseText;
|
||||||
}
|
}
|
||||||
|
@ -856,10 +856,10 @@ namespace Harness {
|
||||||
public reset() { this.fileCollection = {}; }
|
public reset() { this.fileCollection = {}; }
|
||||||
|
|
||||||
public toArray(): { fileName: string; file: WriterAggregator; }[] {
|
public toArray(): { fileName: string; file: WriterAggregator; }[] {
|
||||||
let result: { fileName: string; file: WriterAggregator; }[] = [];
|
const result: { fileName: string; file: WriterAggregator; }[] = [];
|
||||||
for (let p in this.fileCollection) {
|
for (const p in this.fileCollection) {
|
||||||
if (this.fileCollection.hasOwnProperty(p)) {
|
if (this.fileCollection.hasOwnProperty(p)) {
|
||||||
let current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
|
const current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
|
||||||
if (current.lines.length > 0) {
|
if (current.lines.length > 0) {
|
||||||
if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); }
|
if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); }
|
||||||
result.push({ fileName: p, file: this.fileCollection[p] });
|
result.push({ fileName: p, file: this.fileCollection[p] });
|
||||||
|
@ -878,7 +878,7 @@ namespace Harness {
|
||||||
const shouldAssertInvariants = !Harness.lightMode;
|
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 inletiants. We don't need them otherwise.
|
||||||
let result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
|
const result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
|
||||||
|
|
||||||
if (shouldAssertInvariants) {
|
if (shouldAssertInvariants) {
|
||||||
Utils.assertInvariants(result, /*parent:*/ undefined);
|
Utils.assertInvariants(result, /*parent:*/ undefined);
|
||||||
|
@ -916,13 +916,13 @@ namespace Harness {
|
||||||
return useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
return useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
let filemap: { [fileName: string]: ts.SourceFile; } = {};
|
const filemap: { [fileName: string]: ts.SourceFile; } = {};
|
||||||
let getCurrentDirectory = currentDirectory === undefined ? Harness.IO.getCurrentDirectory : () => currentDirectory;
|
const getCurrentDirectory = currentDirectory === undefined ? Harness.IO.getCurrentDirectory : () => currentDirectory;
|
||||||
|
|
||||||
// Register input files
|
// Register input files
|
||||||
function register(file: { unitName: string; content: string; }) {
|
function register(file: { unitName: string; content: string; }) {
|
||||||
if (file.content !== undefined) {
|
if (file.content !== undefined) {
|
||||||
let fileName = ts.normalizePath(file.unitName);
|
const fileName = ts.normalizePath(file.unitName);
|
||||||
const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
|
const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
|
||||||
filemap[getCanonicalFileName(fileName)] = sourceFile;
|
filemap[getCanonicalFileName(fileName)] = sourceFile;
|
||||||
filemap[getCanonicalFileName(ts.getNormalizedAbsolutePath(fileName, getCurrentDirectory()))] = sourceFile;
|
filemap[getCanonicalFileName(ts.getNormalizedAbsolutePath(fileName, getCurrentDirectory()))] = sourceFile;
|
||||||
|
@ -936,11 +936,11 @@ namespace Harness {
|
||||||
return filemap[getCanonicalFileName(fn)];
|
return filemap[getCanonicalFileName(fn)];
|
||||||
}
|
}
|
||||||
else if (currentDirectory) {
|
else if (currentDirectory) {
|
||||||
let canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
|
const canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
|
||||||
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
|
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
|
||||||
}
|
}
|
||||||
else if (fn === fourslashFileName) {
|
else if (fn === fourslashFileName) {
|
||||||
let tsFn = "tests/cases/fourslash/" + fourslashFileName;
|
const tsFn = "tests/cases/fourslash/" + fourslashFileName;
|
||||||
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
|
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
|
||||||
return fourslashSourceFile;
|
return fourslashSourceFile;
|
||||||
}
|
}
|
||||||
|
@ -953,7 +953,7 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let newLine =
|
const newLine =
|
||||||
newLineKind === ts.NewLineKind.CarriageReturnLineFeed ? carriageReturnLineFeed :
|
newLineKind === ts.NewLineKind.CarriageReturnLineFeed ? carriageReturnLineFeed :
|
||||||
newLineKind === ts.NewLineKind.LineFeed ? lineFeed :
|
newLineKind === ts.NewLineKind.LineFeed ? lineFeed :
|
||||||
Harness.IO.newLine();
|
Harness.IO.newLine();
|
||||||
|
@ -991,8 +991,8 @@ namespace Harness {
|
||||||
function getCommandLineOption(name: string): ts.CommandLineOption {
|
function getCommandLineOption(name: string): ts.CommandLineOption {
|
||||||
if (!optionsIndex) {
|
if (!optionsIndex) {
|
||||||
optionsIndex = {};
|
optionsIndex = {};
|
||||||
let optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations);
|
const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations);
|
||||||
for (let option of optionDeclarations) {
|
for (const option of optionDeclarations) {
|
||||||
optionsIndex[option.name.toLowerCase()] = option;
|
optionsIndex[option.name.toLowerCase()] = option;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1000,13 +1000,13 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setCompilerOptionsFromHarnessSetting(settings: Harness.TestCaseParser.CompilerSettings, options: ts.CompilerOptions & HarnessOptions): void {
|
export function setCompilerOptionsFromHarnessSetting(settings: Harness.TestCaseParser.CompilerSettings, options: ts.CompilerOptions & HarnessOptions): void {
|
||||||
for (let name in settings) {
|
for (const name in settings) {
|
||||||
if (settings.hasOwnProperty(name)) {
|
if (settings.hasOwnProperty(name)) {
|
||||||
let value = settings[name];
|
const value = settings[name];
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
throw new Error(`Cannot have undefined value for compiler option '${name}'.`);
|
throw new Error(`Cannot have undefined value for compiler option '${name}'.`);
|
||||||
}
|
}
|
||||||
let option = getCommandLineOption(name);
|
const option = getCommandLineOption(name);
|
||||||
if (option) {
|
if (option) {
|
||||||
switch (option.type) {
|
switch (option.type) {
|
||||||
case "boolean":
|
case "boolean":
|
||||||
|
@ -1102,37 +1102,37 @@ namespace Harness {
|
||||||
settingsCallback(null);
|
settingsCallback(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
let newLine = "\r\n";
|
const newLine = "\r\n";
|
||||||
|
|
||||||
// Parse settings
|
// Parse settings
|
||||||
setCompilerOptionsFromHarnessSetting(this.settings, options);
|
setCompilerOptionsFromHarnessSetting(this.settings, options);
|
||||||
|
|
||||||
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
|
// 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.
|
// Treat them as library files, so include them in build, but not in baselines.
|
||||||
let includeBuiltFiles: { unitName: string; content: string }[] = [];
|
const includeBuiltFiles: { unitName: string; content: string }[] = [];
|
||||||
if (options.includeBuiltFile) {
|
if (options.includeBuiltFile) {
|
||||||
let builtFileName = libFolder + options.includeBuiltFile;
|
const builtFileName = libFolder + options.includeBuiltFile;
|
||||||
includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) });
|
includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) });
|
||||||
}
|
}
|
||||||
|
|
||||||
let useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : Harness.IO.useCaseSensitiveFileNames();
|
const useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : Harness.IO.useCaseSensitiveFileNames();
|
||||||
|
|
||||||
let fileOutputs: GeneratedFile[] = [];
|
const fileOutputs: GeneratedFile[] = [];
|
||||||
|
|
||||||
let programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
|
const programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
|
||||||
|
|
||||||
let compilerHost = createCompilerHost(
|
const compilerHost = createCompilerHost(
|
||||||
inputFiles.concat(includeBuiltFiles).concat(otherFiles),
|
inputFiles.concat(includeBuiltFiles).concat(otherFiles),
|
||||||
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
|
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
|
||||||
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
|
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
|
||||||
let program = ts.createProgram(programFiles, options, compilerHost);
|
const program = ts.createProgram(programFiles, options, compilerHost);
|
||||||
|
|
||||||
let emitResult = program.emit();
|
const emitResult = program.emit();
|
||||||
|
|
||||||
let errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
const errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
||||||
this.lastErrors = errors;
|
this.lastErrors = errors;
|
||||||
|
|
||||||
let result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
|
const result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
|
||||||
onComplete(result, program);
|
onComplete(result, program);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
@ -1149,8 +1149,8 @@ namespace Harness {
|
||||||
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
|
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
let declInputFiles: { unitName: string; content: string }[] = [];
|
const declInputFiles: { unitName: string; content: string }[] = [];
|
||||||
let declOtherFiles: { unitName: string; content: string }[] = [];
|
const declOtherFiles: { unitName: string; content: string }[] = [];
|
||||||
let declResult: Harness.Compiler.CompilerResult;
|
let declResult: Harness.Compiler.CompilerResult;
|
||||||
|
|
||||||
// if the .d.ts is non-empty, confirm it compiles correctly as well
|
// if the .d.ts is non-empty, confirm it compiles correctly as well
|
||||||
|
@ -1168,18 +1168,18 @@ namespace Harness {
|
||||||
dtsFiles.push(file);
|
dtsFiles.push(file);
|
||||||
}
|
}
|
||||||
else if (isTS(file.unitName)) {
|
else if (isTS(file.unitName)) {
|
||||||
let declFile = findResultCodeFile(file.unitName);
|
const declFile = findResultCodeFile(file.unitName);
|
||||||
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function findResultCodeFile(fileName: string) {
|
function findResultCodeFile(fileName: string) {
|
||||||
let sourceFile = result.program.getSourceFile(fileName);
|
const sourceFile = result.program.getSourceFile(fileName);
|
||||||
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
|
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
|
||||||
// Is this file going to be emitted separately
|
// Is this file going to be emitted separately
|
||||||
let sourceFileName: string;
|
let sourceFileName: string;
|
||||||
let outFile = options.outFile || options.out;
|
const outFile = options.outFile || options.out;
|
||||||
if (ts.isExternalModule(sourceFile) || !outFile) {
|
if (ts.isExternalModule(sourceFile) || !outFile) {
|
||||||
if (options.outDir) {
|
if (options.outDir) {
|
||||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
|
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
|
||||||
|
@ -1195,7 +1195,7 @@ namespace Harness {
|
||||||
sourceFileName = outFile;
|
sourceFileName = outFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
let dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
|
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
|
||||||
|
|
||||||
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
|
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
|
||||||
}
|
}
|
||||||
|
@ -1220,7 +1220,7 @@ namespace Harness {
|
||||||
let errorOutput = "";
|
let errorOutput = "";
|
||||||
ts.forEach(diagnostics, diagnostic => {
|
ts.forEach(diagnostics, diagnostic => {
|
||||||
if (diagnostic.file) {
|
if (diagnostic.file) {
|
||||||
let lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
const lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||||
errorOutput += diagnostic.file.fileName + "(" + (lineAndCharacter.line + 1) + "," + (lineAndCharacter.character + 1) + "): ";
|
errorOutput += diagnostic.file.fileName + "(" + (lineAndCharacter.line + 1) + "," + (lineAndCharacter.character + 1) + "): ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,14 +1232,14 @@ namespace Harness {
|
||||||
|
|
||||||
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) {
|
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) {
|
||||||
diagnostics.sort(ts.compareDiagnostics);
|
diagnostics.sort(ts.compareDiagnostics);
|
||||||
let outputLines: string[] = [];
|
const outputLines: string[] = [];
|
||||||
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
|
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
|
||||||
let totalErrorsReportedInNonLibraryFiles = 0;
|
let totalErrorsReportedInNonLibraryFiles = 0;
|
||||||
|
|
||||||
function outputErrorText(error: ts.Diagnostic) {
|
function outputErrorText(error: ts.Diagnostic) {
|
||||||
let message = ts.flattenDiagnosticMessageText(error.messageText, Harness.IO.newLine());
|
const message = ts.flattenDiagnosticMessageText(error.messageText, Harness.IO.newLine());
|
||||||
|
|
||||||
let errLines = RunnerBase.removeFullPaths(message)
|
const errLines = RunnerBase.removeFullPaths(message)
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map(s => s.length > 0 && s.charAt(s.length - 1) === "\r" ? s.substr(0, s.length - 1) : s)
|
.map(s => s.length > 0 && s.charAt(s.length - 1) === "\r" ? s.substr(0, s.length - 1) : s)
|
||||||
.filter(s => s.length > 0)
|
.filter(s => s.length > 0)
|
||||||
|
@ -1257,14 +1257,14 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report global errors
|
// Report global errors
|
||||||
let globalErrors = diagnostics.filter(err => !err.file);
|
const globalErrors = diagnostics.filter(err => !err.file);
|
||||||
globalErrors.forEach(outputErrorText);
|
globalErrors.forEach(outputErrorText);
|
||||||
|
|
||||||
// 'merge' the lines of each input file with any errors associated with it
|
// 'merge' the lines of each input file with any errors associated with it
|
||||||
inputFiles.filter(f => f.content !== undefined).forEach(inputFile => {
|
inputFiles.filter(f => f.content !== undefined).forEach(inputFile => {
|
||||||
// Filter down to the errors in the file
|
// Filter down to the errors in the file
|
||||||
let fileErrors = diagnostics.filter(e => {
|
const fileErrors = diagnostics.filter(e => {
|
||||||
let errFn = e.file;
|
const errFn = e.file;
|
||||||
return errFn && errFn.fileName === inputFile.unitName;
|
return errFn && errFn.fileName === inputFile.unitName;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1278,7 +1278,7 @@ namespace Harness {
|
||||||
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
|
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
|
||||||
// we have to string-based splitting instead and try to figure out the delimiting chars
|
// we have to string-based splitting instead and try to figure out the delimiting chars
|
||||||
|
|
||||||
let lineStarts = ts.computeLineStarts(inputFile.content);
|
const lineStarts = ts.computeLineStarts(inputFile.content);
|
||||||
let lines = inputFile.content.split("\n");
|
let lines = inputFile.content.split("\n");
|
||||||
if (lines.length === 1) {
|
if (lines.length === 1) {
|
||||||
lines = lines[0].split("\r");
|
lines = lines[0].split("\r");
|
||||||
|
@ -1289,7 +1289,7 @@ namespace Harness {
|
||||||
line = line.substr(0, line.length - 1);
|
line = line.substr(0, line.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let thisLineStart = lineStarts[lineIndex];
|
const thisLineStart = lineStarts[lineIndex];
|
||||||
let nextLineStart: number;
|
let nextLineStart: number;
|
||||||
// On the last line of the file, fake the next line start number so that we handle errors on the last character of the file correctly
|
// On the last line of the file, fake the next line start number so that we handle errors on the last character of the file correctly
|
||||||
if (lineIndex === lines.length - 1) {
|
if (lineIndex === lines.length - 1) {
|
||||||
|
@ -1302,14 +1302,14 @@ namespace Harness {
|
||||||
outputLines.push(" " + line);
|
outputLines.push(" " + line);
|
||||||
fileErrors.forEach(err => {
|
fileErrors.forEach(err => {
|
||||||
// Does any error start or continue on to this line? Emit squiggles
|
// Does any error start or continue on to this line? Emit squiggles
|
||||||
let end = ts.textSpanEnd(err);
|
const end = ts.textSpanEnd(err);
|
||||||
if ((end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) {
|
if ((end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) {
|
||||||
// How many characters from the start of this line the error starts at (could be positive or negative)
|
// How many characters from the start of this line the error starts at (could be positive or negative)
|
||||||
let relativeOffset = err.start - thisLineStart;
|
const relativeOffset = err.start - thisLineStart;
|
||||||
// How many characters of the error are on this line (might be longer than this line in reality)
|
// How many characters of the error are on this line (might be longer than this line in reality)
|
||||||
let length = (end - err.start) - Math.max(0, thisLineStart - err.start);
|
const length = (end - err.start) - Math.max(0, thisLineStart - err.start);
|
||||||
// Calculate the start of the squiggle
|
// Calculate the start of the squiggle
|
||||||
let squiggleStart = Math.max(0, relativeOffset);
|
const squiggleStart = Math.max(0, relativeOffset);
|
||||||
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
|
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
|
||||||
outputLines.push(" " + line.substr(0, squiggleStart).replace(/[^\s]/g, " ") + new Array(Math.min(length, line.length - squiggleStart) + 1).join("~"));
|
outputLines.push(" " + line.substr(0, squiggleStart).replace(/[^\s]/g, " ") + new Array(Math.min(length, line.length - squiggleStart) + 1).join("~"));
|
||||||
|
|
||||||
|
@ -1329,11 +1329,11 @@ namespace Harness {
|
||||||
assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName);
|
assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName);
|
||||||
});
|
});
|
||||||
|
|
||||||
let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
const numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||||
return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName));
|
return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName));
|
||||||
});
|
});
|
||||||
|
|
||||||
let numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
const numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||||
// Count an error generated from tests262-harness folder.This should only apply for test262
|
// Count an error generated from tests262-harness folder.This should only apply for test262
|
||||||
return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
|
return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
|
||||||
});
|
});
|
||||||
|
@ -1351,7 +1351,7 @@ namespace Harness {
|
||||||
|
|
||||||
// Emit them
|
// Emit them
|
||||||
let result = "";
|
let result = "";
|
||||||
for (let outputFile of outputFiles) {
|
for (const outputFile of outputFiles) {
|
||||||
// Some extra spacing if this isn't the first file
|
// Some extra spacing if this isn't the first file
|
||||||
if (result.length) {
|
if (result.length) {
|
||||||
result += "\r\n\r\n";
|
result += "\r\n\r\n";
|
||||||
|
@ -1366,7 +1366,7 @@ namespace Harness {
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
function cleanName(fn: string) {
|
function cleanName(fn: string) {
|
||||||
let lastSlash = ts.normalizeSlashes(fn).lastIndexOf("/");
|
const lastSlash = ts.normalizeSlashes(fn).lastIndexOf("/");
|
||||||
return fn.substr(lastSlash + 1).toLowerCase();
|
return fn.substr(lastSlash + 1).toLowerCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1475,10 +1475,10 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regex for parsing options in the format "@Alpha: Value of any sort"
|
// Regex for parsing options in the format "@Alpha: Value of any sort"
|
||||||
let optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
|
const optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
|
||||||
|
|
||||||
function extractCompilerSettings(content: string): CompilerSettings {
|
function extractCompilerSettings(content: string): CompilerSettings {
|
||||||
let opts: CompilerSettings = {};
|
const opts: CompilerSettings = {};
|
||||||
|
|
||||||
let match: RegExpExecArray;
|
let match: RegExpExecArray;
|
||||||
while ((match = optionRegex.exec(content)) != null) {
|
while ((match = optionRegex.exec(content)) != null) {
|
||||||
|
@ -1490,12 +1490,12 @@ namespace Harness {
|
||||||
|
|
||||||
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
|
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
|
||||||
export function makeUnitsFromTest(code: string, fileName: string): { settings: CompilerSettings; testUnitData: TestUnitData[]; } {
|
export function makeUnitsFromTest(code: string, fileName: string): { settings: CompilerSettings; testUnitData: TestUnitData[]; } {
|
||||||
let settings = extractCompilerSettings(code);
|
const settings = extractCompilerSettings(code);
|
||||||
|
|
||||||
// List of all the subfiles we've parsed out
|
// List of all the subfiles we've parsed out
|
||||||
let testUnitData: TestUnitData[] = [];
|
const testUnitData: TestUnitData[] = [];
|
||||||
|
|
||||||
let lines = Utils.splitContentByNewlines(code);
|
const lines = Utils.splitContentByNewlines(code);
|
||||||
|
|
||||||
// Stuff related to the subfile we're parsing
|
// Stuff related to the subfile we're parsing
|
||||||
let currentFileContent: string = null;
|
let currentFileContent: string = null;
|
||||||
|
@ -1504,12 +1504,12 @@ namespace Harness {
|
||||||
let refs: string[] = [];
|
let refs: string[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
let line = lines[i];
|
const line = lines[i];
|
||||||
let testMetaData = optionRegex.exec(line);
|
const testMetaData = optionRegex.exec(line);
|
||||||
if (testMetaData) {
|
if (testMetaData) {
|
||||||
// Comment line, check for global/file @options and record them
|
// Comment line, check for global/file @options and record them
|
||||||
optionRegex.lastIndex = 0;
|
optionRegex.lastIndex = 0;
|
||||||
let metaDataName = testMetaData[1].toLowerCase();
|
const metaDataName = testMetaData[1].toLowerCase();
|
||||||
if (metaDataName === "filename") {
|
if (metaDataName === "filename") {
|
||||||
currentFileOptions[testMetaData[1]] = testMetaData[2];
|
currentFileOptions[testMetaData[1]] = testMetaData[2];
|
||||||
}
|
}
|
||||||
|
@ -1520,7 +1520,7 @@ namespace Harness {
|
||||||
// New metadata statement after having collected some code to go with the previous metadata
|
// New metadata statement after having collected some code to go with the previous metadata
|
||||||
if (currentFileName) {
|
if (currentFileName) {
|
||||||
// Store result file
|
// Store result file
|
||||||
let newTestFile = {
|
const newTestFile = {
|
||||||
content: currentFileContent,
|
content: currentFileContent,
|
||||||
name: currentFileName,
|
name: currentFileName,
|
||||||
fileOptions: currentFileOptions,
|
fileOptions: currentFileOptions,
|
||||||
|
@ -1558,7 +1558,7 @@ namespace Harness {
|
||||||
currentFileName = testUnitData.length > 0 ? currentFileName : Path.getFileName(fileName);
|
currentFileName = testUnitData.length > 0 ? currentFileName : Path.getFileName(fileName);
|
||||||
|
|
||||||
// EOF, push whatever remains
|
// EOF, push whatever remains
|
||||||
let newTestFile2 = {
|
const newTestFile2 = {
|
||||||
content: currentFileContent || "",
|
content: currentFileContent || "",
|
||||||
name: currentFileName,
|
name: currentFileName,
|
||||||
fileOptions: currentFileOptions,
|
fileOptions: currentFileOptions,
|
||||||
|
@ -1606,7 +1606,7 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fileCache: { [idx: string]: boolean } = {};
|
const fileCache: { [idx: string]: boolean } = {};
|
||||||
function generateActual(actualFileName: string, generateContent: () => string): string {
|
function generateActual(actualFileName: string, generateContent: () => string): string {
|
||||||
// For now this is written using TypeScript, because sys is not available when running old test cases.
|
// For now this is written using TypeScript, because sys is not available when running old test cases.
|
||||||
// But we need to move to sys once we have
|
// But we need to move to sys once we have
|
||||||
|
@ -1617,7 +1617,7 @@ namespace Harness {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let parentDirectory = IO.directoryName(dirName);
|
const parentDirectory = IO.directoryName(dirName);
|
||||||
if (parentDirectory != "") {
|
if (parentDirectory != "") {
|
||||||
createDirectoryStructure(parentDirectory);
|
createDirectoryStructure(parentDirectory);
|
||||||
}
|
}
|
||||||
|
@ -1633,7 +1633,7 @@ namespace Harness {
|
||||||
IO.deleteFile(actualFileName);
|
IO.deleteFile(actualFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
let actual = generateContent();
|
const actual = generateContent();
|
||||||
|
|
||||||
if (actual === undefined) {
|
if (actual === undefined) {
|
||||||
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
||||||
|
@ -1656,7 +1656,7 @@ namespace Harness {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
const refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||||
|
|
||||||
if (actual === null) {
|
if (actual === null) {
|
||||||
actual = "<no content>";
|
actual = "<no content>";
|
||||||
|
@ -1671,10 +1671,10 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) {
|
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) {
|
||||||
let encoded_actual = Utils.encodeString(actual);
|
const encoded_actual = Utils.encodeString(actual);
|
||||||
if (expected != encoded_actual) {
|
if (expected != encoded_actual) {
|
||||||
// Overwrite & issue error
|
// Overwrite & issue error
|
||||||
let errMsg = "The baseline file " + relativeFileName + " has changed";
|
const errMsg = "The baseline file " + relativeFileName + " has changed";
|
||||||
throw new Error(errMsg);
|
throw new Error(errMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1687,17 +1687,17 @@ namespace Harness {
|
||||||
opts?: BaselineOptions): void {
|
opts?: BaselineOptions): void {
|
||||||
|
|
||||||
let actual = <string>undefined;
|
let actual = <string>undefined;
|
||||||
let actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||||
|
|
||||||
if (runImmediately) {
|
if (runImmediately) {
|
||||||
actual = generateActual(actualFileName, generateContent);
|
actual = generateActual(actualFileName, generateContent);
|
||||||
let comparison = compareToBaseline(actual, relativeFileName, opts);
|
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
actual = generateActual(actualFileName, generateContent);
|
actual = generateActual(actualFileName, generateContent);
|
||||||
|
|
||||||
let comparison = compareToBaseline(actual, relativeFileName, opts);
|
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1712,7 +1712,7 @@ namespace Harness {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDefaultLibraryFile(io: Harness.IO): { unitName: string, content: string } {
|
export function getDefaultLibraryFile(io: Harness.IO): { unitName: string, content: string } {
|
||||||
let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts";
|
const libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts";
|
||||||
return {
|
return {
|
||||||
unitName: libFile,
|
unitName: libFile,
|
||||||
content: io.readFile(libFile)
|
content: io.readFile(libFile)
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace Harness.LanguageService {
|
||||||
|
|
||||||
public editContent(start: number, end: number, newText: string): void {
|
public editContent(start: number, end: number, newText: string): void {
|
||||||
// Apply edits
|
// Apply edits
|
||||||
let prefix = this.content.substring(0, start);
|
const prefix = this.content.substring(0, start);
|
||||||
let middle = newText;
|
const middle = newText;
|
||||||
let suffix = this.content.substring(end);
|
const suffix = this.content.substring(end);
|
||||||
this.setContent(prefix + middle + suffix);
|
this.setContent(prefix + middle + suffix);
|
||||||
|
|
||||||
// Store edit range + new length of script
|
// Store edit range + new length of script
|
||||||
|
@ -48,10 +48,10 @@ namespace Harness.LanguageService {
|
||||||
return ts.unchangedTextChangeRange;
|
return ts.unchangedTextChangeRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
let initialEditRangeIndex = this.editRanges.length - (this.version - startVersion);
|
const initialEditRangeIndex = this.editRanges.length - (this.version - startVersion);
|
||||||
let lastEditRangeIndex = this.editRanges.length - (this.version - endVersion);
|
const lastEditRangeIndex = this.editRanges.length - (this.version - endVersion);
|
||||||
|
|
||||||
let entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex);
|
const entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex);
|
||||||
return ts.collapseTextChangeRangesAcrossMultipleVersions(entries.map(e => e.textChangeRange));
|
return ts.collapseTextChangeRangesAcrossMultipleVersions(entries.map(e => e.textChangeRange));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ namespace Harness.LanguageService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChangeRange(oldScript: ts.IScriptSnapshot): ts.TextChangeRange {
|
public getChangeRange(oldScript: ts.IScriptSnapshot): ts.TextChangeRange {
|
||||||
let oldShim = <ScriptSnapshot>oldScript;
|
const oldShim = <ScriptSnapshot>oldScript;
|
||||||
return this.scriptInfo.getTextChangeRangeBetweenVersions(oldShim.version, this.version);
|
return this.scriptInfo.getTextChangeRangeBetweenVersions(oldShim.version, this.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,9 +92,9 @@ namespace Harness.LanguageService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChangeRange(oldScript: ts.ScriptSnapshotShim): string {
|
public getChangeRange(oldScript: ts.ScriptSnapshotShim): string {
|
||||||
let oldShim = <ScriptSnapshotProxy>oldScript;
|
const oldShim = <ScriptSnapshotProxy>oldScript;
|
||||||
|
|
||||||
let range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot);
|
const range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot);
|
||||||
if (range === undefined) {
|
if (range === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ namespace Harness.LanguageService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getFilenames(): string[] {
|
public getFilenames(): string[] {
|
||||||
let fileNames: string[] = [];
|
const fileNames: string[] = [];
|
||||||
ts.forEachKey(this.fileNameToScript, (fileName) => { fileNames.push(fileName); });
|
ts.forEachKey(this.fileNameToScript, (fileName) => { fileNames.push(fileName); });
|
||||||
return fileNames;
|
return fileNames;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ namespace Harness.LanguageService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public editScript(fileName: string, start: number, end: number, newText: string) {
|
public editScript(fileName: string, start: number, end: number, newText: string) {
|
||||||
let script = this.getScriptInfo(fileName);
|
const script = this.getScriptInfo(fileName);
|
||||||
if (script !== undefined) {
|
if (script !== undefined) {
|
||||||
script.editContent(start, end, newText);
|
script.editContent(start, end, newText);
|
||||||
return;
|
return;
|
||||||
|
@ -161,7 +161,7 @@ namespace Harness.LanguageService {
|
||||||
* @param col 0 based index
|
* @param col 0 based index
|
||||||
*/
|
*/
|
||||||
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
|
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
|
||||||
let script: ScriptInfo = this.fileNameToScript[fileName];
|
const script: ScriptInfo = this.fileNameToScript[fileName];
|
||||||
assert.isNotNull(script);
|
assert.isNotNull(script);
|
||||||
|
|
||||||
return ts.computeLineAndCharacterOfPosition(script.lineMap, position);
|
return ts.computeLineAndCharacterOfPosition(script.lineMap, position);
|
||||||
|
@ -176,11 +176,11 @@ namespace Harness.LanguageService {
|
||||||
getDefaultLibFileName(): string { return ""; }
|
getDefaultLibFileName(): string { return ""; }
|
||||||
getScriptFileNames(): string[] { return this.getFilenames(); }
|
getScriptFileNames(): string[] { return this.getFilenames(); }
|
||||||
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
|
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
|
||||||
let script = this.getScriptInfo(fileName);
|
const script = this.getScriptInfo(fileName);
|
||||||
return script ? new ScriptSnapshot(script) : undefined;
|
return script ? new ScriptSnapshot(script) : undefined;
|
||||||
}
|
}
|
||||||
getScriptVersion(fileName: string): string {
|
getScriptVersion(fileName: string): string {
|
||||||
let script = this.getScriptInfo(fileName);
|
const script = this.getScriptInfo(fileName);
|
||||||
return script ? script.version.toString() : undefined;
|
return script ? script.version.toString() : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,20 +211,20 @@ namespace Harness.LanguageService {
|
||||||
this.nativeHost = new NativeLanguageServiceHost(cancellationToken, options);
|
this.nativeHost = new NativeLanguageServiceHost(cancellationToken, options);
|
||||||
|
|
||||||
if (preprocessToResolve) {
|
if (preprocessToResolve) {
|
||||||
let compilerOptions = this.nativeHost.getCompilationSettings();
|
const compilerOptions = this.nativeHost.getCompilationSettings();
|
||||||
let moduleResolutionHost: ts.ModuleResolutionHost = {
|
const moduleResolutionHost: ts.ModuleResolutionHost = {
|
||||||
fileExists: fileName => this.getScriptInfo(fileName) !== undefined,
|
fileExists: fileName => this.getScriptInfo(fileName) !== undefined,
|
||||||
readFile: fileName => {
|
readFile: fileName => {
|
||||||
let scriptInfo = this.getScriptInfo(fileName);
|
const scriptInfo = this.getScriptInfo(fileName);
|
||||||
return scriptInfo && scriptInfo.content;
|
return scriptInfo && scriptInfo.content;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.getModuleResolutionsForFile = (fileName) => {
|
this.getModuleResolutionsForFile = (fileName) => {
|
||||||
let scriptInfo = this.getScriptInfo(fileName);
|
const scriptInfo = this.getScriptInfo(fileName);
|
||||||
let preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true);
|
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true);
|
||||||
let imports: ts.Map<string> = {};
|
const imports: ts.Map<string> = {};
|
||||||
for (let module of preprocessInfo.importedFiles) {
|
for (const module of preprocessInfo.importedFiles) {
|
||||||
let resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost);
|
const resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost);
|
||||||
if (resolutionInfo.resolvedModule) {
|
if (resolutionInfo.resolvedModule) {
|
||||||
imports[module.fileName] = resolutionInfo.resolvedModule.resolvedFileName;
|
imports[module.fileName] = resolutionInfo.resolvedModule.resolvedFileName;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ namespace Harness.LanguageService {
|
||||||
getDefaultLibFileName(): string { return this.nativeHost.getDefaultLibFileName(); }
|
getDefaultLibFileName(): string { return this.nativeHost.getDefaultLibFileName(); }
|
||||||
getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); }
|
getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); }
|
||||||
getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim {
|
getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim {
|
||||||
let nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
|
const nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
|
||||||
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
|
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
|
||||||
}
|
}
|
||||||
getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); }
|
getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); }
|
||||||
|
@ -257,7 +257,7 @@ namespace Harness.LanguageService {
|
||||||
}
|
}
|
||||||
fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; }
|
fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; }
|
||||||
readFile(fileName: string) {
|
readFile(fileName: string) {
|
||||||
let snapshot = this.nativeHost.getScriptSnapshot(fileName);
|
const snapshot = this.nativeHost.getScriptSnapshot(fileName);
|
||||||
return snapshot && snapshot.getText(0, snapshot.getLength());
|
return snapshot && snapshot.getText(0, snapshot.getLength());
|
||||||
}
|
}
|
||||||
log(s: string): void { this.nativeHost.log(s); }
|
log(s: string): void { this.nativeHost.log(s); }
|
||||||
|
@ -272,13 +272,13 @@ namespace Harness.LanguageService {
|
||||||
throw new Error("NYI");
|
throw new Error("NYI");
|
||||||
}
|
}
|
||||||
getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult {
|
getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult {
|
||||||
let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split("\n");
|
const result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split("\n");
|
||||||
let entries: ts.ClassificationInfo[] = [];
|
const entries: ts.ClassificationInfo[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let position = 0;
|
let position = 0;
|
||||||
|
|
||||||
for (; i < result.length - 1; i += 2) {
|
for (; i < result.length - 1; i += 2) {
|
||||||
let t = entries[i / 2] = {
|
const t = entries[i / 2] = {
|
||||||
length: parseInt(result[i]),
|
length: parseInt(result[i]),
|
||||||
classification: parseInt(result[i + 1])
|
classification: parseInt(result[i + 1])
|
||||||
};
|
};
|
||||||
|
@ -286,7 +286,7 @@ namespace Harness.LanguageService {
|
||||||
assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length);
|
assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length);
|
||||||
position += t.length;
|
position += t.length;
|
||||||
}
|
}
|
||||||
let finalLexState = parseInt(result[result.length - 1]);
|
const finalLexState = parseInt(result[result.length - 1]);
|
||||||
|
|
||||||
assert.equal(position, text.length, "Expected cumulative length of all entries to match the length of the source. expected: " + text.length + ", but got: " + position);
|
assert.equal(position, text.length, "Expected cumulative length of all entries to match the length of the source. expected: " + text.length + ", but got: " + position);
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ namespace Harness.LanguageService {
|
||||||
}
|
}
|
||||||
|
|
||||||
function unwrapJSONCallResult(result: string): any {
|
function unwrapJSONCallResult(result: string): any {
|
||||||
let parsedResult = JSON.parse(result);
|
const parsedResult = JSON.parse(result);
|
||||||
if (parsedResult.error) {
|
if (parsedResult.error) {
|
||||||
throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error));
|
throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error));
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ namespace Harness.LanguageService {
|
||||||
constructor(private shim: ts.LanguageServiceShim) {
|
constructor(private shim: ts.LanguageServiceShim) {
|
||||||
}
|
}
|
||||||
private unwrappJSONCallResult(result: string): any {
|
private unwrappJSONCallResult(result: string): any {
|
||||||
let parsedResult = JSON.parse(result);
|
const parsedResult = JSON.parse(result);
|
||||||
if (parsedResult.error) {
|
if (parsedResult.error) {
|
||||||
throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error));
|
throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error));
|
||||||
}
|
}
|
||||||
|
@ -443,10 +443,10 @@ namespace Harness.LanguageService {
|
||||||
isLibFile: boolean;
|
isLibFile: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
let coreServicesShim = this.factory.createCoreServicesShim(this.host);
|
const coreServicesShim = this.factory.createCoreServicesShim(this.host);
|
||||||
shimResult = unwrapJSONCallResult(coreServicesShim.getPreProcessedFileInfo(fileName, ts.ScriptSnapshot.fromString(fileContents)));
|
shimResult = unwrapJSONCallResult(coreServicesShim.getPreProcessedFileInfo(fileName, ts.ScriptSnapshot.fromString(fileContents)));
|
||||||
|
|
||||||
let convertResult: ts.PreProcessedFileInfo = {
|
const convertResult: ts.PreProcessedFileInfo = {
|
||||||
referencedFiles: [],
|
referencedFiles: [],
|
||||||
importedFiles: [],
|
importedFiles: [],
|
||||||
ambientExternalModules: [],
|
ambientExternalModules: [],
|
||||||
|
@ -530,7 +530,7 @@ namespace Harness.LanguageService {
|
||||||
fileName = Harness.Compiler.defaultLibFileName;
|
fileName = Harness.Compiler.defaultLibFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
let snapshot = this.host.getScriptSnapshot(fileName);
|
const snapshot = this.host.getScriptSnapshot(fileName);
|
||||||
return snapshot && snapshot.getText(0, snapshot.getLength());
|
return snapshot && snapshot.getText(0, snapshot.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,13 +612,13 @@ namespace Harness.LanguageService {
|
||||||
private client: ts.server.SessionClient;
|
private client: ts.server.SessionClient;
|
||||||
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
|
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
|
||||||
// This is the main host that tests use to direct tests
|
// This is the main host that tests use to direct tests
|
||||||
let clientHost = new SessionClientHost(cancellationToken, options);
|
const clientHost = new SessionClientHost(cancellationToken, options);
|
||||||
let client = new ts.server.SessionClient(clientHost);
|
const client = new ts.server.SessionClient(clientHost);
|
||||||
|
|
||||||
// This host is just a proxy for the clientHost, it uses the client
|
// This host is just a proxy for the clientHost, it uses the client
|
||||||
// host to answer server queries about files on disk
|
// host to answer server queries about files on disk
|
||||||
let serverHost = new SessionServerHost(clientHost);
|
const serverHost = new SessionServerHost(clientHost);
|
||||||
let server = new ts.server.Session(serverHost,
|
const server = new ts.server.Session(serverHost,
|
||||||
Buffer ? Buffer.byteLength : (string: string, encoding?: string) => string.length,
|
Buffer ? Buffer.byteLength : (string: string, encoding?: string) => string.length,
|
||||||
process.hrtime, serverHost);
|
process.hrtime, serverHost);
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace Playback {
|
||||||
|
|
||||||
function memoize<T>(func: (s: string) => T): Memoized<T> {
|
function memoize<T>(func: (s: string) => T): Memoized<T> {
|
||||||
let lookup: { [s: string]: T } = {};
|
let lookup: { [s: string]: T } = {};
|
||||||
let run: Memoized<T> = <Memoized<T>>((s: string) => {
|
const run: Memoized<T> = <Memoized<T>>((s: string) => {
|
||||||
if (lookup.hasOwnProperty(s)) return lookup[s];
|
if (lookup.hasOwnProperty(s)) return lookup[s];
|
||||||
return lookup[s] = func(s);
|
return lookup[s] = func(s);
|
||||||
});
|
});
|
||||||
|
@ -159,7 +159,7 @@ namespace Playback {
|
||||||
wrapper.endRecord = () => {
|
wrapper.endRecord = () => {
|
||||||
if (recordLog !== undefined) {
|
if (recordLog !== undefined) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let fn = () => recordLogFileNameBase + i + ".json";
|
const fn = () => recordLogFileNameBase + i + ".json";
|
||||||
while (underlying.fileExists(fn())) i++;
|
while (underlying.fileExists(fn())) i++;
|
||||||
underlying.writeFile(fn(), JSON.stringify(recordLog));
|
underlying.writeFile(fn(), JSON.stringify(recordLog));
|
||||||
recordLog = undefined;
|
recordLog = undefined;
|
||||||
|
@ -209,8 +209,8 @@ namespace Playback {
|
||||||
|
|
||||||
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
|
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
|
||||||
path => {
|
path => {
|
||||||
let result = underlying.readFile(path);
|
const result = underlying.readFile(path);
|
||||||
let logEntry = { path, codepage: 0, result: { contents: result, codepage: 0 } };
|
const logEntry = { path, codepage: 0, result: { contents: result, codepage: 0 } };
|
||||||
recordLog.filesRead.push(logEntry);
|
recordLog.filesRead.push(logEntry);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
@ -218,8 +218,8 @@ namespace Playback {
|
||||||
|
|
||||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||||
(path, extension, exclude) => {
|
(path, extension, exclude) => {
|
||||||
let result = (<ts.System>underlying).readDirectory(path, extension, exclude);
|
const result = (<ts.System>underlying).readDirectory(path, extension, exclude);
|
||||||
let logEntry = { path, extension, exclude, result };
|
const logEntry = { path, extension, exclude, result };
|
||||||
recordLog.directoriesRead.push(logEntry);
|
recordLog.directoriesRead.push(logEntry);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
@ -263,10 +263,10 @@ namespace Playback {
|
||||||
}
|
}
|
||||||
|
|
||||||
function findResultByFields<T>(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T {
|
function findResultByFields<T>(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T {
|
||||||
let predicate = (entry: { result?: T }) => {
|
const predicate = (entry: { result?: T }) => {
|
||||||
return Object.getOwnPropertyNames(expectedFields).every((name) => (<any>entry)[name] === (<any>expectedFields)[name]);
|
return Object.getOwnPropertyNames(expectedFields).every((name) => (<any>entry)[name] === (<any>expectedFields)[name]);
|
||||||
};
|
};
|
||||||
let results = logArray.filter(entry => predicate(entry));
|
const results = logArray.filter(entry => predicate(entry));
|
||||||
if (results.length === 0) {
|
if (results.length === 0) {
|
||||||
if (defaultValue !== undefined) {
|
if (defaultValue !== undefined) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
@ -279,7 +279,7 @@ namespace Playback {
|
||||||
}
|
}
|
||||||
|
|
||||||
function findResultByPath<T>(wrapper: { resolvePath(s: string): string }, logArray: { path: string; result?: T }[], expectedPath: string, defaultValue?: T): T {
|
function findResultByPath<T>(wrapper: { resolvePath(s: string): string }, logArray: { path: string; result?: T }[], expectedPath: string, defaultValue?: T): T {
|
||||||
let normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
||||||
// Try to find the result through normal fileName
|
// Try to find the result through normal fileName
|
||||||
for (let i = 0; i < logArray.length; i++) {
|
for (let i = 0; i < logArray.length; i++) {
|
||||||
if (ts.normalizeSlashes(logArray[i].path).toLowerCase() === normalizedName) {
|
if (ts.normalizeSlashes(logArray[i].path).toLowerCase() === normalizedName) {
|
||||||
|
@ -288,7 +288,7 @@ namespace Playback {
|
||||||
}
|
}
|
||||||
// Fallback, try to resolve the target paths as well
|
// Fallback, try to resolve the target paths as well
|
||||||
if (replayLog.pathsResolved.length > 0) {
|
if (replayLog.pathsResolved.length > 0) {
|
||||||
let normalizedResolvedName = wrapper.resolvePath(expectedPath).toLowerCase();
|
const normalizedResolvedName = wrapper.resolvePath(expectedPath).toLowerCase();
|
||||||
for (let i = 0; i < logArray.length; i++) {
|
for (let i = 0; i < logArray.length; i++) {
|
||||||
if (wrapper.resolvePath(logArray[i].path).toLowerCase() === normalizedResolvedName) {
|
if (wrapper.resolvePath(logArray[i].path).toLowerCase() === normalizedResolvedName) {
|
||||||
return logArray[i].result;
|
return logArray[i].result;
|
||||||
|
@ -305,9 +305,9 @@ namespace Playback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let pathEquivCache: any = {};
|
const pathEquivCache: any = {};
|
||||||
function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) {
|
function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) {
|
||||||
let key = left + "-~~-" + right;
|
const key = left + "-~~-" + right;
|
||||||
function areSame(a: string, b: string) {
|
function areSame(a: string, b: string) {
|
||||||
return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase();
|
return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase();
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ namespace Playback {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapIO(underlying: Harness.IO): PlaybackIO {
|
export function wrapIO(underlying: Harness.IO): PlaybackIO {
|
||||||
let wrapper: PlaybackIO = <any>{};
|
const wrapper: PlaybackIO = <any>{};
|
||||||
initWrapper(wrapper, underlying);
|
initWrapper(wrapper, underlying);
|
||||||
|
|
||||||
wrapper.directoryName = (path): string => { throw new Error("NotSupported"); };
|
wrapper.directoryName = (path): string => { throw new Error("NotSupported"); };
|
||||||
|
@ -342,7 +342,7 @@ namespace Playback {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapSystem(underlying: ts.System): PlaybackSystem {
|
export function wrapSystem(underlying: ts.System): PlaybackSystem {
|
||||||
let wrapper: PlaybackSystem = <any>{};
|
const wrapper: PlaybackSystem = <any>{};
|
||||||
initWrapper(wrapper, underlying);
|
initWrapper(wrapper, underlying);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
|
||||||
class ProjectRunner extends RunnerBase {
|
class ProjectRunner extends RunnerBase {
|
||||||
public initializeTests() {
|
public initializeTests() {
|
||||||
if (this.tests.length === 0) {
|
if (this.tests.length === 0) {
|
||||||
let testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true });
|
const testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true });
|
||||||
testFiles.forEach(fn => {
|
testFiles.forEach(fn => {
|
||||||
fn = fn.replace(/\\/g, "/");
|
fn = fn.replace(/\\/g, "/");
|
||||||
this.runProjectTestCase(fn);
|
this.runProjectTestCase(fn);
|
||||||
|
@ -101,7 +101,7 @@ class ProjectRunner extends RunnerBase {
|
||||||
function cleanProjectUrl(url: string) {
|
function cleanProjectUrl(url: string) {
|
||||||
let diskProjectPath = ts.normalizeSlashes(Harness.IO.resolvePath(testCase.projectRoot));
|
let diskProjectPath = ts.normalizeSlashes(Harness.IO.resolvePath(testCase.projectRoot));
|
||||||
let projectRootUrl = "file:///" + diskProjectPath;
|
let projectRootUrl = "file:///" + diskProjectPath;
|
||||||
let normalizedProjectRoot = ts.normalizeSlashes(testCase.projectRoot);
|
const normalizedProjectRoot = ts.normalizeSlashes(testCase.projectRoot);
|
||||||
diskProjectPath = diskProjectPath.substr(0, diskProjectPath.lastIndexOf(normalizedProjectRoot));
|
diskProjectPath = diskProjectPath.substr(0, diskProjectPath.lastIndexOf(normalizedProjectRoot));
|
||||||
projectRootUrl = projectRootUrl.substr(0, projectRootUrl.lastIndexOf(normalizedProjectRoot));
|
projectRootUrl = projectRootUrl.substr(0, projectRootUrl.lastIndexOf(normalizedProjectRoot));
|
||||||
if (url && url.length) {
|
if (url && url.length) {
|
||||||
|
@ -130,12 +130,12 @@ class ProjectRunner extends RunnerBase {
|
||||||
getSourceFileTextImpl: (fileName: string) => string,
|
getSourceFileTextImpl: (fileName: string) => string,
|
||||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult {
|
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult {
|
||||||
|
|
||||||
let program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
|
const program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
|
||||||
let errors = ts.getPreEmitDiagnostics(program);
|
let errors = ts.getPreEmitDiagnostics(program);
|
||||||
|
|
||||||
let emitResult = program.emit();
|
const emitResult = program.emit();
|
||||||
errors = ts.concatenate(errors, emitResult.diagnostics);
|
errors = ts.concatenate(errors, emitResult.diagnostics);
|
||||||
let sourceMapData = emitResult.sourceMaps;
|
const sourceMapData = emitResult.sourceMaps;
|
||||||
|
|
||||||
// Clean up source map data that will be used in baselining
|
// Clean up source map data that will be used in baselining
|
||||||
if (sourceMapData) {
|
if (sourceMapData) {
|
||||||
|
@ -181,7 +181,7 @@ class ProjectRunner extends RunnerBase {
|
||||||
sourceFile = languageVersion === ts.ScriptTarget.ES6 ? Harness.Compiler.defaultES6LibSourceFile : Harness.Compiler.defaultLibSourceFile;
|
sourceFile = languageVersion === ts.ScriptTarget.ES6 ? Harness.Compiler.defaultES6LibSourceFile : Harness.Compiler.defaultLibSourceFile;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let text = getSourceFileText(fileName);
|
const text = getSourceFileText(fileName);
|
||||||
if (text !== undefined) {
|
if (text !== undefined) {
|
||||||
sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion);
|
sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion);
|
||||||
}
|
}
|
||||||
|
@ -208,9 +208,9 @@ class ProjectRunner extends RunnerBase {
|
||||||
function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult {
|
function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult {
|
||||||
let nonSubfolderDiskFiles = 0;
|
let nonSubfolderDiskFiles = 0;
|
||||||
|
|
||||||
let outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
const outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
||||||
|
|
||||||
let projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
|
const projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
|
||||||
return {
|
return {
|
||||||
moduleKind,
|
moduleKind,
|
||||||
program: projectCompilerResult.program,
|
program: projectCompilerResult.program,
|
||||||
|
@ -236,11 +236,11 @@ class ProjectRunner extends RunnerBase {
|
||||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) {
|
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||||
// convert file name to rooted name
|
// convert file name to rooted name
|
||||||
// if filename is not rooted - concat it with project root and then expand project root relative to current directory
|
// if filename is not rooted - concat it with project root and then expand project root relative to current directory
|
||||||
let diskFileName = ts.isRootedDiskPath(fileName)
|
const diskFileName = ts.isRootedDiskPath(fileName)
|
||||||
? fileName
|
? fileName
|
||||||
: Harness.IO.resolvePath(ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName));
|
: Harness.IO.resolvePath(ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName));
|
||||||
|
|
||||||
let currentDirectory = getCurrentDirectory();
|
const currentDirectory = getCurrentDirectory();
|
||||||
// compute file name relative to current directory (expanded project root)
|
// compute file name relative to current directory (expanded project root)
|
||||||
let diskRelativeName = ts.getRelativePathToDirectoryOrUrl(currentDirectory, diskFileName, currentDirectory, Harness.Compiler.getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
|
let diskRelativeName = ts.getRelativePathToDirectoryOrUrl(currentDirectory, diskFileName, currentDirectory, Harness.Compiler.getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
|
||||||
if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") {
|
if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") {
|
||||||
|
@ -254,14 +254,14 @@ class ProjectRunner extends RunnerBase {
|
||||||
|
|
||||||
if (Harness.Compiler.isJS(fileName)) {
|
if (Harness.Compiler.isJS(fileName)) {
|
||||||
// Make sure if there is URl we have it cleaned up
|
// Make sure if there is URl we have it cleaned up
|
||||||
let indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL=");
|
const indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL=");
|
||||||
if (indexOfSourceMapUrl !== -1) {
|
if (indexOfSourceMapUrl !== -1) {
|
||||||
data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21));
|
data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Harness.Compiler.isJSMap(fileName)) {
|
else if (Harness.Compiler.isJSMap(fileName)) {
|
||||||
// Make sure sources list is cleaned
|
// Make sure sources list is cleaned
|
||||||
let sourceMapData = JSON.parse(data);
|
const sourceMapData = JSON.parse(data);
|
||||||
for (let i = 0; i < sourceMapData.sources.length; i++) {
|
for (let i = 0; i < sourceMapData.sources.length; i++) {
|
||||||
sourceMapData.sources[i] = cleanProjectUrl(sourceMapData.sources[i]);
|
sourceMapData.sources[i] = cleanProjectUrl(sourceMapData.sources[i]);
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ class ProjectRunner extends RunnerBase {
|
||||||
data = JSON.stringify(sourceMapData);
|
data = JSON.stringify(sourceMapData);
|
||||||
}
|
}
|
||||||
|
|
||||||
let outputFilePath = getProjectOutputFolder(diskRelativeName, moduleKind);
|
const outputFilePath = getProjectOutputFolder(diskRelativeName, moduleKind);
|
||||||
// Actual writing of file as in tc.ts
|
// Actual writing of file as in tc.ts
|
||||||
function ensureDirectoryStructure(directoryname: string) {
|
function ensureDirectoryStructure(directoryname: string) {
|
||||||
if (directoryname) {
|
if (directoryname) {
|
||||||
|
@ -287,8 +287,8 @@ class ProjectRunner extends RunnerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
|
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
|
||||||
let allInputFiles: { emittedFileName: string; code: string; }[] = [];
|
const allInputFiles: { emittedFileName: string; code: string; }[] = [];
|
||||||
let compilerOptions = compilerResult.program.getCompilerOptions();
|
const compilerOptions = compilerResult.program.getCompilerOptions();
|
||||||
|
|
||||||
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
|
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
|
||||||
if (Harness.Compiler.isDTS(sourceFile.fileName)) {
|
if (Harness.Compiler.isDTS(sourceFile.fileName)) {
|
||||||
|
@ -305,15 +305,15 @@ class ProjectRunner extends RunnerBase {
|
||||||
emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
|
emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
let outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
|
const outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
|
||||||
let file = findOutpuDtsFile(outputDtsFileName);
|
const file = findOutpuDtsFile(outputDtsFileName);
|
||||||
if (file) {
|
if (file) {
|
||||||
allInputFiles.unshift(file);
|
allInputFiles.unshift(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts";
|
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts";
|
||||||
let outputDtsFile = findOutpuDtsFile(outputDtsFileName);
|
const outputDtsFile = findOutpuDtsFile(outputDtsFileName);
|
||||||
if (!ts.contains(allInputFiles, outputDtsFile)) {
|
if (!ts.contains(allInputFiles, outputDtsFile)) {
|
||||||
allInputFiles.unshift(outputDtsFile);
|
allInputFiles.unshift(outputDtsFile);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ class ProjectRunner extends RunnerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
||||||
let inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
const inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||||
sourceFile => sourceFile.fileName !== "lib.d.ts"),
|
sourceFile => sourceFile.fileName !== "lib.d.ts"),
|
||||||
sourceFile => {
|
sourceFile => {
|
||||||
return { unitName: RunnerBase.removeFullPaths(sourceFile.fileName), content: sourceFile.text };
|
return { unitName: RunnerBase.removeFullPaths(sourceFile.fileName), content: sourceFile.text };
|
||||||
|
@ -355,7 +355,7 @@ class ProjectRunner extends RunnerBase {
|
||||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = "Compiling project for " + testCase.scenario + ": testcase " + testCaseFileName;
|
const name = "Compiling project for " + testCase.scenario + ": testcase " + testCaseFileName;
|
||||||
|
|
||||||
describe("Projects tests", () => {
|
describe("Projects tests", () => {
|
||||||
describe(name, () => {
|
describe(name, () => {
|
||||||
|
@ -363,7 +363,7 @@ class ProjectRunner extends RunnerBase {
|
||||||
let compilerResult: BatchCompileProjectTestCaseResult;
|
let compilerResult: BatchCompileProjectTestCaseResult;
|
||||||
|
|
||||||
function getCompilerResolutionInfo() {
|
function getCompilerResolutionInfo() {
|
||||||
let resolutionInfo: ProjectRunnerTestCaseResolutionInfo = {
|
const resolutionInfo: ProjectRunnerTestCaseResolutionInfo = {
|
||||||
scenario: testCase.scenario,
|
scenario: testCase.scenario,
|
||||||
projectRoot: testCase.projectRoot,
|
projectRoot: testCase.projectRoot,
|
||||||
inputFiles: testCase.inputFiles,
|
inputFiles: testCase.inputFiles,
|
||||||
|
@ -441,7 +441,7 @@ class ProjectRunner extends RunnerBase {
|
||||||
|
|
||||||
it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||||
if (!compilerResult.errors.length && testCase.declaration) {
|
if (!compilerResult.errors.length && testCase.declaration) {
|
||||||
let dTsCompileResult = compileCompileDTsFiles(compilerResult);
|
const dTsCompileResult = compileCompileDTsFiles(compilerResult);
|
||||||
if (dTsCompileResult.errors.length) {
|
if (dTsCompileResult.errors.length) {
|
||||||
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
|
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
|
||||||
return getErrorsBaseline(dTsCompileResult);
|
return getErrorsBaseline(dTsCompileResult);
|
||||||
|
|
|
@ -41,13 +41,13 @@ let testConfigFile =
|
||||||
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : "");
|
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : "");
|
||||||
|
|
||||||
if (testConfigFile !== "") {
|
if (testConfigFile !== "") {
|
||||||
let testConfig = JSON.parse(testConfigFile);
|
const testConfig = JSON.parse(testConfigFile);
|
||||||
if (testConfig.light) {
|
if (testConfig.light) {
|
||||||
Harness.lightMode = true;
|
Harness.lightMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testConfig.test && testConfig.test.length > 0) {
|
if (testConfig.test && testConfig.test.length > 0) {
|
||||||
for (let option of testConfig.test) {
|
for (const option of testConfig.test) {
|
||||||
if (!option) {
|
if (!option) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,14 @@ abstract class RunnerBase {
|
||||||
let fixedPath = path;
|
let fixedPath = path;
|
||||||
|
|
||||||
// full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point
|
// full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point
|
||||||
let fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
|
const fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
|
||||||
let fullPathList = fixedPath.match(fullPath);
|
const fullPathList = fixedPath.match(fullPath);
|
||||||
if (fullPathList) {
|
if (fullPathList) {
|
||||||
fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match)));
|
fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// when running in the browser the 'full path' is the host name, shows up in error baselines
|
// when running in the browser the 'full path' is the host name, shows up in error baselines
|
||||||
let localHost = /http:\/localhost:\d+/g;
|
const localHost = /http:\/localhost:\d+/g;
|
||||||
fixedPath = fixedPath.replace(localHost, "");
|
fixedPath = fixedPath.replace(localHost, "");
|
||||||
return fixedPath;
|
return fixedPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
namespace RWC {
|
namespace RWC {
|
||||||
function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) {
|
function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) {
|
||||||
let oldIO = Harness.IO;
|
const oldIO = Harness.IO;
|
||||||
|
|
||||||
let wrappedIO = Playback.wrapIO(oldIO);
|
const wrappedIO = Playback.wrapIO(oldIO);
|
||||||
wrappedIO.startReplayFromData(ioLog);
|
wrappedIO.startReplayFromData(ioLog);
|
||||||
Harness.IO = wrappedIO;
|
Harness.IO = wrappedIO;
|
||||||
|
|
||||||
|
@ -55,10 +55,10 @@ namespace RWC {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can compile", () => {
|
it("can compile", () => {
|
||||||
let harnessCompiler = Harness.Compiler.getCompiler();
|
const harnessCompiler = Harness.Compiler.getCompiler();
|
||||||
let opts: ts.ParsedCommandLine;
|
let opts: ts.ParsedCommandLine;
|
||||||
|
|
||||||
let ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
const ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||||
currentDirectory = ioLog.currentDirectory;
|
currentDirectory = ioLog.currentDirectory;
|
||||||
useCustomLibraryFile = ioLog.useCustomLibraryFile;
|
useCustomLibraryFile = ioLog.useCustomLibraryFile;
|
||||||
runWithIOLog(ioLog, () => {
|
runWithIOLog(ioLog, () => {
|
||||||
|
@ -75,26 +75,26 @@ namespace RWC {
|
||||||
|
|
||||||
let fileNames = opts.fileNames;
|
let fileNames = opts.fileNames;
|
||||||
|
|
||||||
let tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined);
|
const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined);
|
||||||
if (tsconfigFile) {
|
if (tsconfigFile) {
|
||||||
let tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path);
|
const tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path);
|
||||||
let parsedTsconfigFileContents = ts.parseConfigFileTextToJson(tsconfigFile.path, tsconfigFileContents.content);
|
const parsedTsconfigFileContents = ts.parseConfigFileTextToJson(tsconfigFile.path, tsconfigFileContents.content);
|
||||||
let configParseResult = ts.parseJsonConfigFileContent(parsedTsconfigFileContents.config, Harness.IO, ts.getDirectoryPath(tsconfigFile.path));
|
const configParseResult = ts.parseJsonConfigFileContent(parsedTsconfigFileContents.config, Harness.IO, ts.getDirectoryPath(tsconfigFile.path));
|
||||||
fileNames = configParseResult.fileNames;
|
fileNames = configParseResult.fileNames;
|
||||||
opts.options = ts.extend(opts.options, configParseResult.options);
|
opts.options = ts.extend(opts.options, configParseResult.options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the files
|
// Load the files
|
||||||
for (let fileName of fileNames) {
|
for (const fileName of fileNames) {
|
||||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add files to compilation
|
// Add files to compilation
|
||||||
let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath;
|
const isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath;
|
||||||
for (let fileRead of ioLog.filesRead) {
|
for (const fileRead of ioLog.filesRead) {
|
||||||
// Check if the file is already added into the set of input files.
|
// Check if the file is already added into the set of input files.
|
||||||
const resolvedPath = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path));
|
const resolvedPath = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path));
|
||||||
let inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath));
|
const inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath));
|
||||||
|
|
||||||
if (isTsConfigFile(fileRead)) {
|
if (isTsConfigFile(fileRead)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -139,7 +139,7 @@ namespace RWC {
|
||||||
});
|
});
|
||||||
|
|
||||||
function getHarnessCompilerInputUnit(fileName: string) {
|
function getHarnessCompilerInputUnit(fileName: string) {
|
||||||
let unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
|
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
|
||||||
let content: string = null;
|
let content: string = null;
|
||||||
try {
|
try {
|
||||||
content = Harness.IO.readFile(unitName);
|
content = Harness.IO.readFile(unitName);
|
||||||
|
@ -201,7 +201,7 @@ namespace RWC {
|
||||||
it("has the expected errors in generated declaration files", () => {
|
it("has the expected errors in generated declaration files", () => {
|
||||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||||
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
|
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
|
||||||
let declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
|
const declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
|
||||||
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
|
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
|
||||||
if (declFileCompilationResult.declResult.errors.length === 0) {
|
if (declFileCompilationResult.declResult.errors.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -227,7 +227,7 @@ class RWCRunner extends RunnerBase {
|
||||||
*/
|
*/
|
||||||
public initializeTests(): void {
|
public initializeTests(): void {
|
||||||
// Read in and evaluate the test list
|
// Read in and evaluate the test list
|
||||||
let testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
|
const testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
|
||||||
for (let i = 0; i < testList.length; i++) {
|
for (let i = 0; i < testList.length; i++) {
|
||||||
this.runTest(testList[i]);
|
this.runTest(testList[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6 digit number
|
// 6 digit number
|
||||||
let currentByte = base64FormatDecode();
|
const currentByte = base64FormatDecode();
|
||||||
|
|
||||||
// If msb is set, we still have more bits to continue
|
// If msb is set, we still have more bits to continue
|
||||||
moreDigits = (currentByte & 32) !== 0;
|
moreDigits = (currentByte & 32) !== 0;
|
||||||
|
@ -259,7 +259,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
|
|
||||||
export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) {
|
export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) {
|
||||||
// verify the decoded span is same as the new span
|
// verify the decoded span is same as the new span
|
||||||
let decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
const decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
||||||
let decodedErrors: string[];
|
let decodedErrors: string[];
|
||||||
if (decodeResult.error
|
if (decodeResult.error
|
||||||
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|
||||||
|
@ -317,8 +317,8 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextOfLine(line: number, lineMap: number[], code: string) {
|
function getTextOfLine(line: number, lineMap: number[], code: string) {
|
||||||
let startPos = lineMap[line];
|
const startPos = lineMap[line];
|
||||||
let endPos = lineMap[line + 1];
|
const endPos = lineMap[line + 1];
|
||||||
return code.substring(startPos, endPos);
|
return code.substring(startPos, endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeRecordedSpans() {
|
function writeRecordedSpans() {
|
||||||
let markerIds: string[] = [];
|
const markerIds: string[] = [];
|
||||||
|
|
||||||
function getMarkerId(markerIndex: number) {
|
function getMarkerId(markerIndex: number) {
|
||||||
let markerId = "";
|
let markerId = "";
|
||||||
|
@ -364,7 +364,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues?: boolean) {
|
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues?: boolean) {
|
||||||
let markerId = getMarkerId(index);
|
const markerId = getMarkerId(index);
|
||||||
markerIds.push(markerId);
|
markerIds.push(markerId);
|
||||||
|
|
||||||
writeSourceMapIndent(prevEmittedCol, markerId);
|
writeSourceMapIndent(prevEmittedCol, markerId);
|
||||||
|
@ -380,7 +380,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeSourceMapSourceText(currentSpan: SourceMapSpanWithDecodeErrors, index: number) {
|
function writeSourceMapSourceText(currentSpan: SourceMapSpanWithDecodeErrors, index: number) {
|
||||||
let sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine - 1] + (currentSpan.sourceMapSpan.sourceColumn - 1);
|
const sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine - 1] + (currentSpan.sourceMapSpan.sourceColumn - 1);
|
||||||
let sourceText = "";
|
let sourceText = "";
|
||||||
if (prevWrittenSourcePos < sourcePos) {
|
if (prevWrittenSourcePos < sourcePos) {
|
||||||
// Position that goes forward, get text
|
// Position that goes forward, get text
|
||||||
|
@ -395,7 +395,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tsCodeLineMap = ts.computeLineStarts(sourceText);
|
const tsCodeLineMap = ts.computeLineStarts(sourceText);
|
||||||
for (let i = 0; i < tsCodeLineMap.length; i++) {
|
for (let i = 0; i < tsCodeLineMap.length; i++) {
|
||||||
writeSourceMapIndent(prevEmittedCol, i === 0 ? markerIds[index] : " >");
|
writeSourceMapIndent(prevEmittedCol, i === 0 ? markerIds[index] : " >");
|
||||||
sourceMapRecoder.Write(getTextOfLine(i, tsCodeLineMap, sourceText));
|
sourceMapRecoder.Write(getTextOfLine(i, tsCodeLineMap, sourceText));
|
||||||
|
@ -412,7 +412,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spansOnSingleLine.length) {
|
if (spansOnSingleLine.length) {
|
||||||
let currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine;
|
const currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine;
|
||||||
|
|
||||||
// Write js line
|
// Write js line
|
||||||
writeJsFileLines(currentJsLine);
|
writeJsFileLines(currentJsLine);
|
||||||
|
@ -420,7 +420,7 @@ namespace Harness.SourceMapRecoder {
|
||||||
// Emit markers
|
// Emit markers
|
||||||
iterateSpans(writeSourceMapMarker);
|
iterateSpans(writeSourceMapMarker);
|
||||||
|
|
||||||
let jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code);
|
const jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code);
|
||||||
if (prevEmittedCol < jsFileText.length) {
|
if (prevEmittedCol < jsFileText.length) {
|
||||||
// There is remaining text on this line that will be part of next source span so write marker that continues
|
// There is remaining text on this line that will be part of next source span so write marker that continues
|
||||||
writeSourceMapMarker(undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true);
|
writeSourceMapMarker(undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true);
|
||||||
|
@ -438,16 +438,16 @@ namespace Harness.SourceMapRecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSourceMapRecord(sourceMapDataList: ts.SourceMapData[], program: ts.Program, jsFiles: Compiler.GeneratedFile[]) {
|
export function getSourceMapRecord(sourceMapDataList: ts.SourceMapData[], program: ts.Program, jsFiles: Compiler.GeneratedFile[]) {
|
||||||
let sourceMapRecoder = new Compiler.WriterAggregator();
|
const sourceMapRecoder = new Compiler.WriterAggregator();
|
||||||
|
|
||||||
for (let i = 0; i < sourceMapDataList.length; i++) {
|
for (let i = 0; i < sourceMapDataList.length; i++) {
|
||||||
let sourceMapData = sourceMapDataList[i];
|
const sourceMapData = sourceMapDataList[i];
|
||||||
let prevSourceFile: ts.SourceFile;
|
let prevSourceFile: ts.SourceFile;
|
||||||
|
|
||||||
SourceMapSpanWriter.intializeSourceMapSpanWriter(sourceMapRecoder, sourceMapData, jsFiles[i]);
|
SourceMapSpanWriter.intializeSourceMapSpanWriter(sourceMapRecoder, sourceMapData, jsFiles[i]);
|
||||||
for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
|
for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
|
||||||
let decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
|
const decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
|
||||||
let currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
|
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
|
||||||
if (currentSourceFile !== prevSourceFile) {
|
if (currentSourceFile !== prevSourceFile) {
|
||||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||||
prevSourceFile = currentSourceFile;
|
prevSourceFile = currentSourceFile;
|
||||||
|
|
|
@ -36,11 +36,11 @@ class Test262BaselineRunner extends RunnerBase {
|
||||||
};
|
};
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
let content = Harness.IO.readFile(filePath);
|
const content = Harness.IO.readFile(filePath);
|
||||||
let testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
|
const testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
|
||||||
let testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
|
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
|
||||||
|
|
||||||
let inputFiles = testCaseContent.testUnitData.map(unit => {
|
const inputFiles = testCaseContent.testUnitData.map(unit => {
|
||||||
return { unitName: Test262BaselineRunner.getTestFilePath(unit.name), content: unit.content };
|
return { unitName: Test262BaselineRunner.getTestFilePath(unit.name), content: unit.content };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -64,14 +64,14 @@ class Test262BaselineRunner extends RunnerBase {
|
||||||
|
|
||||||
it("has the expected emitted code", () => {
|
it("has the expected emitted code", () => {
|
||||||
Harness.Baseline.runBaseline("has the expected emitted code", testState.filename + ".output.js", () => {
|
Harness.Baseline.runBaseline("has the expected emitted code", testState.filename + ".output.js", () => {
|
||||||
let files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath);
|
const files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath);
|
||||||
return Harness.Compiler.collateOutputs(files);
|
return Harness.Compiler.collateOutputs(files);
|
||||||
}, false, Test262BaselineRunner.baselineOptions);
|
}, false, Test262BaselineRunner.baselineOptions);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("has the expected errors", () => {
|
it("has the expected errors", () => {
|
||||||
Harness.Baseline.runBaseline("has the expected errors", testState.filename + ".errors.txt", () => {
|
Harness.Baseline.runBaseline("has the expected errors", testState.filename + ".errors.txt", () => {
|
||||||
let errors = testState.compilerResult.errors;
|
const errors = testState.compilerResult.errors;
|
||||||
if (errors.length === 0) {
|
if (errors.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -81,13 +81,13 @@ class Test262BaselineRunner extends RunnerBase {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("satisfies inletiants", () => {
|
it("satisfies inletiants", () => {
|
||||||
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||||
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
|
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("has the expected AST", () => {
|
it("has the expected AST", () => {
|
||||||
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
|
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
|
||||||
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||||
return Utils.sourceFileToJSON(sourceFile);
|
return Utils.sourceFileToJSON(sourceFile);
|
||||||
}, false, Test262BaselineRunner.baselineOptions);
|
}, false, Test262BaselineRunner.baselineOptions);
|
||||||
});
|
});
|
||||||
|
@ -97,7 +97,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||||
public initializeTests() {
|
public initializeTests() {
|
||||||
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
|
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
|
||||||
if (this.tests.length === 0) {
|
if (this.tests.length === 0) {
|
||||||
let testFiles = this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true });
|
const testFiles = this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true });
|
||||||
testFiles.forEach(fn => {
|
testFiles.forEach(fn => {
|
||||||
this.runTest(ts.normalizePath(fn));
|
this.runTest(ts.normalizePath(fn));
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,7 @@ class TypeWriterWalker {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTypeAndSymbols(fileName: string): TypeWriterResult[] {
|
public getTypeAndSymbols(fileName: string): TypeWriterResult[] {
|
||||||
let sourceFile = this.program.getSourceFile(fileName);
|
const sourceFile = this.program.getSourceFile(fileName);
|
||||||
this.currentSourceFile = sourceFile;
|
this.currentSourceFile = sourceFile;
|
||||||
this.results = [];
|
this.results = [];
|
||||||
this.visitNode(sourceFile);
|
this.visitNode(sourceFile);
|
||||||
|
@ -37,28 +37,28 @@ class TypeWriterWalker {
|
||||||
}
|
}
|
||||||
|
|
||||||
private logTypeAndSymbol(node: ts.Node): void {
|
private logTypeAndSymbol(node: ts.Node): void {
|
||||||
let actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
const actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
||||||
let lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
const lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
||||||
let sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
|
const sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
|
||||||
|
|
||||||
// Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions
|
// Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions
|
||||||
// let type = this.checker.getTypeAtLocation(node);
|
// let type = this.checker.getTypeAtLocation(node);
|
||||||
let type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node);
|
const type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node);
|
||||||
|
|
||||||
ts.Debug.assert(type !== undefined, "type doesn't exist");
|
ts.Debug.assert(type !== undefined, "type doesn't exist");
|
||||||
let symbol = this.checker.getSymbolAtLocation(node);
|
const symbol = this.checker.getSymbolAtLocation(node);
|
||||||
|
|
||||||
let typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation);
|
const typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation);
|
||||||
let symbolString: string;
|
let symbolString: string;
|
||||||
if (symbol) {
|
if (symbol) {
|
||||||
symbolString = "Symbol(" + this.checker.symbolToString(symbol, node.parent);
|
symbolString = "Symbol(" + this.checker.symbolToString(symbol, node.parent);
|
||||||
if (symbol.declarations) {
|
if (symbol.declarations) {
|
||||||
for (let declaration of symbol.declarations) {
|
for (const declaration of symbol.declarations) {
|
||||||
symbolString += ", ";
|
symbolString += ", ";
|
||||||
let declSourceFile = declaration.getSourceFile();
|
const declSourceFile = declaration.getSourceFile();
|
||||||
let declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos);
|
const declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos);
|
||||||
let fileName = ts.getBaseFileName(declSourceFile.fileName);
|
const fileName = ts.getBaseFileName(declSourceFile.fileName);
|
||||||
let isLibFile = /lib(.*)\.d\.ts/i.test(fileName);
|
const isLibFile = /lib(.*)\.d\.ts/i.test(fileName);
|
||||||
symbolString += `Decl(${ fileName }, ${ isLibFile ? "--" : declLineAndCharacter.line }, ${ isLibFile ? "--" : declLineAndCharacter.character })`;
|
symbolString += `Decl(${ fileName }, ${ isLibFile ? "--" : declLineAndCharacter.line }, ${ isLibFile ? "--" : declLineAndCharacter.character })`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
8
src/lib/README.md
Normal file
8
src/lib/README.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Read this!
|
||||||
|
|
||||||
|
The files within this directory are used to generate `lib.d.ts` and `lib.es6.d.ts`.
|
||||||
|
|
||||||
|
## Generated files
|
||||||
|
|
||||||
|
Any files ending in `.generated.d.ts` aren't mean to be edited by hand.
|
||||||
|
If you need to make changes to such files, make a change to the input files for our [library generator](https://github.com/Microsoft/TSJS-lib-generator).
|
|
@ -105,19 +105,19 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] {
|
resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] {
|
||||||
let path = toPath(containingFile, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
const path = toPath(containingFile, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
||||||
let currentResolutionsInFile = this.resolvedModuleNames.get(path);
|
const currentResolutionsInFile = this.resolvedModuleNames.get(path);
|
||||||
|
|
||||||
let newResolutions: Map<TimestampedResolvedModule> = {};
|
const newResolutions: Map<TimestampedResolvedModule> = {};
|
||||||
let resolvedModules: ResolvedModule[] = [];
|
const resolvedModules: ResolvedModule[] = [];
|
||||||
|
|
||||||
let compilerOptions = this.getCompilationSettings();
|
const compilerOptions = this.getCompilationSettings();
|
||||||
|
|
||||||
for (let moduleName of moduleNames) {
|
for (const moduleName of moduleNames) {
|
||||||
// check if this is a duplicate entry in the list
|
// check if this is a duplicate entry in the list
|
||||||
let resolution = lookUp(newResolutions, moduleName);
|
let resolution = lookUp(newResolutions, moduleName);
|
||||||
if (!resolution) {
|
if (!resolution) {
|
||||||
let existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, moduleName);
|
const existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, moduleName);
|
||||||
if (moduleResolutionIsValid(existingResolution)) {
|
if (moduleResolutionIsValid(existingResolution)) {
|
||||||
// ok, it is safe to use existing module resolution results
|
// ok, it is safe to use existing module resolution results
|
||||||
resolution = existingResolution;
|
resolution = existingResolution;
|
||||||
|
@ -211,7 +211,7 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
|
|
||||||
getScriptInfo(filename: string): ScriptInfo {
|
getScriptInfo(filename: string): ScriptInfo {
|
||||||
let path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
const path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
||||||
let scriptInfo = this.filenameToScript.get(path);
|
let scriptInfo = this.filenameToScript.get(path);
|
||||||
if (!scriptInfo) {
|
if (!scriptInfo) {
|
||||||
scriptInfo = this.project.openReferencedFile(filename);
|
scriptInfo = this.project.openReferencedFile(filename);
|
||||||
|
@ -282,7 +282,7 @@ namespace ts.server {
|
||||||
* @param line 1 based index
|
* @param line 1 based index
|
||||||
*/
|
*/
|
||||||
lineToTextSpan(filename: string, line: number): ts.TextSpan {
|
lineToTextSpan(filename: string, line: number): ts.TextSpan {
|
||||||
let path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
const path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
||||||
const script: ScriptInfo = this.filenameToScript.get(path);
|
const script: ScriptInfo = this.filenameToScript.get(path);
|
||||||
const index = script.snap().index;
|
const index = script.snap().index;
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ namespace ts.server {
|
||||||
* @param offset 1 based index
|
* @param offset 1 based index
|
||||||
*/
|
*/
|
||||||
lineOffsetToPosition(filename: string, line: number, offset: number): number {
|
lineOffsetToPosition(filename: string, line: number, offset: number): number {
|
||||||
let path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
const path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
||||||
const script: ScriptInfo = this.filenameToScript.get(path);
|
const script: ScriptInfo = this.filenameToScript.get(path);
|
||||||
const index = script.snap().index;
|
const index = script.snap().index;
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ namespace ts.server {
|
||||||
* @param offset 1-based index
|
* @param offset 1-based index
|
||||||
*/
|
*/
|
||||||
positionToLineOffset(filename: string, position: number): ILineInfo {
|
positionToLineOffset(filename: string, position: number): ILineInfo {
|
||||||
let path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
const path = toPath(filename, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
||||||
const script: ScriptInfo = this.filenameToScript.get(path);
|
const script: ScriptInfo = this.filenameToScript.get(path);
|
||||||
const index = script.snap().index;
|
const index = script.snap().index;
|
||||||
const lineOffset = index.charOffsetToLineNumberAndPos(position);
|
const lineOffset = index.charOffsetToLineNumberAndPos(position);
|
||||||
|
@ -578,9 +578,9 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleProjectFilelistChanges(project: Project) {
|
handleProjectFilelistChanges(project: Project) {
|
||||||
let { succeeded, projectOptions, error } = this.configFileToProjectOptions(project.projectFilename);
|
const { succeeded, projectOptions, error } = this.configFileToProjectOptions(project.projectFilename);
|
||||||
let newRootFiles = projectOptions.files.map((f => this.getCanonicalFileName(f)));
|
const newRootFiles = projectOptions.files.map((f => this.getCanonicalFileName(f)));
|
||||||
let currentRootFiles = project.getRootFiles().map((f => this.getCanonicalFileName(f)));
|
const currentRootFiles = project.getRootFiles().map((f => this.getCanonicalFileName(f)));
|
||||||
|
|
||||||
// We check if the project file list has changed. If so, we update the project.
|
// We check if the project file list has changed. If so, we update the project.
|
||||||
if (!arrayIsEqualTo(currentRootFiles && currentRootFiles.sort(), newRootFiles && newRootFiles.sort())) {
|
if (!arrayIsEqualTo(currentRootFiles && currentRootFiles.sort(), newRootFiles && newRootFiles.sort())) {
|
||||||
|
@ -606,13 +606,13 @@ namespace ts.server {
|
||||||
|
|
||||||
this.log("Detected newly added tsconfig file: " + fileName);
|
this.log("Detected newly added tsconfig file: " + fileName);
|
||||||
|
|
||||||
let { succeeded, projectOptions, error } = this.configFileToProjectOptions(fileName);
|
const { succeeded, projectOptions, error } = this.configFileToProjectOptions(fileName);
|
||||||
let rootFilesInTsconfig = projectOptions.files.map(f => this.getCanonicalFileName(f));
|
const rootFilesInTsconfig = projectOptions.files.map(f => this.getCanonicalFileName(f));
|
||||||
let openFileRoots = this.openFileRoots.map(s => this.getCanonicalFileName(s.fileName));
|
const openFileRoots = this.openFileRoots.map(s => this.getCanonicalFileName(s.fileName));
|
||||||
|
|
||||||
// We should only care about the new tsconfig file if it contains any
|
// We should only care about the new tsconfig file if it contains any
|
||||||
// opened root files of existing inferred projects
|
// opened root files of existing inferred projects
|
||||||
for (let openFileRoot of openFileRoots) {
|
for (const openFileRoot of openFileRoots) {
|
||||||
if (rootFilesInTsconfig.indexOf(openFileRoot) >= 0) {
|
if (rootFilesInTsconfig.indexOf(openFileRoot) >= 0) {
|
||||||
this.reloadProjects();
|
this.reloadProjects();
|
||||||
return;
|
return;
|
||||||
|
@ -621,7 +621,7 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCanonicalFileName(fileName: string) {
|
getCanonicalFileName(fileName: string) {
|
||||||
let name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
const name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||||
return ts.normalizePath(name);
|
return ts.normalizePath(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,7 +737,7 @@ namespace ts.server {
|
||||||
this.configuredProjects = copyListRemovingItem(project, this.configuredProjects);
|
this.configuredProjects = copyListRemovingItem(project, this.configuredProjects);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (let directory of project.directoriesWatchedForTsconfig) {
|
for (const directory of project.directoriesWatchedForTsconfig) {
|
||||||
// if the ref count for this directory watcher drops to 0, it's time to close it
|
// if the ref count for this directory watcher drops to 0, it's time to close it
|
||||||
if (!(--project.projectService.directoryWatchersRefCount[directory])) {
|
if (!(--project.projectService.directoryWatchersRefCount[directory])) {
|
||||||
this.log("Close directory watcher for: " + directory);
|
this.log("Close directory watcher for: " + directory);
|
||||||
|
@ -748,9 +748,9 @@ namespace ts.server {
|
||||||
this.inferredProjects = copyListRemovingItem(project, this.inferredProjects);
|
this.inferredProjects = copyListRemovingItem(project, this.inferredProjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
let fileNames = project.getFileNames();
|
const fileNames = project.getFileNames();
|
||||||
for (let fileName of fileNames) {
|
for (const fileName of fileNames) {
|
||||||
let info = this.getScriptInfo(fileName);
|
const info = this.getScriptInfo(fileName);
|
||||||
if (info.defaultProject == project) {
|
if (info.defaultProject == project) {
|
||||||
info.defaultProject = undefined;
|
info.defaultProject = undefined;
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,7 @@ namespace ts.server {
|
||||||
|
|
||||||
setConfiguredProjectRoot(info: ScriptInfo) {
|
setConfiguredProjectRoot(info: ScriptInfo) {
|
||||||
for (let i = 0, len = this.configuredProjects.length; i < len; i++) {
|
for (let i = 0, len = this.configuredProjects.length; i < len; i++) {
|
||||||
let configuredProject = this.configuredProjects[i];
|
const configuredProject = this.configuredProjects[i];
|
||||||
if (configuredProject.isRoot(info)) {
|
if (configuredProject.isRoot(info)) {
|
||||||
info.defaultProject = configuredProject;
|
info.defaultProject = configuredProject;
|
||||||
configuredProject.addOpenRef();
|
configuredProject.addOpenRef();
|
||||||
|
@ -903,7 +903,7 @@ namespace ts.server {
|
||||||
reloadProjects() {
|
reloadProjects() {
|
||||||
this.log("reload projects.");
|
this.log("reload projects.");
|
||||||
// First check if there is new tsconfig file added for inferred project roots
|
// First check if there is new tsconfig file added for inferred project roots
|
||||||
for (let info of this.openFileRoots) {
|
for (const info of this.openFileRoots) {
|
||||||
this.openOrUpdateConfiguredProjectForFile(info.fileName);
|
this.openOrUpdateConfiguredProjectForFile(info.fileName);
|
||||||
}
|
}
|
||||||
this.updateProjectStructure();
|
this.updateProjectStructure();
|
||||||
|
@ -918,10 +918,10 @@ namespace ts.server {
|
||||||
this.log("updating project structure from ...", "Info");
|
this.log("updating project structure from ...", "Info");
|
||||||
this.printProjects();
|
this.printProjects();
|
||||||
|
|
||||||
let unattachedOpenFiles: ScriptInfo[] = [];
|
const unattachedOpenFiles: ScriptInfo[] = [];
|
||||||
let openFileRootsConfigured: ScriptInfo[] = [];
|
const openFileRootsConfigured: ScriptInfo[] = [];
|
||||||
for (let info of this.openFileRootsConfigured) {
|
for (const info of this.openFileRootsConfigured) {
|
||||||
let project = info.defaultProject;
|
const project = info.defaultProject;
|
||||||
if (!project || !(project.getSourceFile(info))) {
|
if (!project || !(project.getSourceFile(info))) {
|
||||||
info.defaultProject = undefined;
|
info.defaultProject = undefined;
|
||||||
unattachedOpenFiles.push(info);
|
unattachedOpenFiles.push(info);
|
||||||
|
@ -1016,7 +1016,6 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (content !== undefined) {
|
if (content !== undefined) {
|
||||||
let indentSize: number;
|
|
||||||
info = new ScriptInfo(this.host, fileName, content, openedByClient);
|
info = new ScriptInfo(this.host, fileName, content, openedByClient);
|
||||||
info.setFormatOptions(this.getFormatCodeOptions());
|
info.setFormatOptions(this.getFormatCodeOptions());
|
||||||
this.filenameToScriptInfo[fileName] = info;
|
this.filenameToScriptInfo[fileName] = info;
|
||||||
|
@ -1071,12 +1070,12 @@ namespace ts.server {
|
||||||
* the tsconfig file content and update the project; otherwise we create a new one.
|
* the tsconfig file content and update the project; otherwise we create a new one.
|
||||||
*/
|
*/
|
||||||
openOrUpdateConfiguredProjectForFile(fileName: string) {
|
openOrUpdateConfiguredProjectForFile(fileName: string) {
|
||||||
let searchPath = ts.normalizePath(getDirectoryPath(fileName));
|
const searchPath = ts.normalizePath(getDirectoryPath(fileName));
|
||||||
this.log("Search path: " + searchPath, "Info");
|
this.log("Search path: " + searchPath, "Info");
|
||||||
let configFileName = this.findConfigFile(searchPath);
|
const configFileName = this.findConfigFile(searchPath);
|
||||||
if (configFileName) {
|
if (configFileName) {
|
||||||
this.log("Config file name: " + configFileName, "Info");
|
this.log("Config file name: " + configFileName, "Info");
|
||||||
let project = this.findConfiguredProjectByConfigFile(configFileName);
|
const project = this.findConfiguredProjectByConfigFile(configFileName);
|
||||||
if (!project) {
|
if (!project) {
|
||||||
const configResult = this.openConfigFile(configFileName, fileName);
|
const configResult = this.openConfigFile(configFileName, fileName);
|
||||||
if (!configResult.success) {
|
if (!configResult.success) {
|
||||||
|
@ -1215,15 +1214,15 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
|
|
||||||
openConfigFile(configFilename: string, clientFileName?: string): ProjectOpenResult {
|
openConfigFile(configFilename: string, clientFileName?: string): ProjectOpenResult {
|
||||||
let { succeeded, projectOptions, error } = this.configFileToProjectOptions(configFilename);
|
const { succeeded, projectOptions, error } = this.configFileToProjectOptions(configFilename);
|
||||||
if (!succeeded) {
|
if (!succeeded) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let project = this.createProject(configFilename, projectOptions);
|
const project = this.createProject(configFilename, projectOptions);
|
||||||
for (let rootFilename of projectOptions.files) {
|
for (const rootFilename of projectOptions.files) {
|
||||||
if (this.host.fileExists(rootFilename)) {
|
if (this.host.fileExists(rootFilename)) {
|
||||||
let info = this.openFile(rootFilename, /*openedByClient*/ clientFileName == rootFilename);
|
const info = this.openFile(rootFilename, /*openedByClient*/ clientFileName == rootFilename);
|
||||||
project.addRoot(info);
|
project.addRoot(info);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1248,24 +1247,24 @@ namespace ts.server {
|
||||||
this.removeProject(project);
|
this.removeProject(project);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let { succeeded, projectOptions, error } = this.configFileToProjectOptions(project.projectFilename);
|
const { succeeded, projectOptions, error } = this.configFileToProjectOptions(project.projectFilename);
|
||||||
if (!succeeded) {
|
if (!succeeded) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let oldFileNames = project.compilerService.host.roots.map(info => info.fileName);
|
const oldFileNames = project.compilerService.host.roots.map(info => info.fileName);
|
||||||
let newFileNames = projectOptions.files;
|
const newFileNames = projectOptions.files;
|
||||||
let fileNamesToRemove = oldFileNames.filter(f => newFileNames.indexOf(f) < 0);
|
const fileNamesToRemove = oldFileNames.filter(f => newFileNames.indexOf(f) < 0);
|
||||||
let fileNamesToAdd = newFileNames.filter(f => oldFileNames.indexOf(f) < 0);
|
const fileNamesToAdd = newFileNames.filter(f => oldFileNames.indexOf(f) < 0);
|
||||||
|
|
||||||
for (let fileName of fileNamesToRemove) {
|
for (const fileName of fileNamesToRemove) {
|
||||||
let info = this.getScriptInfo(fileName);
|
const info = this.getScriptInfo(fileName);
|
||||||
if (info) {
|
if (info) {
|
||||||
project.removeRoot(info);
|
project.removeRoot(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let fileName of fileNamesToAdd) {
|
for (const fileName of fileNamesToAdd) {
|
||||||
let info = this.getScriptInfo(fileName);
|
let info = this.getScriptInfo(fileName);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
info = this.openFile(fileName, false);
|
info = this.openFile(fileName, false);
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace ts.server {
|
||||||
|
|
||||||
const logger = createLoggerFromEnv();
|
const logger = createLoggerFromEnv();
|
||||||
|
|
||||||
let pending: string[] = [];
|
const pending: string[] = [];
|
||||||
let canWrite = true;
|
let canWrite = true;
|
||||||
function writeMessage(s: string) {
|
function writeMessage(s: string) {
|
||||||
if (!canWrite) {
|
if (!canWrite) {
|
||||||
|
|
|
@ -338,25 +338,25 @@ namespace ts.server {
|
||||||
|
|
||||||
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[] {
|
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[] {
|
||||||
fileName = ts.normalizePath(fileName);
|
fileName = ts.normalizePath(fileName);
|
||||||
let project = this.projectService.getProjectForFile(fileName);
|
const project = this.projectService.getProjectForFile(fileName);
|
||||||
|
|
||||||
if (!project) {
|
if (!project) {
|
||||||
throw Errors.NoProject;
|
throw Errors.NoProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { compilerService } = project;
|
const { compilerService } = project;
|
||||||
let position = compilerService.host.lineOffsetToPosition(fileName, line, offset);
|
const position = compilerService.host.lineOffsetToPosition(fileName, line, offset);
|
||||||
|
|
||||||
let occurrences = compilerService.languageService.getOccurrencesAtPosition(fileName, position);
|
const occurrences = compilerService.languageService.getOccurrencesAtPosition(fileName, position);
|
||||||
|
|
||||||
if (!occurrences) {
|
if (!occurrences) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return occurrences.map(occurrence => {
|
return occurrences.map(occurrence => {
|
||||||
let { fileName, isWriteAccess, textSpan } = occurrence;
|
const { fileName, isWriteAccess, textSpan } = occurrence;
|
||||||
let start = compilerService.host.positionToLineOffset(fileName, textSpan.start);
|
const start = compilerService.host.positionToLineOffset(fileName, textSpan.start);
|
||||||
let end = compilerService.host.positionToLineOffset(fileName, ts.textSpanEnd(textSpan));
|
const end = compilerService.host.positionToLineOffset(fileName, ts.textSpanEnd(textSpan));
|
||||||
return {
|
return {
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
|
@ -368,16 +368,16 @@ namespace ts.server {
|
||||||
|
|
||||||
private getDocumentHighlights(line: number, offset: number, fileName: string, filesToSearch: string[]): protocol.DocumentHighlightsItem[] {
|
private getDocumentHighlights(line: number, offset: number, fileName: string, filesToSearch: string[]): protocol.DocumentHighlightsItem[] {
|
||||||
fileName = ts.normalizePath(fileName);
|
fileName = ts.normalizePath(fileName);
|
||||||
let project = this.projectService.getProjectForFile(fileName);
|
const project = this.projectService.getProjectForFile(fileName);
|
||||||
|
|
||||||
if (!project) {
|
if (!project) {
|
||||||
throw Errors.NoProject;
|
throw Errors.NoProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { compilerService } = project;
|
const { compilerService } = project;
|
||||||
let position = compilerService.host.lineOffsetToPosition(fileName, line, offset);
|
const position = compilerService.host.lineOffsetToPosition(fileName, line, offset);
|
||||||
|
|
||||||
let documentHighlights = compilerService.languageService.getDocumentHighlights(fileName, position, filesToSearch);
|
const documentHighlights = compilerService.languageService.getDocumentHighlights(fileName, position, filesToSearch);
|
||||||
|
|
||||||
if (!documentHighlights) {
|
if (!documentHighlights) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -386,7 +386,7 @@ namespace ts.server {
|
||||||
return documentHighlights.map(convertToDocumentHighlightsItem);
|
return documentHighlights.map(convertToDocumentHighlightsItem);
|
||||||
|
|
||||||
function convertToDocumentHighlightsItem(documentHighlights: ts.DocumentHighlights): ts.server.protocol.DocumentHighlightsItem {
|
function convertToDocumentHighlightsItem(documentHighlights: ts.DocumentHighlights): ts.server.protocol.DocumentHighlightsItem {
|
||||||
let { fileName, highlightSpans } = documentHighlights;
|
const { fileName, highlightSpans } = documentHighlights;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
file: fileName,
|
file: fileName,
|
||||||
|
@ -394,9 +394,9 @@ namespace ts.server {
|
||||||
};
|
};
|
||||||
|
|
||||||
function convertHighlightSpan(highlightSpan: ts.HighlightSpan): ts.server.protocol.HighlightSpan {
|
function convertHighlightSpan(highlightSpan: ts.HighlightSpan): ts.server.protocol.HighlightSpan {
|
||||||
let { textSpan, kind } = highlightSpan;
|
const { textSpan, kind } = highlightSpan;
|
||||||
let start = compilerService.host.positionToLineOffset(fileName, textSpan.start);
|
const start = compilerService.host.positionToLineOffset(fileName, textSpan.start);
|
||||||
let end = compilerService.host.positionToLineOffset(fileName, ts.textSpanEnd(textSpan));
|
const end = compilerService.host.positionToLineOffset(fileName, ts.textSpanEnd(textSpan));
|
||||||
return { start, end, kind };
|
return { start, end, kind };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,9 +404,9 @@ namespace ts.server {
|
||||||
|
|
||||||
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
|
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
|
||||||
fileName = ts.normalizePath(fileName);
|
fileName = ts.normalizePath(fileName);
|
||||||
let project = this.projectService.getProjectForFile(fileName);
|
const project = this.projectService.getProjectForFile(fileName);
|
||||||
|
|
||||||
let projectInfo: protocol.ProjectInfo = {
|
const projectInfo: protocol.ProjectInfo = {
|
||||||
configFileName: project.projectFilename
|
configFileName: project.projectFilename
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -640,7 +640,7 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
// i points to the first non whitespace character
|
// i points to the first non whitespace character
|
||||||
if (preferredIndent !== hasIndent) {
|
if (preferredIndent !== hasIndent) {
|
||||||
let firstNoWhiteSpacePosition = lineInfo.offset + i;
|
const firstNoWhiteSpacePosition = lineInfo.offset + i;
|
||||||
edits.push({
|
edits.push({
|
||||||
span: ts.createTextSpanFromBounds(lineInfo.offset, firstNoWhiteSpacePosition),
|
span: ts.createTextSpanFromBounds(lineInfo.offset, firstNoWhiteSpacePosition),
|
||||||
newText: generateIndentString(preferredIndent, editorOptions)
|
newText: generateIndentString(preferredIndent, editorOptions)
|
||||||
|
@ -897,22 +897,22 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDiagnosticsForProject(delay: number, fileName: string) {
|
getDiagnosticsForProject(delay: number, fileName: string) {
|
||||||
let { configFileName, fileNames: fileNamesInProject } = this.getProjectInfo(fileName, true);
|
const { configFileName, fileNames } = this.getProjectInfo(fileName, true);
|
||||||
// No need to analyze lib.d.ts
|
// No need to analyze lib.d.ts
|
||||||
fileNamesInProject = fileNamesInProject.filter((value, index, array) => value.indexOf("lib.d.ts") < 0);
|
let fileNamesInProject = fileNames.filter((value, index, array) => value.indexOf("lib.d.ts") < 0);
|
||||||
|
|
||||||
// Sort the file name list to make the recently touched files come first
|
// Sort the file name list to make the recently touched files come first
|
||||||
let highPriorityFiles: string[] = [];
|
const highPriorityFiles: string[] = [];
|
||||||
let mediumPriorityFiles: string[] = [];
|
const mediumPriorityFiles: string[] = [];
|
||||||
let lowPriorityFiles: string[] = [];
|
const lowPriorityFiles: string[] = [];
|
||||||
let veryLowPriorityFiles: string[] = [];
|
const veryLowPriorityFiles: string[] = [];
|
||||||
let normalizedFileName = ts.normalizePath(fileName);
|
const normalizedFileName = ts.normalizePath(fileName);
|
||||||
let project = this.projectService.getProjectForFile(normalizedFileName);
|
const project = this.projectService.getProjectForFile(normalizedFileName);
|
||||||
for (let fileNameInProject of fileNamesInProject) {
|
for (const fileNameInProject of fileNamesInProject) {
|
||||||
if (this.getCanonicalFileName(fileNameInProject) == this.getCanonicalFileName(fileName))
|
if (this.getCanonicalFileName(fileNameInProject) == this.getCanonicalFileName(fileName))
|
||||||
highPriorityFiles.push(fileNameInProject);
|
highPriorityFiles.push(fileNameInProject);
|
||||||
else {
|
else {
|
||||||
let info = this.projectService.getScriptInfo(fileNameInProject);
|
const info = this.projectService.getScriptInfo(fileNameInProject);
|
||||||
if (!info.isOpen) {
|
if (!info.isOpen) {
|
||||||
if (fileNameInProject.indexOf(".d.ts") > 0)
|
if (fileNameInProject.indexOf(".d.ts") > 0)
|
||||||
veryLowPriorityFiles.push(fileNameInProject);
|
veryLowPriorityFiles.push(fileNameInProject);
|
||||||
|
@ -927,8 +927,8 @@ namespace ts.server {
|
||||||
fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles);
|
fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles);
|
||||||
|
|
||||||
if (fileNamesInProject.length > 0) {
|
if (fileNamesInProject.length > 0) {
|
||||||
let checkList = fileNamesInProject.map<PendingErrorCheck>((fileName: string) => {
|
const checkList = fileNamesInProject.map<PendingErrorCheck>((fileName: string) => {
|
||||||
let normalizedFileName = ts.normalizePath(fileName);
|
const normalizedFileName = ts.normalizePath(fileName);
|
||||||
return { fileName: normalizedFileName, project };
|
return { fileName: normalizedFileName, project };
|
||||||
});
|
});
|
||||||
// Project level error analysis runs on background files too, therefore
|
// Project level error analysis runs on background files too, therefore
|
||||||
|
@ -938,7 +938,7 @@ namespace ts.server {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCanonicalFileName(fileName: string) {
|
getCanonicalFileName(fileName: string) {
|
||||||
let name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
const name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||||
return ts.normalizePath(name);
|
return ts.normalizePath(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,7 +1001,7 @@ namespace ts.server {
|
||||||
return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false};
|
return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false};
|
||||||
},
|
},
|
||||||
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
|
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
|
||||||
let { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
|
const { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
|
||||||
return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false};
|
return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false};
|
||||||
},
|
},
|
||||||
[CommandNames.Change]: (request: protocol.Request) => {
|
[CommandNames.Change]: (request: protocol.Request) => {
|
||||||
|
|
|
@ -174,7 +174,7 @@ namespace ts {
|
||||||
let jsDocCompletionEntries: CompletionEntry[];
|
let jsDocCompletionEntries: CompletionEntry[];
|
||||||
|
|
||||||
function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject {
|
function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject {
|
||||||
let node = <NodeObject> new (getNodeConstructor(kind))(pos, end);
|
let node = new NodeObject(kind, pos, end);
|
||||||
node.flags = flags;
|
node.flags = flags;
|
||||||
node.parent = parent;
|
node.parent = parent;
|
||||||
return node;
|
return node;
|
||||||
|
@ -188,6 +188,14 @@ namespace ts {
|
||||||
public parent: Node;
|
public parent: Node;
|
||||||
private _children: Node[];
|
private _children: Node[];
|
||||||
|
|
||||||
|
constructor(kind: SyntaxKind, pos: number, end: number) {
|
||||||
|
this.kind = kind;
|
||||||
|
this.pos = pos;
|
||||||
|
this.end = end;
|
||||||
|
this.flags = NodeFlags.None;
|
||||||
|
this.parent = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public getSourceFile(): SourceFile {
|
public getSourceFile(): SourceFile {
|
||||||
return getSourceFileOfNode(this);
|
return getSourceFileOfNode(this);
|
||||||
}
|
}
|
||||||
|
@ -805,6 +813,10 @@ namespace ts {
|
||||||
public imports: LiteralExpression[];
|
public imports: LiteralExpression[];
|
||||||
private namedDeclarations: Map<Declaration[]>;
|
private namedDeclarations: Map<Declaration[]>;
|
||||||
|
|
||||||
|
constructor(kind: SyntaxKind, pos: number, end: number) {
|
||||||
|
super(kind, pos, end)
|
||||||
|
}
|
||||||
|
|
||||||
public update(newText: string, textChangeRange: TextChangeRange): SourceFile {
|
public update(newText: string, textChangeRange: TextChangeRange): SourceFile {
|
||||||
return updateSourceFile(this, newText, textChangeRange);
|
return updateSourceFile(this, newText, textChangeRange);
|
||||||
}
|
}
|
||||||
|
@ -7970,18 +7982,8 @@ namespace ts {
|
||||||
|
|
||||||
function initializeServices() {
|
function initializeServices() {
|
||||||
objectAllocator = {
|
objectAllocator = {
|
||||||
getNodeConstructor: kind => {
|
getNodeConstructor: () => NodeObject,
|
||||||
function Node(pos: number, end: number) {
|
getSourceFileConstructor: () => SourceFileObject,
|
||||||
this.pos = pos;
|
|
||||||
this.end = end;
|
|
||||||
this.flags = NodeFlags.None;
|
|
||||||
this.parent = undefined;
|
|
||||||
}
|
|
||||||
let proto = kind === SyntaxKind.SourceFile ? new SourceFileObject() : new NodeObject();
|
|
||||||
proto.kind = kind;
|
|
||||||
Node.prototype = proto;
|
|
||||||
return <any>Node;
|
|
||||||
},
|
|
||||||
getSymbolConstructor: () => SymbolObject,
|
getSymbolConstructor: () => SymbolObject,
|
||||||
getTypeConstructor: () => TypeObject,
|
getTypeConstructor: () => TypeObject,
|
||||||
getSignatureConstructor: () => SignatureObject,
|
getSignatureConstructor: () => SignatureObject,
|
||||||
|
|
|
@ -1032,7 +1032,7 @@ namespace ts {
|
||||||
public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim {
|
public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim {
|
||||||
try {
|
try {
|
||||||
if (this.documentRegistry === undefined) {
|
if (this.documentRegistry === undefined) {
|
||||||
this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory());
|
||||||
}
|
}
|
||||||
var hostAdapter = new LanguageServiceShimHostAdapter(host);
|
var hostAdapter = new LanguageServiceShimHostAdapter(host);
|
||||||
var languageService = createLanguageService(hostAdapter, this.documentRegistry);
|
var languageService = createLanguageService(hostAdapter, this.documentRegistry);
|
||||||
|
@ -1068,7 +1068,7 @@ namespace ts {
|
||||||
public close(): void {
|
public close(): void {
|
||||||
// Forget all the registered shims
|
// Forget all the registered shims
|
||||||
this._shims = [];
|
this._shims = [];
|
||||||
this.documentRegistry = createDocumentRegistry();
|
this.documentRegistry = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerShim(shim: Shim): void {
|
public registerShim(shim: Shim): void {
|
||||||
|
|
|
@ -4,6 +4,7 @@ tests/cases/compiler/fuzzy.ts(21,20): error TS2322: Type '{ anything: number; on
|
||||||
Types of property 'oneI' are incompatible.
|
Types of property 'oneI' are incompatible.
|
||||||
Type 'this' is not assignable to type 'I'.
|
Type 'this' is not assignable to type 'I'.
|
||||||
Type 'C' is not assignable to type 'I'.
|
Type 'C' is not assignable to type 'I'.
|
||||||
|
Property 'alsoWorks' is missing in type 'C'.
|
||||||
tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Neither type '{ oneI: this; }' nor type 'R' is assignable to the other.
|
tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Neither type '{ oneI: this; }' nor type 'R' is assignable to the other.
|
||||||
Property 'anything' is missing in type '{ oneI: this; }'.
|
Property 'anything' is missing in type '{ oneI: this; }'.
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Neither type '{ oneI: this;
|
||||||
!!! error TS2322: Types of property 'oneI' are incompatible.
|
!!! error TS2322: Types of property 'oneI' are incompatible.
|
||||||
!!! error TS2322: Type 'this' is not assignable to type 'I'.
|
!!! error TS2322: Type 'this' is not assignable to type 'I'.
|
||||||
!!! error TS2322: Type 'C' is not assignable to type 'I'.
|
!!! error TS2322: Type 'C' is not assignable to type 'I'.
|
||||||
|
!!! error TS2322: Property 'alsoWorks' is missing in type 'C'.
|
||||||
}
|
}
|
||||||
|
|
||||||
worksToo():R {
|
worksToo():R {
|
||||||
|
|
|
@ -63,7 +63,7 @@ if (elementA instanceof FileMatch && elementB instanceof FileMatch) {
|
||||||
} else if (elementA instanceof Match && elementB instanceof Match) {
|
} else if (elementA instanceof Match && elementB instanceof Match) {
|
||||||
>elementA instanceof Match && elementB instanceof Match : boolean
|
>elementA instanceof Match && elementB instanceof Match : boolean
|
||||||
>elementA instanceof Match : boolean
|
>elementA instanceof Match : boolean
|
||||||
>elementA : FileMatch | Match
|
>elementA : Match | FileMatch
|
||||||
>Match : typeof Match
|
>Match : typeof Match
|
||||||
>elementB instanceof Match : boolean
|
>elementB instanceof Match : boolean
|
||||||
>elementB : FileMatch | Match
|
>elementB : FileMatch | Match
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
//// [noReachabilityErrorsOnEmptyStatement.ts]
|
||||||
|
function foo() {
|
||||||
|
return 1;;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// [noReachabilityErrorsOnEmptyStatement.js]
|
||||||
|
function foo() {
|
||||||
|
return 1;
|
||||||
|
;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
=== tests/cases/compiler/noReachabilityErrorsOnEmptyStatement.ts ===
|
||||||
|
function foo() {
|
||||||
|
>foo : Symbol(foo, Decl(noReachabilityErrorsOnEmptyStatement.ts, 0, 0))
|
||||||
|
|
||||||
|
return 1;;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
=== tests/cases/compiler/noReachabilityErrorsOnEmptyStatement.ts ===
|
||||||
|
function foo() {
|
||||||
|
>foo : () => number
|
||||||
|
|
||||||
|
return 1;;
|
||||||
|
>1 : number
|
||||||
|
}
|
|
@ -1,19 +1,7 @@
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(3,12): error TS4050: Return type of public static method from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(3,12): error TS4050: Return type of public static method from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(7,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(9,5): error TS4053: Return type of public method from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(9,5): error TS4053: Return type of public method from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(10,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(13,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(15,12): error TS4050: Return type of public static method from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(15,12): error TS4050: Return type of public static method from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(19,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(21,5): error TS4053: Return type of public method from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(21,5): error TS4053: Return type of public method from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(22,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(25,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(34,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(37,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(40,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(46,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(49,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(52,49): error TS7027: Unreachable code detected.
|
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(56,17): error TS4058: Return type of exported function has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(56,17): error TS4058: Return type of exported function has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(62,17): error TS4058: Return type of exported function has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(62,17): error TS4058: Return type of exported function has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(70,12): error TS4050: Return type of public static method from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(70,12): error TS4050: Return type of public static method from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
||||||
|
@ -24,7 +12,7 @@ tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(83,17): error
|
||||||
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(86,17): error TS4058: Return type of exported function has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named.
|
tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(86,17): error TS4058: Return type of exported function has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named.
|
||||||
|
|
||||||
|
|
||||||
==== tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts (24 errors) ====
|
==== tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts (12 errors) ====
|
||||||
import exporter = require("./privacyFunctionReturnTypeDeclFile_exporter");
|
import exporter = require("./privacyFunctionReturnTypeDeclFile_exporter");
|
||||||
export class publicClassWithWithPrivateParmeterTypes {
|
export class publicClassWithWithPrivateParmeterTypes {
|
||||||
static myPublicStaticMethod() { // Error
|
static myPublicStaticMethod() { // Error
|
||||||
|
@ -34,20 +22,14 @@ tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(86,17): error
|
||||||
}
|
}
|
||||||
private static myPrivateStaticMethod() {
|
private static myPrivateStaticMethod() {
|
||||||
return exporter.createExportedWidget1();;
|
return exporter.createExportedWidget1();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
myPublicMethod() { // Error
|
myPublicMethod() { // Error
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
!!! error TS4053: Return type of public method from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
!!! error TS4053: Return type of public method from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyFunctionReturnTypeDeclFile_Widgets" but cannot be named.
|
||||||
return exporter.createExportedWidget1();;
|
return exporter.createExportedWidget1();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
private myPrivateMethod() {
|
private myPrivateMethod() {
|
||||||
return exporter.createExportedWidget1();;
|
return exporter.createExportedWidget1();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
static myPublicStaticMethod1() { // Error
|
static myPublicStaticMethod1() { // Error
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -56,20 +38,14 @@ tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(86,17): error
|
||||||
}
|
}
|
||||||
private static myPrivateStaticMethod1() {
|
private static myPrivateStaticMethod1() {
|
||||||
return exporter.createExportedWidget3();;
|
return exporter.createExportedWidget3();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
myPublicMethod1() { // Error
|
myPublicMethod1() { // Error
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
!!! error TS4053: Return type of public method from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
!!! error TS4053: Return type of public method from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named.
|
||||||
return exporter.createExportedWidget3();;
|
return exporter.createExportedWidget3();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
private myPrivateMethod1() {
|
private myPrivateMethod1() {
|
||||||
return exporter.createExportedWidget3();;
|
return exporter.createExportedWidget3();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,36 +55,24 @@ tests/cases/compiler/privacyFunctionReturnTypeDeclFile_consumer.ts(86,17): error
|
||||||
}
|
}
|
||||||
private static myPrivateStaticMethod() {
|
private static myPrivateStaticMethod() {
|
||||||
return exporter.createExportedWidget1();;
|
return exporter.createExportedWidget1();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
myPublicMethod() {
|
myPublicMethod() {
|
||||||
return exporter.createExportedWidget1();;
|
return exporter.createExportedWidget1();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
private myPrivateMethod() {
|
private myPrivateMethod() {
|
||||||
return exporter.createExportedWidget1();;
|
return exporter.createExportedWidget1();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
static myPublicStaticMethod1() {
|
static myPublicStaticMethod1() {
|
||||||
return exporter.createExportedWidget3();
|
return exporter.createExportedWidget3();
|
||||||
}
|
}
|
||||||
private static myPrivateStaticMethod1() {
|
private static myPrivateStaticMethod1() {
|
||||||
return exporter.createExportedWidget3();;
|
return exporter.createExportedWidget3();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
myPublicMethod1() {
|
myPublicMethod1() {
|
||||||
return exporter.createExportedWidget3();;
|
return exporter.createExportedWidget3();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
private myPrivateMethod1() {
|
private myPrivateMethod1() {
|
||||||
return exporter.createExportedWidget3();;
|
return exporter.createExportedWidget3();;
|
||||||
~
|
|
||||||
!!! error TS7027: Unreachable code detected.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
50
tests/baselines/reference/thisTypeAndConstraints.js
Normal file
50
tests/baselines/reference/thisTypeAndConstraints.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
//// [thisTypeAndConstraints.ts]
|
||||||
|
class A {
|
||||||
|
self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f<T extends A>(x: T) {
|
||||||
|
function g<U extends T>(x: U) {
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
|
||||||
|
class B<T extends A> {
|
||||||
|
foo(x: T) {
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
bar<U extends T>(x: U) {
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [thisTypeAndConstraints.js]
|
||||||
|
var A = (function () {
|
||||||
|
function A() {
|
||||||
|
}
|
||||||
|
A.prototype.self = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
return A;
|
||||||
|
})();
|
||||||
|
function f(x) {
|
||||||
|
function g(x) {
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
var B = (function () {
|
||||||
|
function B() {
|
||||||
|
}
|
||||||
|
B.prototype.foo = function (x) {
|
||||||
|
x = x.self();
|
||||||
|
};
|
||||||
|
B.prototype.bar = function (x) {
|
||||||
|
x = x.self();
|
||||||
|
};
|
||||||
|
return B;
|
||||||
|
})();
|
70
tests/baselines/reference/thisTypeAndConstraints.symbols
Normal file
70
tests/baselines/reference/thisTypeAndConstraints.symbols
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
=== tests/cases/conformance/types/thisType/thisTypeAndConstraints.ts ===
|
||||||
|
class A {
|
||||||
|
>A : Symbol(A, Decl(thisTypeAndConstraints.ts, 0, 0))
|
||||||
|
|
||||||
|
self() {
|
||||||
|
>self : Symbol(self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
|
||||||
|
return this;
|
||||||
|
>this : Symbol(A, Decl(thisTypeAndConstraints.ts, 0, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f<T extends A>(x: T) {
|
||||||
|
>f : Symbol(f, Decl(thisTypeAndConstraints.ts, 4, 1))
|
||||||
|
>T : Symbol(T, Decl(thisTypeAndConstraints.ts, 6, 11))
|
||||||
|
>A : Symbol(A, Decl(thisTypeAndConstraints.ts, 0, 0))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 6, 24))
|
||||||
|
>T : Symbol(T, Decl(thisTypeAndConstraints.ts, 6, 11))
|
||||||
|
|
||||||
|
function g<U extends T>(x: U) {
|
||||||
|
>g : Symbol(g, Decl(thisTypeAndConstraints.ts, 6, 31))
|
||||||
|
>U : Symbol(U, Decl(thisTypeAndConstraints.ts, 7, 15))
|
||||||
|
>T : Symbol(T, Decl(thisTypeAndConstraints.ts, 6, 11))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 7, 28))
|
||||||
|
>U : Symbol(U, Decl(thisTypeAndConstraints.ts, 7, 15))
|
||||||
|
|
||||||
|
x = x.self();
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 7, 28))
|
||||||
|
>x.self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 7, 28))
|
||||||
|
>self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
}
|
||||||
|
x = x.self();
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 6, 24))
|
||||||
|
>x.self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 6, 24))
|
||||||
|
>self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
}
|
||||||
|
|
||||||
|
class B<T extends A> {
|
||||||
|
>B : Symbol(B, Decl(thisTypeAndConstraints.ts, 11, 1))
|
||||||
|
>T : Symbol(T, Decl(thisTypeAndConstraints.ts, 13, 8))
|
||||||
|
>A : Symbol(A, Decl(thisTypeAndConstraints.ts, 0, 0))
|
||||||
|
|
||||||
|
foo(x: T) {
|
||||||
|
>foo : Symbol(foo, Decl(thisTypeAndConstraints.ts, 13, 22))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 14, 8))
|
||||||
|
>T : Symbol(T, Decl(thisTypeAndConstraints.ts, 13, 8))
|
||||||
|
|
||||||
|
x = x.self();
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 14, 8))
|
||||||
|
>x.self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 14, 8))
|
||||||
|
>self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
}
|
||||||
|
bar<U extends T>(x: U) {
|
||||||
|
>bar : Symbol(bar, Decl(thisTypeAndConstraints.ts, 16, 5))
|
||||||
|
>U : Symbol(U, Decl(thisTypeAndConstraints.ts, 17, 8))
|
||||||
|
>T : Symbol(T, Decl(thisTypeAndConstraints.ts, 13, 8))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 17, 21))
|
||||||
|
>U : Symbol(U, Decl(thisTypeAndConstraints.ts, 17, 8))
|
||||||
|
|
||||||
|
x = x.self();
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 17, 21))
|
||||||
|
>x.self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
>x : Symbol(x, Decl(thisTypeAndConstraints.ts, 17, 21))
|
||||||
|
>self : Symbol(A.self, Decl(thisTypeAndConstraints.ts, 0, 9))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
78
tests/baselines/reference/thisTypeAndConstraints.types
Normal file
78
tests/baselines/reference/thisTypeAndConstraints.types
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
=== tests/cases/conformance/types/thisType/thisTypeAndConstraints.ts ===
|
||||||
|
class A {
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
self() {
|
||||||
|
>self : () => this
|
||||||
|
|
||||||
|
return this;
|
||||||
|
>this : this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f<T extends A>(x: T) {
|
||||||
|
>f : <T extends A>(x: T) => void
|
||||||
|
>T : T
|
||||||
|
>A : A
|
||||||
|
>x : T
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
function g<U extends T>(x: U) {
|
||||||
|
>g : <U extends T>(x: U) => void
|
||||||
|
>U : U
|
||||||
|
>T : T
|
||||||
|
>x : U
|
||||||
|
>U : U
|
||||||
|
|
||||||
|
x = x.self();
|
||||||
|
>x = x.self() : U
|
||||||
|
>x : U
|
||||||
|
>x.self() : U
|
||||||
|
>x.self : () => U
|
||||||
|
>x : U
|
||||||
|
>self : () => U
|
||||||
|
}
|
||||||
|
x = x.self();
|
||||||
|
>x = x.self() : T
|
||||||
|
>x : T
|
||||||
|
>x.self() : T
|
||||||
|
>x.self : () => T
|
||||||
|
>x : T
|
||||||
|
>self : () => T
|
||||||
|
}
|
||||||
|
|
||||||
|
class B<T extends A> {
|
||||||
|
>B : B<T>
|
||||||
|
>T : T
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
foo(x: T) {
|
||||||
|
>foo : (x: T) => void
|
||||||
|
>x : T
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
x = x.self();
|
||||||
|
>x = x.self() : T
|
||||||
|
>x : T
|
||||||
|
>x.self() : T
|
||||||
|
>x.self : () => T
|
||||||
|
>x : T
|
||||||
|
>self : () => T
|
||||||
|
}
|
||||||
|
bar<U extends T>(x: U) {
|
||||||
|
>bar : <U extends T>(x: U) => void
|
||||||
|
>U : U
|
||||||
|
>T : T
|
||||||
|
>x : U
|
||||||
|
>U : U
|
||||||
|
|
||||||
|
x = x.self();
|
||||||
|
>x = x.self() : U
|
||||||
|
>x : U
|
||||||
|
>x.self() : U
|
||||||
|
>x.self : () => U
|
||||||
|
>x : U
|
||||||
|
>self : () => U
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
tests/cases/conformance/types/thisType/thisTypeInClasses.ts(4,20): error TS2526: A 'this' type is available only in a non-static member of a class or interface.
|
|
||||||
|
|
||||||
|
|
||||||
==== tests/cases/conformance/types/thisType/thisTypeInClasses.ts (1 errors) ====
|
|
||||||
class C1 {
|
|
||||||
x: this;
|
|
||||||
f(x: this): this { return undefined; }
|
|
||||||
constructor(x: this) { }
|
|
||||||
~~~~
|
|
||||||
!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface.
|
|
||||||
}
|
|
||||||
|
|
||||||
class C2 {
|
|
||||||
[x: string]: this;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Foo<T> {
|
|
||||||
x: T;
|
|
||||||
y: this;
|
|
||||||
}
|
|
||||||
|
|
||||||
class C3 {
|
|
||||||
a: this[];
|
|
||||||
b: [this, this];
|
|
||||||
c: this | Date;
|
|
||||||
d: this & Date;
|
|
||||||
e: (((this)));
|
|
||||||
f: (x: this) => this;
|
|
||||||
g: new (x: this) => this;
|
|
||||||
h: Foo<this>;
|
|
||||||
i: Foo<this | (() => this)>;
|
|
||||||
j: (x: any) => x is this;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class C4 {
|
|
||||||
x: this;
|
|
||||||
f(x: this): this;
|
|
||||||
}
|
|
||||||
|
|
||||||
class C5 {
|
|
||||||
foo() {
|
|
||||||
let f1 = (x: this): this => this;
|
|
||||||
let f2 = (x: this) => this;
|
|
||||||
let f3 = (x: this) => (y: this) => this;
|
|
||||||
let f4 = (x: this) => {
|
|
||||||
let g = (y: this) => {
|
|
||||||
return () => this;
|
|
||||||
}
|
|
||||||
return g(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bar() {
|
|
||||||
let x1 = <this>undefined;
|
|
||||||
let x2 = undefined as this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
class C1 {
|
class C1 {
|
||||||
x: this;
|
x: this;
|
||||||
f(x: this): this { return undefined; }
|
f(x: this): this { return undefined; }
|
||||||
constructor(x: this) { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class C2 {
|
class C2 {
|
||||||
|
@ -53,7 +52,7 @@ class C5 {
|
||||||
|
|
||||||
//// [thisTypeInClasses.js]
|
//// [thisTypeInClasses.js]
|
||||||
var C1 = (function () {
|
var C1 = (function () {
|
||||||
function C1(x) {
|
function C1() {
|
||||||
}
|
}
|
||||||
C1.prototype.f = function (x) { return undefined; };
|
C1.prototype.f = function (x) { return undefined; };
|
||||||
return C1;
|
return C1;
|
||||||
|
|
|
@ -9,131 +9,128 @@ class C1 {
|
||||||
>f : Symbol(f, Decl(thisTypeInClasses.ts, 1, 12))
|
>f : Symbol(f, Decl(thisTypeInClasses.ts, 1, 12))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 2, 6))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 2, 6))
|
||||||
>undefined : Symbol(undefined)
|
>undefined : Symbol(undefined)
|
||||||
|
|
||||||
constructor(x: this) { }
|
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 3, 16))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class C2 {
|
class C2 {
|
||||||
>C2 : Symbol(C2, Decl(thisTypeInClasses.ts, 4, 1))
|
>C2 : Symbol(C2, Decl(thisTypeInClasses.ts, 3, 1))
|
||||||
|
|
||||||
[x: string]: this;
|
[x: string]: this;
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 7, 5))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 6, 5))
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Foo<T> {
|
interface Foo<T> {
|
||||||
>Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 8, 1))
|
>Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 7, 1))
|
||||||
>T : Symbol(T, Decl(thisTypeInClasses.ts, 10, 14))
|
>T : Symbol(T, Decl(thisTypeInClasses.ts, 9, 14))
|
||||||
|
|
||||||
x: T;
|
x: T;
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 10, 18))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 9, 18))
|
||||||
>T : Symbol(T, Decl(thisTypeInClasses.ts, 10, 14))
|
>T : Symbol(T, Decl(thisTypeInClasses.ts, 9, 14))
|
||||||
|
|
||||||
y: this;
|
y: this;
|
||||||
>y : Symbol(y, Decl(thisTypeInClasses.ts, 11, 9))
|
>y : Symbol(y, Decl(thisTypeInClasses.ts, 10, 9))
|
||||||
}
|
}
|
||||||
|
|
||||||
class C3 {
|
class C3 {
|
||||||
>C3 : Symbol(C3, Decl(thisTypeInClasses.ts, 13, 1))
|
>C3 : Symbol(C3, Decl(thisTypeInClasses.ts, 12, 1))
|
||||||
|
|
||||||
a: this[];
|
a: this[];
|
||||||
>a : Symbol(a, Decl(thisTypeInClasses.ts, 15, 10))
|
>a : Symbol(a, Decl(thisTypeInClasses.ts, 14, 10))
|
||||||
|
|
||||||
b: [this, this];
|
b: [this, this];
|
||||||
>b : Symbol(b, Decl(thisTypeInClasses.ts, 16, 14))
|
>b : Symbol(b, Decl(thisTypeInClasses.ts, 15, 14))
|
||||||
|
|
||||||
c: this | Date;
|
c: this | Date;
|
||||||
>c : Symbol(c, Decl(thisTypeInClasses.ts, 17, 20))
|
>c : Symbol(c, Decl(thisTypeInClasses.ts, 16, 20))
|
||||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
d: this & Date;
|
d: this & Date;
|
||||||
>d : Symbol(d, Decl(thisTypeInClasses.ts, 18, 19))
|
>d : Symbol(d, Decl(thisTypeInClasses.ts, 17, 19))
|
||||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
e: (((this)));
|
e: (((this)));
|
||||||
>e : Symbol(e, Decl(thisTypeInClasses.ts, 19, 19))
|
>e : Symbol(e, Decl(thisTypeInClasses.ts, 18, 19))
|
||||||
|
|
||||||
f: (x: this) => this;
|
f: (x: this) => this;
|
||||||
>f : Symbol(f, Decl(thisTypeInClasses.ts, 20, 18))
|
>f : Symbol(f, Decl(thisTypeInClasses.ts, 19, 18))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 21, 8))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 20, 8))
|
||||||
|
|
||||||
g: new (x: this) => this;
|
g: new (x: this) => this;
|
||||||
>g : Symbol(g, Decl(thisTypeInClasses.ts, 21, 25))
|
>g : Symbol(g, Decl(thisTypeInClasses.ts, 20, 25))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 22, 12))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 21, 12))
|
||||||
|
|
||||||
h: Foo<this>;
|
h: Foo<this>;
|
||||||
>h : Symbol(h, Decl(thisTypeInClasses.ts, 22, 29))
|
>h : Symbol(h, Decl(thisTypeInClasses.ts, 21, 29))
|
||||||
>Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 8, 1))
|
>Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 7, 1))
|
||||||
|
|
||||||
i: Foo<this | (() => this)>;
|
i: Foo<this | (() => this)>;
|
||||||
>i : Symbol(i, Decl(thisTypeInClasses.ts, 23, 17))
|
>i : Symbol(i, Decl(thisTypeInClasses.ts, 22, 17))
|
||||||
>Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 8, 1))
|
>Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 7, 1))
|
||||||
|
|
||||||
j: (x: any) => x is this;
|
j: (x: any) => x is this;
|
||||||
>j : Symbol(j, Decl(thisTypeInClasses.ts, 24, 32))
|
>j : Symbol(j, Decl(thisTypeInClasses.ts, 23, 32))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 25, 8))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 24, 8))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 25, 8))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 24, 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
declare class C4 {
|
declare class C4 {
|
||||||
>C4 : Symbol(C4, Decl(thisTypeInClasses.ts, 26, 1))
|
>C4 : Symbol(C4, Decl(thisTypeInClasses.ts, 25, 1))
|
||||||
|
|
||||||
x: this;
|
x: this;
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 28, 18))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 27, 18))
|
||||||
|
|
||||||
f(x: this): this;
|
f(x: this): this;
|
||||||
>f : Symbol(f, Decl(thisTypeInClasses.ts, 29, 12))
|
>f : Symbol(f, Decl(thisTypeInClasses.ts, 28, 12))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 30, 6))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 29, 6))
|
||||||
}
|
}
|
||||||
|
|
||||||
class C5 {
|
class C5 {
|
||||||
>C5 : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1))
|
>C5 : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
|
||||||
|
|
||||||
foo() {
|
foo() {
|
||||||
>foo : Symbol(foo, Decl(thisTypeInClasses.ts, 33, 10))
|
>foo : Symbol(foo, Decl(thisTypeInClasses.ts, 32, 10))
|
||||||
|
|
||||||
let f1 = (x: this): this => this;
|
let f1 = (x: this): this => this;
|
||||||
>f1 : Symbol(f1, Decl(thisTypeInClasses.ts, 35, 11))
|
>f1 : Symbol(f1, Decl(thisTypeInClasses.ts, 34, 11))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 35, 18))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 34, 18))
|
||||||
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1))
|
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
|
||||||
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1))
|
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
|
||||||
|
|
||||||
let f2 = (x: this) => this;
|
let f2 = (x: this) => this;
|
||||||
>f2 : Symbol(f2, Decl(thisTypeInClasses.ts, 36, 11))
|
>f2 : Symbol(f2, Decl(thisTypeInClasses.ts, 35, 11))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 36, 18))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 35, 18))
|
||||||
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1))
|
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
|
||||||
|
|
||||||
let f3 = (x: this) => (y: this) => this;
|
let f3 = (x: this) => (y: this) => this;
|
||||||
>f3 : Symbol(f3, Decl(thisTypeInClasses.ts, 37, 11))
|
>f3 : Symbol(f3, Decl(thisTypeInClasses.ts, 36, 11))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 37, 18))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 36, 18))
|
||||||
>y : Symbol(y, Decl(thisTypeInClasses.ts, 37, 31))
|
>y : Symbol(y, Decl(thisTypeInClasses.ts, 36, 31))
|
||||||
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1))
|
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
|
||||||
|
|
||||||
let f4 = (x: this) => {
|
let f4 = (x: this) => {
|
||||||
>f4 : Symbol(f4, Decl(thisTypeInClasses.ts, 38, 11))
|
>f4 : Symbol(f4, Decl(thisTypeInClasses.ts, 37, 11))
|
||||||
>x : Symbol(x, Decl(thisTypeInClasses.ts, 38, 18))
|
>x : Symbol(x, Decl(thisTypeInClasses.ts, 37, 18))
|
||||||
|
|
||||||
let g = (y: this) => {
|
let g = (y: this) => {
|
||||||
>g : Symbol(g, Decl(thisTypeInClasses.ts, 39, 15))
|
>g : Symbol(g, Decl(thisTypeInClasses.ts, 38, 15))
|
||||||
>y : Symbol(y, Decl(thisTypeInClasses.ts, 39, 21))
|
>y : Symbol(y, Decl(thisTypeInClasses.ts, 38, 21))
|
||||||
|
|
||||||
return () => this;
|
return () => this;
|
||||||
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1))
|
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
|
||||||
}
|
}
|
||||||
return g(this);
|
return g(this);
|
||||||
>g : Symbol(g, Decl(thisTypeInClasses.ts, 39, 15))
|
>g : Symbol(g, Decl(thisTypeInClasses.ts, 38, 15))
|
||||||
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1))
|
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bar() {
|
bar() {
|
||||||
>bar : Symbol(bar, Decl(thisTypeInClasses.ts, 44, 5))
|
>bar : Symbol(bar, Decl(thisTypeInClasses.ts, 43, 5))
|
||||||
|
|
||||||
let x1 = <this>undefined;
|
let x1 = <this>undefined;
|
||||||
>x1 : Symbol(x1, Decl(thisTypeInClasses.ts, 46, 11))
|
>x1 : Symbol(x1, Decl(thisTypeInClasses.ts, 45, 11))
|
||||||
>undefined : Symbol(undefined)
|
>undefined : Symbol(undefined)
|
||||||
|
|
||||||
let x2 = undefined as this;
|
let x2 = undefined as this;
|
||||||
>x2 : Symbol(x2, Decl(thisTypeInClasses.ts, 47, 11))
|
>x2 : Symbol(x2, Decl(thisTypeInClasses.ts, 46, 11))
|
||||||
>undefined : Symbol(undefined)
|
>undefined : Symbol(undefined)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,6 @@ class C1 {
|
||||||
>f : (x: this) => this
|
>f : (x: this) => this
|
||||||
>x : this
|
>x : this
|
||||||
>undefined : undefined
|
>undefined : undefined
|
||||||
|
|
||||||
constructor(x: this) { }
|
|
||||||
>x : this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class C2 {
|
class C2 {
|
||||||
|
|
|
@ -14,21 +14,58 @@ class C2 {
|
||||||
class D1 extends C1 {
|
class D1 extends C1 {
|
||||||
p3: number;
|
p3: number;
|
||||||
}
|
}
|
||||||
|
class C3 {
|
||||||
|
p4: number;
|
||||||
|
}
|
||||||
var str: string;
|
var str: string;
|
||||||
var num: number;
|
var num: number;
|
||||||
var strOrNum: string | number;
|
var strOrNum: string | number;
|
||||||
|
|
||||||
var c1Orc2: C1 | C2;
|
var ctor1: C1 | C2;
|
||||||
str = c1Orc2 instanceof C1 && c1Orc2.p1; // C1
|
str = ctor1 instanceof C1 && ctor1.p1; // C1
|
||||||
num = c1Orc2 instanceof C2 && c1Orc2.p2; // C2
|
num = ctor1 instanceof C2 && ctor1.p2; // C2
|
||||||
str = c1Orc2 instanceof D1 && c1Orc2.p1; // D1
|
str = ctor1 instanceof D1 && ctor1.p1; // D1
|
||||||
num = c1Orc2 instanceof D1 && c1Orc2.p3; // D1
|
num = ctor1 instanceof D1 && ctor1.p3; // D1
|
||||||
|
|
||||||
var c2Ord1: C2 | D1;
|
var ctor2: C2 | D1;
|
||||||
num = c2Ord1 instanceof C2 && c2Ord1.p2; // C2
|
num = ctor2 instanceof C2 && ctor2.p2; // C2
|
||||||
num = c2Ord1 instanceof D1 && c2Ord1.p3; // D1
|
num = ctor2 instanceof D1 && ctor2.p3; // D1
|
||||||
str = c2Ord1 instanceof D1 && c2Ord1.p1; // D1
|
str = ctor2 instanceof D1 && ctor2.p1; // D1
|
||||||
var r2: D1 | C2 = c2Ord1 instanceof C1 && c2Ord1; // C2 | D1
|
var r2: D1 | C2 = ctor2 instanceof C1 && ctor2; // C2 | D1
|
||||||
|
|
||||||
|
var ctor3: C1 | C2;
|
||||||
|
if (ctor3 instanceof C1) {
|
||||||
|
ctor3.p1; // C1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor3.p2; // C2
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor4: C1 | C2 | C3;
|
||||||
|
if (ctor4 instanceof C1) {
|
||||||
|
ctor4.p1; // C1
|
||||||
|
}
|
||||||
|
else if (ctor4 instanceof C2) {
|
||||||
|
ctor4.p2; // C2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor4.p4; // C3
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor5: C1 | D1 | C2;
|
||||||
|
if (ctor5 instanceof C1) {
|
||||||
|
ctor5.p1; // C1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor5.p2; // C2
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor6: C1 | C2 | C3;
|
||||||
|
if (ctor6 instanceof C1 || ctor6 instanceof C2) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor6.p4; // C3
|
||||||
|
}
|
||||||
|
|
||||||
//// [typeGuardOfFormInstanceOf.js]
|
//// [typeGuardOfFormInstanceOf.js]
|
||||||
// A type guard of the form x instanceof C, where C is of a subtype of the global type 'Function'
|
// A type guard of the form x instanceof C, where C is of a subtype of the global type 'Function'
|
||||||
|
@ -58,16 +95,51 @@ var D1 = (function (_super) {
|
||||||
}
|
}
|
||||||
return D1;
|
return D1;
|
||||||
})(C1);
|
})(C1);
|
||||||
|
var C3 = (function () {
|
||||||
|
function C3() {
|
||||||
|
}
|
||||||
|
return C3;
|
||||||
|
})();
|
||||||
var str;
|
var str;
|
||||||
var num;
|
var num;
|
||||||
var strOrNum;
|
var strOrNum;
|
||||||
var c1Orc2;
|
var ctor1;
|
||||||
str = c1Orc2 instanceof C1 && c1Orc2.p1; // C1
|
str = ctor1 instanceof C1 && ctor1.p1; // C1
|
||||||
num = c1Orc2 instanceof C2 && c1Orc2.p2; // C2
|
num = ctor1 instanceof C2 && ctor1.p2; // C2
|
||||||
str = c1Orc2 instanceof D1 && c1Orc2.p1; // D1
|
str = ctor1 instanceof D1 && ctor1.p1; // D1
|
||||||
num = c1Orc2 instanceof D1 && c1Orc2.p3; // D1
|
num = ctor1 instanceof D1 && ctor1.p3; // D1
|
||||||
var c2Ord1;
|
var ctor2;
|
||||||
num = c2Ord1 instanceof C2 && c2Ord1.p2; // C2
|
num = ctor2 instanceof C2 && ctor2.p2; // C2
|
||||||
num = c2Ord1 instanceof D1 && c2Ord1.p3; // D1
|
num = ctor2 instanceof D1 && ctor2.p3; // D1
|
||||||
str = c2Ord1 instanceof D1 && c2Ord1.p1; // D1
|
str = ctor2 instanceof D1 && ctor2.p1; // D1
|
||||||
var r2 = c2Ord1 instanceof C1 && c2Ord1; // C2 | D1
|
var r2 = ctor2 instanceof C1 && ctor2; // C2 | D1
|
||||||
|
var ctor3;
|
||||||
|
if (ctor3 instanceof C1) {
|
||||||
|
ctor3.p1; // C1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor3.p2; // C2
|
||||||
|
}
|
||||||
|
var ctor4;
|
||||||
|
if (ctor4 instanceof C1) {
|
||||||
|
ctor4.p1; // C1
|
||||||
|
}
|
||||||
|
else if (ctor4 instanceof C2) {
|
||||||
|
ctor4.p2; // C2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor4.p4; // C3
|
||||||
|
}
|
||||||
|
var ctor5;
|
||||||
|
if (ctor5 instanceof C1) {
|
||||||
|
ctor5.p1; // C1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor5.p2; // C2
|
||||||
|
}
|
||||||
|
var ctor6;
|
||||||
|
if (ctor6 instanceof C1 || ctor6 instanceof C2) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor6.p4; // C3
|
||||||
|
}
|
||||||
|
|
|
@ -24,86 +24,184 @@ class D1 extends C1 {
|
||||||
p3: number;
|
p3: number;
|
||||||
>p3 : Symbol(p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
>p3 : Symbol(p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
||||||
}
|
}
|
||||||
|
class C3 {
|
||||||
|
>C3 : Symbol(C3, Decl(typeGuardOfFormInstanceOf.ts, 14, 1))
|
||||||
|
|
||||||
|
p4: number;
|
||||||
|
>p4 : Symbol(p4, Decl(typeGuardOfFormInstanceOf.ts, 15, 10))
|
||||||
|
}
|
||||||
var str: string;
|
var str: string;
|
||||||
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 15, 3))
|
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 18, 3))
|
||||||
|
|
||||||
var num: number;
|
var num: number;
|
||||||
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 16, 3))
|
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
||||||
|
|
||||||
var strOrNum: string | number;
|
var strOrNum: string | number;
|
||||||
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormInstanceOf.ts, 17, 3))
|
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormInstanceOf.ts, 20, 3))
|
||||||
|
|
||||||
var c1Orc2: C1 | C2;
|
var ctor1: C1 | C2;
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
|
|
||||||
str = c1Orc2 instanceof C1 && c1Orc2.p1; // C1
|
str = ctor1 instanceof C1 && ctor1.p1; // C1
|
||||||
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 15, 3))
|
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 18, 3))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
>ctor1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
|
||||||
num = c1Orc2 instanceof C2 && c1Orc2.p2; // C2
|
num = ctor1 instanceof C2 && ctor1.p2; // C2
|
||||||
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 16, 3))
|
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
>c1Orc2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
>ctor1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
|
||||||
str = c1Orc2 instanceof D1 && c1Orc2.p1; // D1
|
str = ctor1 instanceof D1 && ctor1.p1; // D1
|
||||||
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 15, 3))
|
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 18, 3))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
||||||
>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
>ctor1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
|
||||||
num = c1Orc2 instanceof D1 && c1Orc2.p3; // D1
|
num = ctor1 instanceof D1 && ctor1.p3; // D1
|
||||||
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 16, 3))
|
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
||||||
>c1Orc2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
>ctor1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
||||||
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
>ctor1 : Symbol(ctor1, Decl(typeGuardOfFormInstanceOf.ts, 22, 3))
|
||||||
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
||||||
|
|
||||||
var c2Ord1: C2 | D1;
|
var ctor2: C2 | D1;
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
||||||
|
|
||||||
num = c2Ord1 instanceof C2 && c2Ord1.p2; // C2
|
num = ctor2 instanceof C2 && ctor2.p2; // C2
|
||||||
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 16, 3))
|
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
>c2Ord1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
>ctor2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
|
||||||
num = c2Ord1 instanceof D1 && c2Ord1.p3; // D1
|
num = ctor2 instanceof D1 && ctor2.p3; // D1
|
||||||
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 16, 3))
|
>num : Symbol(num, Decl(typeGuardOfFormInstanceOf.ts, 19, 3))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
||||||
>c2Ord1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
>ctor2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormInstanceOf.ts, 12, 21))
|
||||||
|
|
||||||
str = c2Ord1 instanceof D1 && c2Ord1.p1; // D1
|
str = ctor2 instanceof D1 && ctor2.p1; // D1
|
||||||
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 15, 3))
|
>str : Symbol(str, Decl(typeGuardOfFormInstanceOf.ts, 18, 3))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
||||||
>c2Ord1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
>ctor2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
|
||||||
var r2: D1 | C2 = c2Ord1 instanceof C1 && c2Ord1; // C2 | D1
|
var r2: D1 | C2 = ctor2 instanceof C1 && ctor2; // C2 | D1
|
||||||
>r2 : Symbol(r2, Decl(typeGuardOfFormInstanceOf.ts, 29, 3))
|
>r2 : Symbol(r2, Decl(typeGuardOfFormInstanceOf.ts, 32, 3))
|
||||||
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
||||||
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormInstanceOf.ts, 25, 3))
|
>ctor2 : Symbol(ctor2, Decl(typeGuardOfFormInstanceOf.ts, 28, 3))
|
||||||
|
|
||||||
|
var ctor3: C1 | C2;
|
||||||
|
>ctor3 : Symbol(ctor3, Decl(typeGuardOfFormInstanceOf.ts, 34, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
|
|
||||||
|
if (ctor3 instanceof C1) {
|
||||||
|
>ctor3 : Symbol(ctor3, Decl(typeGuardOfFormInstanceOf.ts, 34, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
|
||||||
|
ctor3.p1; // C1
|
||||||
|
>ctor3.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
>ctor3 : Symbol(ctor3, Decl(typeGuardOfFormInstanceOf.ts, 34, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor3.p2; // C2
|
||||||
|
>ctor3.p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
>ctor3 : Symbol(ctor3, Decl(typeGuardOfFormInstanceOf.ts, 34, 3))
|
||||||
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor4: C1 | C2 | C3;
|
||||||
|
>ctor4 : Symbol(ctor4, Decl(typeGuardOfFormInstanceOf.ts, 42, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
|
>C3 : Symbol(C3, Decl(typeGuardOfFormInstanceOf.ts, 14, 1))
|
||||||
|
|
||||||
|
if (ctor4 instanceof C1) {
|
||||||
|
>ctor4 : Symbol(ctor4, Decl(typeGuardOfFormInstanceOf.ts, 42, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
|
||||||
|
ctor4.p1; // C1
|
||||||
|
>ctor4.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
>ctor4 : Symbol(ctor4, Decl(typeGuardOfFormInstanceOf.ts, 42, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
}
|
||||||
|
else if (ctor4 instanceof C2) {
|
||||||
|
>ctor4 : Symbol(ctor4, Decl(typeGuardOfFormInstanceOf.ts, 42, 3))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
|
|
||||||
|
ctor4.p2; // C2
|
||||||
|
>ctor4.p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
>ctor4 : Symbol(ctor4, Decl(typeGuardOfFormInstanceOf.ts, 42, 3))
|
||||||
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor4.p4; // C3
|
||||||
|
>ctor4.p4 : Symbol(C3.p4, Decl(typeGuardOfFormInstanceOf.ts, 15, 10))
|
||||||
|
>ctor4 : Symbol(ctor4, Decl(typeGuardOfFormInstanceOf.ts, 42, 3))
|
||||||
|
>p4 : Symbol(C3.p4, Decl(typeGuardOfFormInstanceOf.ts, 15, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor5: C1 | D1 | C2;
|
||||||
|
>ctor5 : Symbol(ctor5, Decl(typeGuardOfFormInstanceOf.ts, 53, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormInstanceOf.ts, 11, 1))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
|
|
||||||
|
if (ctor5 instanceof C1) {
|
||||||
|
>ctor5 : Symbol(ctor5, Decl(typeGuardOfFormInstanceOf.ts, 53, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
|
||||||
|
ctor5.p1; // C1
|
||||||
|
>ctor5.p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
>ctor5 : Symbol(ctor5, Decl(typeGuardOfFormInstanceOf.ts, 53, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormInstanceOf.ts, 6, 10))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor5.p2; // C2
|
||||||
|
>ctor5.p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
>ctor5 : Symbol(ctor5, Decl(typeGuardOfFormInstanceOf.ts, 53, 3))
|
||||||
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormInstanceOf.ts, 9, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor6: C1 | C2 | C3;
|
||||||
|
>ctor6 : Symbol(ctor6, Decl(typeGuardOfFormInstanceOf.ts, 61, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
|
>C3 : Symbol(C3, Decl(typeGuardOfFormInstanceOf.ts, 14, 1))
|
||||||
|
|
||||||
|
if (ctor6 instanceof C1 || ctor6 instanceof C2) {
|
||||||
|
>ctor6 : Symbol(ctor6, Decl(typeGuardOfFormInstanceOf.ts, 61, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormInstanceOf.ts, 0, 0))
|
||||||
|
>ctor6 : Symbol(ctor6, Decl(typeGuardOfFormInstanceOf.ts, 61, 3))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormInstanceOf.ts, 8, 1))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor6.p4; // C3
|
||||||
|
>ctor6.p4 : Symbol(C3.p4, Decl(typeGuardOfFormInstanceOf.ts, 15, 10))
|
||||||
|
>ctor6 : Symbol(ctor6, Decl(typeGuardOfFormInstanceOf.ts, 61, 3))
|
||||||
|
>p4 : Symbol(C3.p4, Decl(typeGuardOfFormInstanceOf.ts, 15, 10))
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,12 @@ class D1 extends C1 {
|
||||||
p3: number;
|
p3: number;
|
||||||
>p3 : number
|
>p3 : number
|
||||||
}
|
}
|
||||||
|
class C3 {
|
||||||
|
>C3 : C3
|
||||||
|
|
||||||
|
p4: number;
|
||||||
|
>p4 : number
|
||||||
|
}
|
||||||
var str: string;
|
var str: string;
|
||||||
>str : string
|
>str : string
|
||||||
|
|
||||||
|
@ -33,100 +39,199 @@ var num: number;
|
||||||
var strOrNum: string | number;
|
var strOrNum: string | number;
|
||||||
>strOrNum : string | number
|
>strOrNum : string | number
|
||||||
|
|
||||||
var c1Orc2: C1 | C2;
|
var ctor1: C1 | C2;
|
||||||
>c1Orc2 : C1 | C2
|
>ctor1 : C1 | C2
|
||||||
>C1 : C1
|
>C1 : C1
|
||||||
>C2 : C2
|
>C2 : C2
|
||||||
|
|
||||||
str = c1Orc2 instanceof C1 && c1Orc2.p1; // C1
|
str = ctor1 instanceof C1 && ctor1.p1; // C1
|
||||||
>str = c1Orc2 instanceof C1 && c1Orc2.p1 : string
|
>str = ctor1 instanceof C1 && ctor1.p1 : string
|
||||||
>str : string
|
>str : string
|
||||||
>c1Orc2 instanceof C1 && c1Orc2.p1 : string
|
>ctor1 instanceof C1 && ctor1.p1 : string
|
||||||
>c1Orc2 instanceof C1 : boolean
|
>ctor1 instanceof C1 : boolean
|
||||||
>c1Orc2 : C1 | C2
|
>ctor1 : C1 | C2
|
||||||
>C1 : typeof C1
|
>C1 : typeof C1
|
||||||
>c1Orc2.p1 : string
|
>ctor1.p1 : string
|
||||||
>c1Orc2 : C1
|
>ctor1 : C1
|
||||||
>p1 : string
|
>p1 : string
|
||||||
|
|
||||||
num = c1Orc2 instanceof C2 && c1Orc2.p2; // C2
|
num = ctor1 instanceof C2 && ctor1.p2; // C2
|
||||||
>num = c1Orc2 instanceof C2 && c1Orc2.p2 : number
|
>num = ctor1 instanceof C2 && ctor1.p2 : number
|
||||||
>num : number
|
>num : number
|
||||||
>c1Orc2 instanceof C2 && c1Orc2.p2 : number
|
>ctor1 instanceof C2 && ctor1.p2 : number
|
||||||
>c1Orc2 instanceof C2 : boolean
|
>ctor1 instanceof C2 : boolean
|
||||||
>c1Orc2 : C1 | C2
|
>ctor1 : C1 | C2
|
||||||
>C2 : typeof C2
|
>C2 : typeof C2
|
||||||
>c1Orc2.p2 : number
|
>ctor1.p2 : number
|
||||||
>c1Orc2 : C2
|
>ctor1 : C2
|
||||||
>p2 : number
|
>p2 : number
|
||||||
|
|
||||||
str = c1Orc2 instanceof D1 && c1Orc2.p1; // D1
|
str = ctor1 instanceof D1 && ctor1.p1; // D1
|
||||||
>str = c1Orc2 instanceof D1 && c1Orc2.p1 : string
|
>str = ctor1 instanceof D1 && ctor1.p1 : string
|
||||||
>str : string
|
>str : string
|
||||||
>c1Orc2 instanceof D1 && c1Orc2.p1 : string
|
>ctor1 instanceof D1 && ctor1.p1 : string
|
||||||
>c1Orc2 instanceof D1 : boolean
|
>ctor1 instanceof D1 : boolean
|
||||||
>c1Orc2 : C1 | C2
|
>ctor1 : C1 | C2
|
||||||
>D1 : typeof D1
|
>D1 : typeof D1
|
||||||
>c1Orc2.p1 : string
|
>ctor1.p1 : string
|
||||||
>c1Orc2 : D1
|
>ctor1 : D1
|
||||||
>p1 : string
|
>p1 : string
|
||||||
|
|
||||||
num = c1Orc2 instanceof D1 && c1Orc2.p3; // D1
|
num = ctor1 instanceof D1 && ctor1.p3; // D1
|
||||||
>num = c1Orc2 instanceof D1 && c1Orc2.p3 : number
|
>num = ctor1 instanceof D1 && ctor1.p3 : number
|
||||||
>num : number
|
>num : number
|
||||||
>c1Orc2 instanceof D1 && c1Orc2.p3 : number
|
>ctor1 instanceof D1 && ctor1.p3 : number
|
||||||
>c1Orc2 instanceof D1 : boolean
|
>ctor1 instanceof D1 : boolean
|
||||||
>c1Orc2 : C1 | C2
|
>ctor1 : C1 | C2
|
||||||
>D1 : typeof D1
|
>D1 : typeof D1
|
||||||
>c1Orc2.p3 : number
|
>ctor1.p3 : number
|
||||||
>c1Orc2 : D1
|
>ctor1 : D1
|
||||||
>p3 : number
|
>p3 : number
|
||||||
|
|
||||||
var c2Ord1: C2 | D1;
|
var ctor2: C2 | D1;
|
||||||
>c2Ord1 : C2 | D1
|
>ctor2 : C2 | D1
|
||||||
>C2 : C2
|
>C2 : C2
|
||||||
>D1 : D1
|
>D1 : D1
|
||||||
|
|
||||||
num = c2Ord1 instanceof C2 && c2Ord1.p2; // C2
|
num = ctor2 instanceof C2 && ctor2.p2; // C2
|
||||||
>num = c2Ord1 instanceof C2 && c2Ord1.p2 : number
|
>num = ctor2 instanceof C2 && ctor2.p2 : number
|
||||||
>num : number
|
>num : number
|
||||||
>c2Ord1 instanceof C2 && c2Ord1.p2 : number
|
>ctor2 instanceof C2 && ctor2.p2 : number
|
||||||
>c2Ord1 instanceof C2 : boolean
|
>ctor2 instanceof C2 : boolean
|
||||||
>c2Ord1 : C2 | D1
|
>ctor2 : C2 | D1
|
||||||
>C2 : typeof C2
|
>C2 : typeof C2
|
||||||
>c2Ord1.p2 : number
|
>ctor2.p2 : number
|
||||||
>c2Ord1 : C2
|
>ctor2 : C2
|
||||||
>p2 : number
|
>p2 : number
|
||||||
|
|
||||||
num = c2Ord1 instanceof D1 && c2Ord1.p3; // D1
|
num = ctor2 instanceof D1 && ctor2.p3; // D1
|
||||||
>num = c2Ord1 instanceof D1 && c2Ord1.p3 : number
|
>num = ctor2 instanceof D1 && ctor2.p3 : number
|
||||||
>num : number
|
>num : number
|
||||||
>c2Ord1 instanceof D1 && c2Ord1.p3 : number
|
>ctor2 instanceof D1 && ctor2.p3 : number
|
||||||
>c2Ord1 instanceof D1 : boolean
|
>ctor2 instanceof D1 : boolean
|
||||||
>c2Ord1 : C2 | D1
|
>ctor2 : C2 | D1
|
||||||
>D1 : typeof D1
|
>D1 : typeof D1
|
||||||
>c2Ord1.p3 : number
|
>ctor2.p3 : number
|
||||||
>c2Ord1 : D1
|
>ctor2 : D1
|
||||||
>p3 : number
|
>p3 : number
|
||||||
|
|
||||||
str = c2Ord1 instanceof D1 && c2Ord1.p1; // D1
|
str = ctor2 instanceof D1 && ctor2.p1; // D1
|
||||||
>str = c2Ord1 instanceof D1 && c2Ord1.p1 : string
|
>str = ctor2 instanceof D1 && ctor2.p1 : string
|
||||||
>str : string
|
>str : string
|
||||||
>c2Ord1 instanceof D1 && c2Ord1.p1 : string
|
>ctor2 instanceof D1 && ctor2.p1 : string
|
||||||
>c2Ord1 instanceof D1 : boolean
|
>ctor2 instanceof D1 : boolean
|
||||||
>c2Ord1 : C2 | D1
|
>ctor2 : C2 | D1
|
||||||
>D1 : typeof D1
|
>D1 : typeof D1
|
||||||
>c2Ord1.p1 : string
|
>ctor2.p1 : string
|
||||||
>c2Ord1 : D1
|
>ctor2 : D1
|
||||||
>p1 : string
|
>p1 : string
|
||||||
|
|
||||||
var r2: D1 | C2 = c2Ord1 instanceof C1 && c2Ord1; // C2 | D1
|
var r2: D1 | C2 = ctor2 instanceof C1 && ctor2; // C2 | D1
|
||||||
>r2 : D1 | C2
|
>r2 : D1 | C2
|
||||||
>D1 : D1
|
>D1 : D1
|
||||||
>C2 : C2
|
>C2 : C2
|
||||||
>c2Ord1 instanceof C1 && c2Ord1 : D1
|
>ctor2 instanceof C1 && ctor2 : D1
|
||||||
>c2Ord1 instanceof C1 : boolean
|
>ctor2 instanceof C1 : boolean
|
||||||
>c2Ord1 : C2 | D1
|
>ctor2 : C2 | D1
|
||||||
>C1 : typeof C1
|
>C1 : typeof C1
|
||||||
>c2Ord1 : D1
|
>ctor2 : D1
|
||||||
|
|
||||||
|
var ctor3: C1 | C2;
|
||||||
|
>ctor3 : C1 | C2
|
||||||
|
>C1 : C1
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
if (ctor3 instanceof C1) {
|
||||||
|
>ctor3 instanceof C1 : boolean
|
||||||
|
>ctor3 : C1 | C2
|
||||||
|
>C1 : typeof C1
|
||||||
|
|
||||||
|
ctor3.p1; // C1
|
||||||
|
>ctor3.p1 : string
|
||||||
|
>ctor3 : C1
|
||||||
|
>p1 : string
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor3.p2; // C2
|
||||||
|
>ctor3.p2 : number
|
||||||
|
>ctor3 : C2
|
||||||
|
>p2 : number
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor4: C1 | C2 | C3;
|
||||||
|
>ctor4 : C1 | C2 | C3
|
||||||
|
>C1 : C1
|
||||||
|
>C2 : C2
|
||||||
|
>C3 : C3
|
||||||
|
|
||||||
|
if (ctor4 instanceof C1) {
|
||||||
|
>ctor4 instanceof C1 : boolean
|
||||||
|
>ctor4 : C1 | C2 | C3
|
||||||
|
>C1 : typeof C1
|
||||||
|
|
||||||
|
ctor4.p1; // C1
|
||||||
|
>ctor4.p1 : string
|
||||||
|
>ctor4 : C1
|
||||||
|
>p1 : string
|
||||||
|
}
|
||||||
|
else if (ctor4 instanceof C2) {
|
||||||
|
>ctor4 instanceof C2 : boolean
|
||||||
|
>ctor4 : C2 | C3
|
||||||
|
>C2 : typeof C2
|
||||||
|
|
||||||
|
ctor4.p2; // C2
|
||||||
|
>ctor4.p2 : number
|
||||||
|
>ctor4 : C2
|
||||||
|
>p2 : number
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor4.p4; // C3
|
||||||
|
>ctor4.p4 : number
|
||||||
|
>ctor4 : C3
|
||||||
|
>p4 : number
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor5: C1 | D1 | C2;
|
||||||
|
>ctor5 : C1 | D1 | C2
|
||||||
|
>C1 : C1
|
||||||
|
>D1 : D1
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
if (ctor5 instanceof C1) {
|
||||||
|
>ctor5 instanceof C1 : boolean
|
||||||
|
>ctor5 : C1 | D1 | C2
|
||||||
|
>C1 : typeof C1
|
||||||
|
|
||||||
|
ctor5.p1; // C1
|
||||||
|
>ctor5.p1 : string
|
||||||
|
>ctor5 : C1
|
||||||
|
>p1 : string
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor5.p2; // C2
|
||||||
|
>ctor5.p2 : number
|
||||||
|
>ctor5 : C2
|
||||||
|
>p2 : number
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor6: C1 | C2 | C3;
|
||||||
|
>ctor6 : C1 | C2 | C3
|
||||||
|
>C1 : C1
|
||||||
|
>C2 : C2
|
||||||
|
>C3 : C3
|
||||||
|
|
||||||
|
if (ctor6 instanceof C1 || ctor6 instanceof C2) {
|
||||||
|
>ctor6 instanceof C1 || ctor6 instanceof C2 : boolean
|
||||||
|
>ctor6 instanceof C1 : boolean
|
||||||
|
>ctor6 : C1 | C2 | C3
|
||||||
|
>C1 : typeof C1
|
||||||
|
>ctor6 instanceof C2 : boolean
|
||||||
|
>ctor6 : C2 | C3
|
||||||
|
>C2 : typeof C2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor6.p4; // C3
|
||||||
|
>ctor6.p4 : number
|
||||||
|
>ctor6 : C3
|
||||||
|
>p4 : number
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(10,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(20,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(23,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(25,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/conformance/types/union/unionTypeCallSignatures4.ts (4 errors) ====
|
||||||
|
type F1 = (a: string, b?: string) => void;
|
||||||
|
type F2 = (a: string, b?: string, c?: string) => void;
|
||||||
|
type F3 = (a: string, ...rest: string[]) => void;
|
||||||
|
type F4 = (a: string, b?: string, ...rest: string[]) => void;
|
||||||
|
type F5 = (a: string, b: string) => void;
|
||||||
|
|
||||||
|
var f12: F1 | F2;
|
||||||
|
f12("a");
|
||||||
|
f12("a", "b");
|
||||||
|
f12("a", "b", "c"); // error
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
|
||||||
|
var f34: F3 | F4;
|
||||||
|
f34("a");
|
||||||
|
f34("a", "b");
|
||||||
|
f34("a", "b", "c");
|
||||||
|
|
||||||
|
var f1234: F1 | F2 | F3 | F4;
|
||||||
|
f1234("a");
|
||||||
|
f1234("a", "b");
|
||||||
|
f1234("a", "b", "c"); // error
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
|
||||||
|
var f12345: F1 | F2 | F3 | F4 | F5;
|
||||||
|
f12345("a"); // error
|
||||||
|
~~~~~~~~~~~
|
||||||
|
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
f12345("a", "b");
|
||||||
|
f12345("a", "b", "c"); // error
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||||
|
|
45
tests/baselines/reference/unionTypeCallSignatures4.js
Normal file
45
tests/baselines/reference/unionTypeCallSignatures4.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
//// [unionTypeCallSignatures4.ts]
|
||||||
|
type F1 = (a: string, b?: string) => void;
|
||||||
|
type F2 = (a: string, b?: string, c?: string) => void;
|
||||||
|
type F3 = (a: string, ...rest: string[]) => void;
|
||||||
|
type F4 = (a: string, b?: string, ...rest: string[]) => void;
|
||||||
|
type F5 = (a: string, b: string) => void;
|
||||||
|
|
||||||
|
var f12: F1 | F2;
|
||||||
|
f12("a");
|
||||||
|
f12("a", "b");
|
||||||
|
f12("a", "b", "c"); // error
|
||||||
|
|
||||||
|
var f34: F3 | F4;
|
||||||
|
f34("a");
|
||||||
|
f34("a", "b");
|
||||||
|
f34("a", "b", "c");
|
||||||
|
|
||||||
|
var f1234: F1 | F2 | F3 | F4;
|
||||||
|
f1234("a");
|
||||||
|
f1234("a", "b");
|
||||||
|
f1234("a", "b", "c"); // error
|
||||||
|
|
||||||
|
var f12345: F1 | F2 | F3 | F4 | F5;
|
||||||
|
f12345("a"); // error
|
||||||
|
f12345("a", "b");
|
||||||
|
f12345("a", "b", "c"); // error
|
||||||
|
|
||||||
|
|
||||||
|
//// [unionTypeCallSignatures4.js]
|
||||||
|
var f12;
|
||||||
|
f12("a");
|
||||||
|
f12("a", "b");
|
||||||
|
f12("a", "b", "c"); // error
|
||||||
|
var f34;
|
||||||
|
f34("a");
|
||||||
|
f34("a", "b");
|
||||||
|
f34("a", "b", "c");
|
||||||
|
var f1234;
|
||||||
|
f1234("a");
|
||||||
|
f1234("a", "b");
|
||||||
|
f1234("a", "b", "c"); // error
|
||||||
|
var f12345;
|
||||||
|
f12345("a"); // error
|
||||||
|
f12345("a", "b");
|
||||||
|
f12345("a", "b", "c"); // error
|
|
@ -0,0 +1,3 @@
|
||||||
|
function foo() {
|
||||||
|
return 1;;
|
||||||
|
}
|
|
@ -13,18 +13,55 @@ class C2 {
|
||||||
class D1 extends C1 {
|
class D1 extends C1 {
|
||||||
p3: number;
|
p3: number;
|
||||||
}
|
}
|
||||||
|
class C3 {
|
||||||
|
p4: number;
|
||||||
|
}
|
||||||
var str: string;
|
var str: string;
|
||||||
var num: number;
|
var num: number;
|
||||||
var strOrNum: string | number;
|
var strOrNum: string | number;
|
||||||
|
|
||||||
var c1Orc2: C1 | C2;
|
var ctor1: C1 | C2;
|
||||||
str = c1Orc2 instanceof C1 && c1Orc2.p1; // C1
|
str = ctor1 instanceof C1 && ctor1.p1; // C1
|
||||||
num = c1Orc2 instanceof C2 && c1Orc2.p2; // C2
|
num = ctor1 instanceof C2 && ctor1.p2; // C2
|
||||||
str = c1Orc2 instanceof D1 && c1Orc2.p1; // D1
|
str = ctor1 instanceof D1 && ctor1.p1; // D1
|
||||||
num = c1Orc2 instanceof D1 && c1Orc2.p3; // D1
|
num = ctor1 instanceof D1 && ctor1.p3; // D1
|
||||||
|
|
||||||
var c2Ord1: C2 | D1;
|
var ctor2: C2 | D1;
|
||||||
num = c2Ord1 instanceof C2 && c2Ord1.p2; // C2
|
num = ctor2 instanceof C2 && ctor2.p2; // C2
|
||||||
num = c2Ord1 instanceof D1 && c2Ord1.p3; // D1
|
num = ctor2 instanceof D1 && ctor2.p3; // D1
|
||||||
str = c2Ord1 instanceof D1 && c2Ord1.p1; // D1
|
str = ctor2 instanceof D1 && ctor2.p1; // D1
|
||||||
var r2: D1 | C2 = c2Ord1 instanceof C1 && c2Ord1; // C2 | D1
|
var r2: D1 | C2 = ctor2 instanceof C1 && ctor2; // C2 | D1
|
||||||
|
|
||||||
|
var ctor3: C1 | C2;
|
||||||
|
if (ctor3 instanceof C1) {
|
||||||
|
ctor3.p1; // C1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor3.p2; // C2
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor4: C1 | C2 | C3;
|
||||||
|
if (ctor4 instanceof C1) {
|
||||||
|
ctor4.p1; // C1
|
||||||
|
}
|
||||||
|
else if (ctor4 instanceof C2) {
|
||||||
|
ctor4.p2; // C2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor4.p4; // C3
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor5: C1 | D1 | C2;
|
||||||
|
if (ctor5 instanceof C1) {
|
||||||
|
ctor5.p1; // C1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor5.p2; // C2
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctor6: C1 | C2 | C3;
|
||||||
|
if (ctor6 instanceof C1 || ctor6 instanceof C2) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctor6.p4; // C3
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
class A {
|
||||||
|
self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f<T extends A>(x: T) {
|
||||||
|
function g<U extends T>(x: U) {
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
|
||||||
|
class B<T extends A> {
|
||||||
|
foo(x: T) {
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
bar<U extends T>(x: U) {
|
||||||
|
x = x.self();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
class C1 {
|
class C1 {
|
||||||
x: this;
|
x: this;
|
||||||
f(x: this): this { return undefined; }
|
f(x: this): this { return undefined; }
|
||||||
constructor(x: this) { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class C2 {
|
class C2 {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
type F1 = (a: string, b?: string) => void;
|
||||||
|
type F2 = (a: string, b?: string, c?: string) => void;
|
||||||
|
type F3 = (a: string, ...rest: string[]) => void;
|
||||||
|
type F4 = (a: string, b?: string, ...rest: string[]) => void;
|
||||||
|
type F5 = (a: string, b: string) => void;
|
||||||
|
|
||||||
|
var f12: F1 | F2;
|
||||||
|
f12("a");
|
||||||
|
f12("a", "b");
|
||||||
|
f12("a", "b", "c"); // error
|
||||||
|
|
||||||
|
var f34: F3 | F4;
|
||||||
|
f34("a");
|
||||||
|
f34("a", "b");
|
||||||
|
f34("a", "b", "c");
|
||||||
|
|
||||||
|
var f1234: F1 | F2 | F3 | F4;
|
||||||
|
f1234("a");
|
||||||
|
f1234("a", "b");
|
||||||
|
f1234("a", "b", "c"); // error
|
||||||
|
|
||||||
|
var f12345: F1 | F2 | F3 | F4 | F5;
|
||||||
|
f12345("a"); // error
|
||||||
|
f12345("a", "b");
|
||||||
|
f12345("a", "b", "c"); // error
|
|
@ -39,6 +39,7 @@
|
||||||
"no-inferrable-types": true,
|
"no-inferrable-types": true,
|
||||||
"no-null": true,
|
"no-null": true,
|
||||||
"boolean-trivia": true,
|
"boolean-trivia": true,
|
||||||
"type-operator-spacing": true
|
"type-operator-spacing": true,
|
||||||
|
"prefer-const": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue