mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into undefined-unique
This commit is contained in:
-10
@@ -1,15 +1,5 @@
|
||||
node_modules/
|
||||
built/*
|
||||
tests/cases/*.js
|
||||
tests/cases/*/*.js
|
||||
tests/cases/*/*/*.js
|
||||
tests/cases/*/*/*/*.js
|
||||
tests/cases/*/*/*/*/*.js
|
||||
tests/cases/*.js.map
|
||||
tests/cases/*/*.js.map
|
||||
tests/cases/*/*/*.js.map
|
||||
tests/cases/*/*/*/*.js.map
|
||||
tests/cases/*/*/*/*/*.js.map
|
||||
tests/cases/rwc/*
|
||||
tests/cases/test262/*
|
||||
tests/cases/perf/*
|
||||
|
||||
+19
-4
@@ -8,6 +8,7 @@ TypeScript is authored by:
|
||||
* Basarat Ali Syed
|
||||
* Ben Duffield
|
||||
* Bill Ticehurst
|
||||
* Brett Mayen
|
||||
* Bryan Forbes
|
||||
* Caitlin Potter
|
||||
* Chris Bubernak
|
||||
@@ -17,11 +18,14 @@ TypeScript is authored by:
|
||||
* Dan Quirk
|
||||
* Daniel Rosenwasser
|
||||
* David Li
|
||||
* Dick van den Brink
|
||||
* Dirk Bäumer
|
||||
* Denis Nedelyaev
|
||||
* Dick van den Brink
|
||||
* Dirk Bäumer
|
||||
* Eyas Sharaiha
|
||||
* Frank Wallis
|
||||
* Gabriel Isenberg
|
||||
* Gilad Peleg
|
||||
* Graeme Wicksted
|
||||
* Guillaume Salles
|
||||
* Harald Niesche
|
||||
* Ingvar Stepanyan
|
||||
@@ -31,30 +35,39 @@ TypeScript is authored by:
|
||||
* Jason Ramsay
|
||||
* Jed Mao
|
||||
* Johannes Rieken
|
||||
* John Vilk
|
||||
* Jonathan Bond-Caron
|
||||
* Jonathan Park
|
||||
* Jonathan Turner
|
||||
* Josh Kalderimis
|
||||
* Julian Williams
|
||||
* Kagami Sascha Rosylight
|
||||
* Keith Mashinter
|
||||
* Ken Howard
|
||||
* Kenji Imamula
|
||||
* Lorant Pinter
|
||||
* Martin Všetička
|
||||
* Masahiro Wakame
|
||||
* Max Deepfield
|
||||
* Micah Zoltu
|
||||
* Mohamed Hegazy
|
||||
* Nathan Shively-Sanders
|
||||
* Oleg Mihailik
|
||||
* Oleksandr Chekhovskyi
|
||||
* Paul van Brenk
|
||||
* Pedro Maltez
|
||||
* Philip Bulley
|
||||
* piloopin
|
||||
* @progre
|
||||
* Punya Biswal
|
||||
* Ron Buckton
|
||||
* Ryan Cavanaugh
|
||||
* Ryohei Ikegami
|
||||
* Sébastien Arod
|
||||
* Sheetal Nandi
|
||||
* Shengping Zhong
|
||||
* Shyyko Serhiy
|
||||
* Simon Hürlimann
|
||||
* Simon Hürlimann
|
||||
* Solal Pirelli
|
||||
* Stan Thomas
|
||||
* Steve Lucco
|
||||
@@ -63,8 +76,10 @@ TypeScript is authored by:
|
||||
* togru
|
||||
* Tomas Grubliauskas
|
||||
* TruongSinh Tran-Nguyen
|
||||
* Viliv Vane
|
||||
* Vladimir Matveev
|
||||
* Wesley Wigham
|
||||
* York Yao
|
||||
* Yui Tanglertsampan
|
||||
* Zev Spitz
|
||||
* Zhengbo Li
|
||||
* Zhengbo Li
|
||||
|
||||
+4
-2
@@ -36,11 +36,13 @@ Your pull request should:
|
||||
|
||||
The library sources are in: [src/lib](https://github.com/Microsoft/TypeScript/tree/master/src/lib)
|
||||
|
||||
To build the library files, run
|
||||
Library files in `built/local/` are updated by running
|
||||
```Shell
|
||||
jake lib
|
||||
jake
|
||||
```
|
||||
|
||||
The files in `lib/` are used to bootstrap compilation and usually do not need to be updated.
|
||||
|
||||
#### `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
|
||||
|
||||
+25
-7
@@ -40,6 +40,7 @@ var compilerSources = [
|
||||
"utilities.ts",
|
||||
"binder.ts",
|
||||
"checker.ts",
|
||||
"sourcemap.ts",
|
||||
"declarationEmitter.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
@@ -59,6 +60,7 @@ var servicesSources = [
|
||||
"utilities.ts",
|
||||
"binder.ts",
|
||||
"checker.ts",
|
||||
"sourcemap.ts",
|
||||
"declarationEmitter.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
@@ -106,6 +108,17 @@ var serverCoreSources = [
|
||||
return path.join(serverDirectory, f);
|
||||
});
|
||||
|
||||
var scriptSources = [
|
||||
"tslint/booleanTriviaRule.ts",
|
||||
"tslint/nextLineRule.ts",
|
||||
"tslint/noNullRule.ts",
|
||||
"tslint/preferConstRule.ts",
|
||||
"tslint/typeOperatorSpacingRule.ts",
|
||||
"tslint/noInOperatorRule.ts"
|
||||
].map(function (f) {
|
||||
return path.join(scriptsDirectory, f);
|
||||
});
|
||||
|
||||
var serverSources = serverCoreSources.concat(servicesSources);
|
||||
|
||||
var languageServiceLibrarySources = [
|
||||
@@ -365,7 +378,6 @@ file(builtGeneratedDiagnosticMessagesJSON,[generatedDiagnosticMessagesJSON], fun
|
||||
desc("Generates a diagnostic file in TypeScript based on an input JSON file");
|
||||
task("generate-diagnostics", [diagnosticInfoMapTs]);
|
||||
|
||||
|
||||
// Publish nightly
|
||||
var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
|
||||
var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
|
||||
@@ -466,7 +478,7 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca
|
||||
var nodeDefinitionsFileContents = definitionFileContents + "\r\nexport = ts;";
|
||||
fs.writeFileSync(nodeDefinitionsFile, nodeDefinitionsFileContents);
|
||||
|
||||
// Node package definition file to be distributed without the package. Created by replacing
|
||||
// Node package definition file to be distributed without the package. Created by replacing
|
||||
// 'ts' namespace with '"typescript"' as a module.
|
||||
var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
|
||||
fs.writeFileSync(nodeStandaloneDefinitionsFile, nodeStandaloneDefinitionsFileContents);
|
||||
@@ -864,7 +876,8 @@ var tslintRules = ([
|
||||
"noNullRule",
|
||||
"preferConstRule",
|
||||
"booleanTriviaRule",
|
||||
"typeOperatorSpacingRule"
|
||||
"typeOperatorSpacingRule",
|
||||
"noInOperatorRule"
|
||||
]);
|
||||
var tslintRulesFiles = tslintRules.map(function(p) {
|
||||
return path.join(tslintRuleDir, p + ".ts");
|
||||
@@ -875,7 +888,7 @@ var tslintRulesOutFiles = tslintRules.map(function(p) {
|
||||
desc("Compiles tslint rules to js");
|
||||
task("build-rules", tslintRulesOutFiles);
|
||||
tslintRulesFiles.forEach(function(ruleFile, i) {
|
||||
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
|
||||
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
|
||||
});
|
||||
|
||||
function getLinterOptions() {
|
||||
@@ -909,18 +922,23 @@ function lintFileAsync(options, path, cb) {
|
||||
|
||||
var lintTargets = compilerSources
|
||||
.concat(harnessCoreSources)
|
||||
.concat(serverCoreSources);
|
||||
.concat(serverCoreSources)
|
||||
.concat(scriptSources);
|
||||
|
||||
desc("Runs tslint on the compiler sources");
|
||||
task("lint", ["build-rules"], function() {
|
||||
var lintOptions = getLinterOptions();
|
||||
var failed = 0;
|
||||
for (var i in lintTargets) {
|
||||
var result = lintFile(lintOptions, lintTargets[i]);
|
||||
if (result.failureCount > 0) {
|
||||
console.log(result.output);
|
||||
fail('Linter errors.', result.failureCount);
|
||||
failed += result.failureCount;
|
||||
}
|
||||
}
|
||||
if (failed > 0) {
|
||||
fail('Linter errors.', failed);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -937,7 +955,7 @@ function lintWatchFile(filename) {
|
||||
if (event !== "change") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!lintSemaphores[filename]) {
|
||||
lintSemaphores[filename] = true;
|
||||
lintFileAsync(getLinterOptions(), filename, function(err, result) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[](https://travis-ci.org/Microsoft/TypeScript)
|
||||
[](http://badge.fury.io/js/typescript)
|
||||
[](https://npmjs.org/package/typescript)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
|
||||
# TypeScript
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1323,7 +1323,7 @@ x = "hello"; // Ok
|
||||
x = 42; // Ok
|
||||
x = test; // Error, boolean not assignable
|
||||
x = test ? 5 : "five"; // Ok
|
||||
x = test ? 0 : false; // Error, number | boolean not asssignable
|
||||
x = test ? 0 : false; // Error, number | boolean not assignable
|
||||
```
|
||||
|
||||
it is possible to assign 'x' a value of type `string`, `number`, or the union type `string | number`, but not any other type. To access a value in 'x', a type guard can be used to first narrow the type of 'x' to either `string` or `number`:
|
||||
|
||||
+1
-1
@@ -1,4 +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.
|
||||
If you need to make modifications, the respective files should be changed within the repository's top-level `src` directory. Running `jake LKG` will then appropriately update the files in this directory.
|
||||
|
||||
+1859
-1423
File diff suppressed because it is too large
Load Diff
+1057
-557
File diff suppressed because it is too large
Load Diff
Vendored
+13
-6
@@ -387,6 +387,7 @@ declare namespace ts {
|
||||
right: Identifier;
|
||||
}
|
||||
type EntityName = Identifier | QualifiedName;
|
||||
type PropertyName = Identifier | LiteralExpression | ComputedPropertyName;
|
||||
type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
|
||||
interface Declaration extends Node {
|
||||
_declarationBrand: any;
|
||||
@@ -425,7 +426,7 @@ declare namespace ts {
|
||||
initializer?: Expression;
|
||||
}
|
||||
interface BindingElement extends Declaration {
|
||||
propertyName?: Identifier;
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: Node;
|
||||
name: Identifier | BindingPattern;
|
||||
initializer?: Expression;
|
||||
@@ -452,7 +453,7 @@ declare namespace ts {
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
interface VariableLikeDeclaration extends Declaration {
|
||||
propertyName?: Identifier;
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: Node;
|
||||
name: DeclarationName;
|
||||
questionToken?: Node;
|
||||
@@ -581,7 +582,7 @@ declare namespace ts {
|
||||
asteriskToken?: Node;
|
||||
expression?: Expression;
|
||||
}
|
||||
interface BinaryExpression extends Expression {
|
||||
interface BinaryExpression extends Expression, Declaration {
|
||||
left: Expression;
|
||||
operatorToken: Node;
|
||||
right: Expression;
|
||||
@@ -625,7 +626,7 @@ declare namespace ts {
|
||||
interface ObjectLiteralExpression extends PrimaryExpression, Declaration {
|
||||
properties: NodeArray<ObjectLiteralElement>;
|
||||
}
|
||||
interface PropertyAccessExpression extends MemberExpression {
|
||||
interface PropertyAccessExpression extends MemberExpression, Declaration {
|
||||
expression: LeftHandSideExpression;
|
||||
dotToken: Node;
|
||||
name: Identifier;
|
||||
@@ -1220,6 +1221,7 @@ declare namespace ts {
|
||||
ObjectLiteral = 524288,
|
||||
ESSymbol = 16777216,
|
||||
ThisType = 33554432,
|
||||
ObjectLiteralPatternWithComputedProperties = 67108864,
|
||||
StringLike = 258,
|
||||
NumberLike = 132,
|
||||
ObjectType = 80896,
|
||||
@@ -1537,7 +1539,6 @@ declare namespace ts {
|
||||
function getTypeParameterOwner(d: Declaration): Declaration;
|
||||
}
|
||||
declare namespace ts {
|
||||
function getNodeConstructor(kind: SyntaxKind): new (pos?: number, end?: number) => Node;
|
||||
function createNode(kind: SyntaxKind, pos?: number, end?: number): Node;
|
||||
function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T;
|
||||
function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes?: boolean): SourceFile;
|
||||
@@ -2126,6 +2127,9 @@ declare namespace ts {
|
||||
static typeAliasName: string;
|
||||
static parameterName: string;
|
||||
static docCommentTagName: string;
|
||||
static jsxOpenTagName: string;
|
||||
static jsxCloseTagName: string;
|
||||
static jsxSelfClosingTagName: string;
|
||||
}
|
||||
enum ClassificationType {
|
||||
comment = 1,
|
||||
@@ -2146,6 +2150,9 @@ declare namespace ts {
|
||||
typeAliasName = 16,
|
||||
parameterName = 17,
|
||||
docCommentTagName = 18,
|
||||
jsxOpenTagName = 19,
|
||||
jsxCloseTagName = 20,
|
||||
jsxSelfClosingTagName = 21,
|
||||
}
|
||||
interface DisplayPartsSymbolWriter extends SymbolWriter {
|
||||
displayParts(): SymbolDisplayPart[];
|
||||
@@ -2171,7 +2178,7 @@ declare namespace ts {
|
||||
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile;
|
||||
function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string;
|
||||
function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry;
|
||||
function preProcessFile(sourceText: string, readImportFiles?: boolean): PreProcessedFileInfo;
|
||||
function preProcessFile(sourceText: string, readImportFiles?: boolean, detectJavaScriptImports?: boolean): PreProcessedFileInfo;
|
||||
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry): LanguageService;
|
||||
function createClassifier(): Classifier;
|
||||
/**
|
||||
|
||||
+2546
-1958
File diff suppressed because it is too large
Load Diff
Vendored
+13
-6
@@ -387,6 +387,7 @@ declare namespace ts {
|
||||
right: Identifier;
|
||||
}
|
||||
type EntityName = Identifier | QualifiedName;
|
||||
type PropertyName = Identifier | LiteralExpression | ComputedPropertyName;
|
||||
type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
|
||||
interface Declaration extends Node {
|
||||
_declarationBrand: any;
|
||||
@@ -425,7 +426,7 @@ declare namespace ts {
|
||||
initializer?: Expression;
|
||||
}
|
||||
interface BindingElement extends Declaration {
|
||||
propertyName?: Identifier;
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: Node;
|
||||
name: Identifier | BindingPattern;
|
||||
initializer?: Expression;
|
||||
@@ -452,7 +453,7 @@ declare namespace ts {
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
interface VariableLikeDeclaration extends Declaration {
|
||||
propertyName?: Identifier;
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: Node;
|
||||
name: DeclarationName;
|
||||
questionToken?: Node;
|
||||
@@ -581,7 +582,7 @@ declare namespace ts {
|
||||
asteriskToken?: Node;
|
||||
expression?: Expression;
|
||||
}
|
||||
interface BinaryExpression extends Expression {
|
||||
interface BinaryExpression extends Expression, Declaration {
|
||||
left: Expression;
|
||||
operatorToken: Node;
|
||||
right: Expression;
|
||||
@@ -625,7 +626,7 @@ declare namespace ts {
|
||||
interface ObjectLiteralExpression extends PrimaryExpression, Declaration {
|
||||
properties: NodeArray<ObjectLiteralElement>;
|
||||
}
|
||||
interface PropertyAccessExpression extends MemberExpression {
|
||||
interface PropertyAccessExpression extends MemberExpression, Declaration {
|
||||
expression: LeftHandSideExpression;
|
||||
dotToken: Node;
|
||||
name: Identifier;
|
||||
@@ -1220,6 +1221,7 @@ declare namespace ts {
|
||||
ObjectLiteral = 524288,
|
||||
ESSymbol = 16777216,
|
||||
ThisType = 33554432,
|
||||
ObjectLiteralPatternWithComputedProperties = 67108864,
|
||||
StringLike = 258,
|
||||
NumberLike = 132,
|
||||
ObjectType = 80896,
|
||||
@@ -1537,7 +1539,6 @@ declare namespace ts {
|
||||
function getTypeParameterOwner(d: Declaration): Declaration;
|
||||
}
|
||||
declare namespace ts {
|
||||
function getNodeConstructor(kind: SyntaxKind): new (pos?: number, end?: number) => Node;
|
||||
function createNode(kind: SyntaxKind, pos?: number, end?: number): Node;
|
||||
function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T;
|
||||
function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes?: boolean): SourceFile;
|
||||
@@ -2126,6 +2127,9 @@ declare namespace ts {
|
||||
static typeAliasName: string;
|
||||
static parameterName: string;
|
||||
static docCommentTagName: string;
|
||||
static jsxOpenTagName: string;
|
||||
static jsxCloseTagName: string;
|
||||
static jsxSelfClosingTagName: string;
|
||||
}
|
||||
enum ClassificationType {
|
||||
comment = 1,
|
||||
@@ -2146,6 +2150,9 @@ declare namespace ts {
|
||||
typeAliasName = 16,
|
||||
parameterName = 17,
|
||||
docCommentTagName = 18,
|
||||
jsxOpenTagName = 19,
|
||||
jsxCloseTagName = 20,
|
||||
jsxSelfClosingTagName = 21,
|
||||
}
|
||||
interface DisplayPartsSymbolWriter extends SymbolWriter {
|
||||
displayParts(): SymbolDisplayPart[];
|
||||
@@ -2171,7 +2178,7 @@ declare namespace ts {
|
||||
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile;
|
||||
function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string;
|
||||
function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry;
|
||||
function preProcessFile(sourceText: string, readImportFiles?: boolean): PreProcessedFileInfo;
|
||||
function preProcessFile(sourceText: string, readImportFiles?: boolean, detectJavaScriptImports?: boolean): PreProcessedFileInfo;
|
||||
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry): LanguageService;
|
||||
function createClassifier(): Classifier;
|
||||
/**
|
||||
|
||||
+2546
-1958
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -35,7 +35,8 @@
|
||||
"browserify": "latest",
|
||||
"istanbul": "latest",
|
||||
"mocha-fivemat-progress-reporter": "latest",
|
||||
"tslint": "latest",
|
||||
"tslint": "next",
|
||||
"typescript": "next",
|
||||
"tsd": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
|
||||
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||
|
||||
import * as Lint from "tslint/lib/lint";
|
||||
import * as ts from "typescript";
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING_FACTORY = (name: string, currently: string) => `Tag boolean argument as '${name}' (currently '${currently}')`;
|
||||
@@ -19,7 +18,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
|
||||
|
||||
visitCallExpression(node: ts.CallExpression) {
|
||||
super.visitCallExpression(node);
|
||||
if (node.arguments) {
|
||||
if (node.arguments) {
|
||||
const targetCallSignature = this.checker.getResolvedSignature(node);
|
||||
if (!!targetCallSignature) {
|
||||
const targetParameters = targetCallSignature.getParameters();
|
||||
@@ -37,7 +36,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
|
||||
let triviaContent: string;
|
||||
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
|
||||
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
|
||||
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); //+/-2 to remove /**/
|
||||
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); // +/-2 to remove /**/
|
||||
}
|
||||
if (triviaContent !== param.getName()) {
|
||||
this.addFailure(this.createFailure(arg.getStart(source), arg.getWidth(source), Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent)));
|
||||
@@ -45,6 +44,6 @@ class BooleanTriviaWalker extends Lint.RuleWalker {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
|
||||
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||
import * as Lint from "tslint/lib/lint";
|
||||
import * as ts from "typescript";
|
||||
|
||||
const OPTION_CATCH = "check-catch";
|
||||
const OPTION_ELSE = "check-else";
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as Lint from "tslint/lib/lint";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "Don't use the 'in' keyword - use 'hasProperty' to check for key presence instead";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new InWalker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
class InWalker extends Lint.RuleWalker {
|
||||
visitNode(node: ts.Node) {
|
||||
super.visitNode(node);
|
||||
if (node.kind === ts.SyntaxKind.InKeyword && node.parent && node.parent.kind === ts.SyntaxKind.BinaryExpression) {
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
|
||||
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||
import * as Lint from "tslint/lib/lint";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
|
||||
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||
import * as Lint from "tslint/lib/lint";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
@@ -85,12 +85,12 @@ class PreferConstWalker extends Lint.RuleWalker {
|
||||
|
||||
visitBinaryExpression(node: ts.BinaryExpression) {
|
||||
if (isAssignmentOperator(node.operatorToken.kind)) {
|
||||
this.visitLHSExpressions(node.left);
|
||||
this.visitLeftHandSideExpression(node.left);
|
||||
}
|
||||
super.visitBinaryExpression(node);
|
||||
}
|
||||
|
||||
private visitLHSExpressions(node: ts.Expression) {
|
||||
private visitLeftHandSideExpression(node: ts.Expression) {
|
||||
while (node.kind === ts.SyntaxKind.ParenthesizedExpression) {
|
||||
node = (node as ts.ParenthesizedExpression).expression;
|
||||
}
|
||||
@@ -101,23 +101,25 @@ class PreferConstWalker extends Lint.RuleWalker {
|
||||
this.visitBindingLiteralExpression(node as (ts.ArrayLiteralExpression | ts.ObjectLiteralExpression));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private visitBindingLiteralExpression(node: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression) {
|
||||
if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
|
||||
const pattern = node as ts.ObjectLiteralExpression;
|
||||
for (const element of pattern.properties) {
|
||||
if (element.name.kind === ts.SyntaxKind.Identifier) {
|
||||
this.markAssignment(element.name as ts.Identifier)
|
||||
const kind = element.kind;
|
||||
|
||||
if (kind === ts.SyntaxKind.ShorthandPropertyAssignment) {
|
||||
this.markAssignment((element as ts.ShorthandPropertyAssignment).name);
|
||||
}
|
||||
else if (isBindingPattern(element.name)) {
|
||||
this.visitBindingPatternIdentifiers(element.name as ts.BindingPattern);
|
||||
else if (kind === ts.SyntaxKind.PropertyAssignment) {
|
||||
this.visitLeftHandSideExpression((element as ts.PropertyAssignment).initializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
||||
const pattern = node as ts.ArrayLiteralExpression;
|
||||
for (const element of pattern.elements) {
|
||||
this.visitLHSExpressions(element);
|
||||
this.visitLeftHandSideExpression(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,7 +147,7 @@ class PreferConstWalker extends Lint.RuleWalker {
|
||||
|
||||
private visitAnyUnaryExpression(node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression) {
|
||||
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) {
|
||||
this.visitLHSExpressions(node.operand);
|
||||
this.visitLeftHandSideExpression(node.operand);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,12 +213,12 @@ class PreferConstWalker extends Lint.RuleWalker {
|
||||
}
|
||||
}
|
||||
|
||||
private collectNameIdentifiers(value: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map<DeclarationUsages>) {
|
||||
private collectNameIdentifiers(declaration: ts.VariableDeclaration, node: ts.Identifier | ts.BindingPattern, table: ts.Map<DeclarationUsages>) {
|
||||
if (node.kind === ts.SyntaxKind.Identifier) {
|
||||
table[(node as ts.Identifier).text] = {declaration: value, usages: 0};
|
||||
table[(node as ts.Identifier).text] = { declaration, usages: 0 };
|
||||
}
|
||||
else {
|
||||
this.collectBindingPatternIdentifiers(value, node as ts.BindingPattern, table);
|
||||
this.collectBindingPatternIdentifiers(declaration, node as ts.BindingPattern, table);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
|
||||
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||
import * as Lint from "tslint/lib/lint";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
@@ -13,10 +13,10 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
class TypeOperatorSpacingWalker extends Lint.RuleWalker {
|
||||
public visitNode(node: ts.Node) {
|
||||
if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) {
|
||||
let types = (<ts.UnionOrIntersectionTypeNode>node).types;
|
||||
const types = (<ts.UnionOrIntersectionTypeNode>node).types;
|
||||
let expectedStart = types[0].end + 2; // space, | or &
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
let currentType = types[i];
|
||||
const currentType = types[i];
|
||||
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
|
||||
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
|
||||
+15
-8
@@ -139,6 +139,8 @@ namespace ts {
|
||||
file.classifiableNames = classifiableNames;
|
||||
}
|
||||
|
||||
file = undefined;
|
||||
options = undefined;
|
||||
parent = undefined;
|
||||
container = undefined;
|
||||
blockScopeContainer = undefined;
|
||||
@@ -175,9 +177,14 @@ namespace ts {
|
||||
symbol.members = {};
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value && !symbol.valueDeclaration) {
|
||||
symbol.valueDeclaration = node;
|
||||
}
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
const valueDeclaration = symbol.valueDeclaration;
|
||||
if (!valueDeclaration ||
|
||||
(valueDeclaration.kind !== node.kind && valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) {
|
||||
// other kinds of value declarations take precedence over modules
|
||||
symbol.valueDeclaration = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Should not be called on a declaration with a computed property name,
|
||||
@@ -189,7 +196,7 @@ namespace ts {
|
||||
}
|
||||
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>node.name).expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression.kind)) {
|
||||
return (<LiteralExpression>nameExpression).text;
|
||||
}
|
||||
@@ -450,7 +457,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Returns true if node and its subnodes were successfully traversed.
|
||||
* Returning false means that node was not examined and caller needs to dive into the node himself.
|
||||
* Returning false means that node was not examined and caller needs to dive into the node himself.
|
||||
*/
|
||||
function bindReachableStatement(node: Node): void {
|
||||
if (checkUnreachable(node)) {
|
||||
@@ -560,7 +567,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindIfStatement(n: IfStatement): void {
|
||||
// denotes reachability state when entering 'thenStatement' part of the if statement:
|
||||
// denotes reachability state when entering 'thenStatement' part of the if statement:
|
||||
// i.e. if condition is false then thenStatement is unreachable
|
||||
const ifTrueState = n.expression.kind === SyntaxKind.FalseKeyword ? Reachability.Unreachable : currentReachabilityState;
|
||||
// denotes reachability state when entering 'elseStatement':
|
||||
@@ -1179,7 +1186,7 @@ namespace ts {
|
||||
return checkStrictModePrefixUnaryExpression(<PrefixUnaryExpression>node);
|
||||
case SyntaxKind.WithStatement:
|
||||
return checkStrictModeWithStatement(<WithStatement>node);
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.ThisType:
|
||||
seenThisKeyword = true;
|
||||
return;
|
||||
|
||||
@@ -1528,7 +1535,7 @@ namespace ts {
|
||||
|
||||
// unreachable code is reported if
|
||||
// - user has explicitly asked about it AND
|
||||
// - statement is in not ambient context (statements in ambient context is already an error
|
||||
// - statement is in not ambient context (statements in ambient context is already an error
|
||||
// so we should not report extras) AND
|
||||
// - node is not variable statement OR
|
||||
// - node is block scoped variable statement OR
|
||||
|
||||
+444
-215
File diff suppressed because it is too large
Load Diff
@@ -279,6 +279,16 @@ namespace ts {
|
||||
name: "forceConsistentCasingInFileNames",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
|
||||
},
|
||||
{
|
||||
name: "allowSyntheticDefaultImports",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
|
||||
},
|
||||
{
|
||||
name: "allowJs",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Allow_javascript_files_to_be_compiled
|
||||
}
|
||||
];
|
||||
|
||||
@@ -474,9 +484,10 @@ namespace ts {
|
||||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string): ParsedCommandLine {
|
||||
const { options, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}): ParsedCommandLine {
|
||||
const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
|
||||
|
||||
const options = extend(existingOptions, optionsFromJsonConfigFile);
|
||||
return {
|
||||
options,
|
||||
fileNames: getFileNames(),
|
||||
@@ -494,23 +505,32 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const filesSeen: Map<boolean> = {};
|
||||
const exclude = json["exclude"] instanceof Array ? map(<string[]>json["exclude"], normalizeSlashes) : undefined;
|
||||
const sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
|
||||
for (let i = 0; i < sysFiles.length; i++) {
|
||||
const name = sysFiles[i];
|
||||
if (fileExtensionIs(name, ".d.ts")) {
|
||||
const baseName = name.substr(0, name.length - ".d.ts".length);
|
||||
if (!contains(sysFiles, baseName + ".tsx") && !contains(sysFiles, baseName + ".ts")) {
|
||||
fileNames.push(name);
|
||||
const supportedExtensions = getSupportedExtensions(options);
|
||||
Debug.assert(indexOf(supportedExtensions, ".ts") < indexOf(supportedExtensions, ".d.ts"), "Changed priority of extensions to pick");
|
||||
|
||||
// Get files of supported extensions in their order of resolution
|
||||
for (const extension of supportedExtensions) {
|
||||
const filesInDirWithExtension = host.readDirectory(basePath, extension, exclude);
|
||||
for (const fileName of filesInDirWithExtension) {
|
||||
// .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension,
|
||||
// lets pick them when its turn comes up
|
||||
if (extension === ".ts" && fileExtensionIs(fileName, ".d.ts")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (fileExtensionIs(name, ".ts")) {
|
||||
if (!contains(sysFiles, name + "x")) {
|
||||
fileNames.push(name);
|
||||
|
||||
// If this is one of the output extension (which would be .d.ts and .js if we are allowing compilation of js files)
|
||||
// do not include this file if we included .ts or .tsx file with same base name as it could be output of the earlier compilation
|
||||
if (extension === ".d.ts" || (options.allowJs && contains(supportedJavascriptExtensions, extension))) {
|
||||
const baseName = fileName.substr(0, fileName.length - extension.length);
|
||||
if (hasProperty(filesSeen, baseName + ".ts") || hasProperty(filesSeen, baseName + ".tsx")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
fileNames.push(name);
|
||||
|
||||
filesSeen[fileName] = true;
|
||||
fileNames.push(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-8
@@ -297,8 +297,8 @@ namespace ts {
|
||||
return <T>result;
|
||||
}
|
||||
|
||||
export function extend<T1, T2>(first: Map<T1>, second: Map<T2>): Map<T1 & T2> {
|
||||
const result: Map<T1 & T2> = {};
|
||||
export function extend<T1 extends Map<{}>, T2 extends Map<{}>>(first: T1 , second: T2): T1 & T2 {
|
||||
const result: T1 & T2 = <any>{};
|
||||
for (const id in first) {
|
||||
(result as any)[id] = first[id];
|
||||
}
|
||||
@@ -356,6 +356,33 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the properties of a map.
|
||||
*
|
||||
* @param map The map to reduce
|
||||
* @param callback An aggregation function that is called for each entry in the map
|
||||
* @param initial The initial value for the reduction.
|
||||
*/
|
||||
export function reduceProperties<T, U>(map: Map<T>, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
|
||||
let result = initial;
|
||||
if (map) {
|
||||
for (const key in map) {
|
||||
if (hasProperty(map, key)) {
|
||||
result = callback(result, map[key], String(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a value is an array.
|
||||
*/
|
||||
export function isArray(value: any): value is any[] {
|
||||
return Array.isArray ? Array.isArray(value) : value instanceof Array;
|
||||
}
|
||||
|
||||
export function memoize<T>(callback: () => T): () => T {
|
||||
let value: T;
|
||||
return () => {
|
||||
@@ -714,7 +741,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getBaseFileName(path: string) {
|
||||
if (!path) {
|
||||
if (path === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const i = path.lastIndexOf(directorySeparator);
|
||||
@@ -738,13 +765,18 @@ namespace ts {
|
||||
/**
|
||||
* List of supported extensions in order of file resolution precedence.
|
||||
*/
|
||||
export const supportedExtensions = [".ts", ".tsx", ".d.ts"];
|
||||
export const supportedJsExtensions = supportedExtensions.concat(".js", ".jsx");
|
||||
export const supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"];
|
||||
export const supportedJavascriptExtensions = [".js", ".jsx"];
|
||||
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
|
||||
|
||||
export function isSupportedSourceFileName(fileName: string) {
|
||||
export function getSupportedExtensions(options?: CompilerOptions): string[] {
|
||||
return options && options.allowJs ? allSupportedExtensions : supportedTypeScriptExtensions;
|
||||
}
|
||||
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions) {
|
||||
if (!fileName) { return false; }
|
||||
|
||||
for (const extension of supportedExtensions) {
|
||||
for (const extension of getSupportedExtensions(compilerOptions)) {
|
||||
if (fileExtensionIs(fileName, extension)) {
|
||||
return true;
|
||||
}
|
||||
@@ -842,7 +874,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function fail(message?: string): void {
|
||||
Debug.assert(false, message);
|
||||
Debug.assert(/*expression*/ false, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+122
-111
@@ -31,13 +31,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
const jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
|
||||
emitDeclarations(host, resolver, diagnostics, jsFilePath, targetSourceFile);
|
||||
return diagnostics;
|
||||
const declarationDiagnostics = createDiagnosticCollection();
|
||||
forEachExpectedEmitFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
|
||||
return declarationDiagnostics.getDiagnostics(targetSourceFile.fileName);
|
||||
|
||||
function getDeclarationDiagnosticsFromFile({ declarationFilePath }, sources: SourceFile[], isBundledEmit: boolean) {
|
||||
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit);
|
||||
}
|
||||
}
|
||||
|
||||
function emitDeclarations(host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[], jsFilePath: string, root?: SourceFile): DeclarationEmit {
|
||||
function emitDeclarations(host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, declarationFilePath: string,
|
||||
sourceFiles: SourceFile[], isBundledEmit: boolean): DeclarationEmit {
|
||||
const newLine = host.getNewLine();
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
|
||||
@@ -58,7 +62,7 @@ namespace ts {
|
||||
let errorNameNode: DeclarationName;
|
||||
const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
|
||||
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
|
||||
let noDeclare = !root;
|
||||
let noDeclare: boolean;
|
||||
|
||||
let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||
let asynchronousSubModuleDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[];
|
||||
@@ -68,105 +72,78 @@ namespace ts {
|
||||
// and we could be collecting these paths from multiple files into single one with --out option
|
||||
let referencePathsOutput = "";
|
||||
|
||||
if (root) {
|
||||
// Emitting just a single file, so emit references in this file only
|
||||
// Emit references corresponding to each file
|
||||
const emittedReferencedFiles: SourceFile[] = [];
|
||||
let addedGlobalFileReference = false;
|
||||
let allSourcesModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||
forEach(sourceFiles, sourceFile => {
|
||||
// Dont emit for javascript file
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check what references need to be added
|
||||
if (!compilerOptions.noResolve) {
|
||||
let addedGlobalFileReference = false;
|
||||
forEach(root.referencedFiles, fileReference => {
|
||||
const referencedFile = tryResolveScriptReference(host, root, fileReference);
|
||||
forEach(sourceFile.referencedFiles, fileReference => {
|
||||
const referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
|
||||
|
||||
// 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
|
||||
shouldEmitToOwnFile(referencedFile, compilerOptions) || // This is referenced file is emitting its own js file
|
||||
!addedGlobalFileReference)) { // Or the global out file corresponding to this reference was not added
|
||||
|
||||
writeReferencePath(referencedFile);
|
||||
if (!isExternalModuleOrDeclarationFile(referencedFile)) {
|
||||
// Emit reference in dts, if the file reference was not already emitted
|
||||
if (referencedFile && !contains(emittedReferencedFiles, referencedFile)) {
|
||||
// Add a reference to generated dts file,
|
||||
// global file reference is added only
|
||||
// - if it is not bundled emit (because otherwise it would be self reference)
|
||||
// - and it is not already added
|
||||
if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference)) {
|
||||
addedGlobalFileReference = true;
|
||||
}
|
||||
emittedReferencedFiles.push(referencedFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
emitSourceFile(root);
|
||||
if (!isBundledEmit || !isExternalModule(sourceFile)) {
|
||||
noDeclare = false;
|
||||
emitSourceFile(sourceFile);
|
||||
}
|
||||
else if (isExternalModule(sourceFile)) {
|
||||
noDeclare = true;
|
||||
write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`);
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
emitSourceFile(sourceFile);
|
||||
decreaseIndent();
|
||||
write("}");
|
||||
writeLine();
|
||||
}
|
||||
|
||||
// create asynchronous output for the importDeclarations
|
||||
if (moduleElementDeclarationEmitInfo.length) {
|
||||
const oldWriter = writer;
|
||||
forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => {
|
||||
if (aliasEmitInfo.isVisible) {
|
||||
if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
|
||||
Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration);
|
||||
createAndSetNewTextWriterWithSymbolWriter();
|
||||
Debug.assert(aliasEmitInfo.indent === 0);
|
||||
Debug.assert(aliasEmitInfo.indent === 0 || (aliasEmitInfo.indent === 1 && isBundledEmit));
|
||||
for (let i = 0; i < aliasEmitInfo.indent; i++) {
|
||||
increaseIndent();
|
||||
}
|
||||
writeImportDeclaration(<ImportDeclaration>aliasEmitInfo.node);
|
||||
aliasEmitInfo.asynchronousOutput = writer.getText();
|
||||
for (let i = 0; i < aliasEmitInfo.indent; i++) {
|
||||
decreaseIndent();
|
||||
}
|
||||
}
|
||||
});
|
||||
setWriter(oldWriter);
|
||||
|
||||
allSourcesModuleElementDeclarationEmitInfo = allSourcesModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
|
||||
moduleElementDeclarationEmitInfo = [];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Emit references corresponding to this file
|
||||
const emittedReferencedFiles: SourceFile[] = [];
|
||||
let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (!isDeclarationFile(sourceFile)) {
|
||||
// Check what references need to be added
|
||||
if (!compilerOptions.noResolve) {
|
||||
forEach(sourceFile.referencedFiles, fileReference => {
|
||||
const referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
|
||||
|
||||
// If the reference file is a declaration file, emit that reference
|
||||
if (referencedFile && (isDeclarationFile(referencedFile) &&
|
||||
!contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted
|
||||
|
||||
writeReferencePath(referencedFile);
|
||||
emittedReferencedFiles.push(referencedFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
|
||||
noDeclare = false;
|
||||
emitSourceFile(sourceFile);
|
||||
}
|
||||
else if (isExternalModule(sourceFile)) {
|
||||
noDeclare = true;
|
||||
write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`);
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
emitSourceFile(sourceFile);
|
||||
decreaseIndent();
|
||||
write("}");
|
||||
writeLine();
|
||||
|
||||
// create asynchronous output for the importDeclarations
|
||||
if (moduleElementDeclarationEmitInfo.length) {
|
||||
const oldWriter = writer;
|
||||
forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => {
|
||||
if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) {
|
||||
Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration);
|
||||
createAndSetNewTextWriterWithSymbolWriter();
|
||||
Debug.assert(aliasEmitInfo.indent === 1);
|
||||
increaseIndent();
|
||||
writeImportDeclaration(<ImportDeclaration>aliasEmitInfo.node);
|
||||
aliasEmitInfo.asynchronousOutput = writer.getText();
|
||||
decreaseIndent();
|
||||
}
|
||||
});
|
||||
setWriter(oldWriter);
|
||||
}
|
||||
prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
|
||||
moduleElementDeclarationEmitInfo = [];
|
||||
}
|
||||
});
|
||||
moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
reportedDeclarationError,
|
||||
moduleElementDeclarationEmitInfo,
|
||||
moduleElementDeclarationEmitInfo: allSourcesModuleElementDeclarationEmitInfo,
|
||||
synchronousDeclarationOutput: writer.getText(),
|
||||
referencePathsOutput,
|
||||
};
|
||||
@@ -278,14 +255,14 @@ namespace ts {
|
||||
const errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
|
||||
if (errorInfo) {
|
||||
if (errorInfo.typeName) {
|
||||
diagnostics.push(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
|
||||
emitterDiagnostics.add(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
|
||||
errorInfo.diagnosticMessage,
|
||||
getTextOfNodeFromSourceText(currentText, errorInfo.typeName),
|
||||
symbolAccesibilityResult.errorSymbolName,
|
||||
symbolAccesibilityResult.errorModuleName));
|
||||
}
|
||||
else {
|
||||
diagnostics.push(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
|
||||
emitterDiagnostics.add(createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode,
|
||||
errorInfo.diagnosticMessage,
|
||||
symbolAccesibilityResult.errorSymbolName,
|
||||
symbolAccesibilityResult.errorModuleName));
|
||||
@@ -300,7 +277,8 @@ namespace ts {
|
||||
|
||||
function reportInaccessibleThisError() {
|
||||
if (errorNameNode) {
|
||||
diagnostics.push(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary,
|
||||
reportedDeclarationError = true;
|
||||
emitterDiagnostics.add(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary,
|
||||
declarationNameToString(errorNameNode)));
|
||||
}
|
||||
}
|
||||
@@ -378,8 +356,8 @@ namespace ts {
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.StringLiteralType:
|
||||
return writeTextOfNode(currentText, type);
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>type);
|
||||
@@ -680,7 +658,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
write("require(");
|
||||
writeTextOfNode(currentText, getExternalModuleImportEqualsDeclarationExpression(node));
|
||||
emitExternalModuleSpecifier(node);
|
||||
write(");");
|
||||
}
|
||||
writer.writeLine();
|
||||
@@ -737,14 +715,23 @@ namespace ts {
|
||||
}
|
||||
write(" from ");
|
||||
}
|
||||
emitExternalModuleSpecifier(node.moduleSpecifier);
|
||||
emitExternalModuleSpecifier(node);
|
||||
write(";");
|
||||
writer.writeLine();
|
||||
}
|
||||
|
||||
function emitExternalModuleSpecifier(moduleSpecifier: Expression) {
|
||||
if (moduleSpecifier.kind === SyntaxKind.StringLiteral && (!root) && (compilerOptions.out || compilerOptions.outFile)) {
|
||||
const moduleName = getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent as (ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration));
|
||||
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration) {
|
||||
let moduleSpecifier: Node;
|
||||
if (parent.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
const node = parent as ImportEqualsDeclaration;
|
||||
moduleSpecifier = getExternalModuleImportEqualsDeclarationExpression(node);
|
||||
}
|
||||
else {
|
||||
const node = parent as (ImportDeclaration | ExportDeclaration);
|
||||
moduleSpecifier = node.moduleSpecifier;
|
||||
}
|
||||
if (moduleSpecifier.kind === SyntaxKind.StringLiteral && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) {
|
||||
const moduleName = getExternalModuleNameFromDeclaration(host, resolver, parent);
|
||||
if (moduleName) {
|
||||
write("\"");
|
||||
write(moduleName);
|
||||
@@ -787,7 +774,7 @@ namespace ts {
|
||||
}
|
||||
if (node.moduleSpecifier) {
|
||||
write(" from ");
|
||||
emitExternalModuleSpecifier(node.moduleSpecifier);
|
||||
emitExternalModuleSpecifier(node);
|
||||
}
|
||||
write(";");
|
||||
writer.writeLine();
|
||||
@@ -1643,34 +1630,58 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function writeReferencePath(referencedFile: SourceFile) {
|
||||
let declFileName = referencedFile.flags & NodeFlags.DeclarationFile
|
||||
? referencedFile.fileName // Declaration file, use declaration file name
|
||||
: shouldEmitToOwnFile(referencedFile, compilerOptions)
|
||||
? getOwnEmitOutputFilePath(referencedFile, host, ".d.ts") // Own output file so get the .d.ts file
|
||||
: removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts"; // Global out file
|
||||
/**
|
||||
* Adds the reference to referenced file, returns true if global file reference was emitted
|
||||
* @param referencedFile
|
||||
* @param addBundledFileReference Determines if global file reference corresponding to bundled file should be emitted or not
|
||||
*/
|
||||
function writeReferencePath(referencedFile: SourceFile, addBundledFileReference: boolean): boolean {
|
||||
let declFileName: string;
|
||||
let addedBundledEmitReference = false;
|
||||
if (isDeclarationFile(referencedFile)) {
|
||||
// Declaration file, use declaration file name
|
||||
declFileName = referencedFile.fileName;
|
||||
}
|
||||
else {
|
||||
// Get the declaration file path
|
||||
forEachExpectedEmitFile(host, getDeclFileName, referencedFile);
|
||||
}
|
||||
|
||||
declFileName = getRelativePathToDirectoryOrUrl(
|
||||
getDirectoryPath(normalizeSlashes(jsFilePath)),
|
||||
declFileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ false);
|
||||
if (declFileName) {
|
||||
declFileName = getRelativePathToDirectoryOrUrl(
|
||||
getDirectoryPath(normalizeSlashes(declarationFilePath)),
|
||||
declFileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ false);
|
||||
|
||||
referencePathsOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
|
||||
referencePathsOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
|
||||
}
|
||||
return addedBundledEmitReference;
|
||||
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
|
||||
if (isBundledEmit && !addBundledFileReference) {
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.assert(!!emitFileNames.declarationFilePath || isSourceFileJavaScript(referencedFile), "Declaration file is not present only for javascript files");
|
||||
declFileName = emitFileNames.declarationFilePath || emitFileNames.jsFilePath;
|
||||
addedBundledEmitReference = isBundledEmit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function writeDeclarationFile(jsFilePath: string, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[]) {
|
||||
const emitDeclarationResult = emitDeclarations(host, resolver, diagnostics, jsFilePath, sourceFile);
|
||||
// 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
|
||||
if (!emitDeclarationResult.reportedDeclarationError) {
|
||||
export function writeDeclarationFile(declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection) {
|
||||
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit);
|
||||
const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
|
||||
if (!emitSkipped) {
|
||||
const declarationOutput = emitDeclarationResult.referencePathsOutput
|
||||
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
|
||||
writeFile(host, diagnostics, removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, host.getCompilerOptions().emitBOM);
|
||||
writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM);
|
||||
}
|
||||
return emitSkipped;
|
||||
|
||||
function getDeclarationOutput(synchronousDeclarationOutput: string, moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[]) {
|
||||
let appliedSyncOutputPos = 0;
|
||||
|
||||
@@ -783,6 +783,14 @@
|
||||
"category": "Error",
|
||||
"code": 1245
|
||||
},
|
||||
"An interface property cannot have an initializer.": {
|
||||
"category": "Error",
|
||||
"code": 1246
|
||||
},
|
||||
"A type literal property cannot have an initializer.": {
|
||||
"category": "Error",
|
||||
"code": 1247
|
||||
},
|
||||
|
||||
"'with' statements are not allowed in an async function block.": {
|
||||
"category": "Error",
|
||||
@@ -836,6 +844,10 @@
|
||||
"category": "Error",
|
||||
"code": 2307
|
||||
},
|
||||
"Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": {
|
||||
"category": "Error",
|
||||
"code": 2308
|
||||
},
|
||||
"An export assignment cannot be used in a module with other exported elements.": {
|
||||
"category": "Error",
|
||||
"code": 2309
|
||||
@@ -892,6 +904,10 @@
|
||||
"category": "Error",
|
||||
"code": 2322
|
||||
},
|
||||
"Cannot redeclare exported variable '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2323
|
||||
},
|
||||
"Property '{0}' is missing in type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2324
|
||||
@@ -1626,7 +1642,7 @@
|
||||
},
|
||||
"Cannot assign an abstract constructor type to a non-abstract constructor type.": {
|
||||
"category": "Error",
|
||||
"code":2517
|
||||
"code": 2517
|
||||
},
|
||||
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
|
||||
"category": "Error",
|
||||
@@ -1728,6 +1744,10 @@
|
||||
"category": "Error",
|
||||
"code": 2657
|
||||
},
|
||||
"Type '{0}' provides no match for the signature '{1}'": {
|
||||
"category": "Error",
|
||||
"code": 2658
|
||||
},
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
@@ -2064,6 +2084,22 @@
|
||||
"category": "Error",
|
||||
"code": 5054
|
||||
},
|
||||
"Cannot write file '{0}' because it would overwrite input file.": {
|
||||
"category": "Error",
|
||||
"code": 5055
|
||||
},
|
||||
"Cannot write file '{0}' because it would be overwritten by multiple input files.": {
|
||||
"category": "Error",
|
||||
"code": 5056
|
||||
},
|
||||
"Cannot find a tsconfig.json file at the specified directory: '{0}'": {
|
||||
"category": "Error",
|
||||
"code": 5057
|
||||
},
|
||||
"The specified path does not exist: '{0}'": {
|
||||
"category": "Error",
|
||||
"code": 5058
|
||||
},
|
||||
|
||||
"Concatenate and emit output to single file.": {
|
||||
"category": "Message",
|
||||
@@ -2105,6 +2141,10 @@
|
||||
"category": "Message",
|
||||
"code": 6010
|
||||
},
|
||||
"Allow default imports from modules with no default export. This does not affect code emit, just typechecking.": {
|
||||
"category": "Message",
|
||||
"code": 6011
|
||||
},
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015' (experimental)": {
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
@@ -2326,6 +2366,11 @@
|
||||
"category": "Error",
|
||||
"code": 6082
|
||||
},
|
||||
"Allow javascript files to be compiled.": {
|
||||
"category": "Message",
|
||||
"code": 6083
|
||||
},
|
||||
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@@ -2409,7 +2454,7 @@
|
||||
"Not all code paths return a value.": {
|
||||
"category": "Error",
|
||||
"code": 7030
|
||||
},
|
||||
},
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
"code": 8000
|
||||
|
||||
+289
-652
File diff suppressed because it is too large
Load Diff
+105
-70
@@ -544,6 +544,11 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguageVariant(fileName: string) {
|
||||
// .tsx and .jsx files are treated as jsx language variant.
|
||||
return fileExtensionIs(fileName, ".tsx") || fileExtensionIs(fileName, ".jsx") ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
}
|
||||
|
||||
function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, isJavaScriptFile: boolean, _syntaxCursor: IncrementalParser.SyntaxCursor) {
|
||||
NodeConstructor = objectAllocator.getNodeConstructor();
|
||||
SourceFileConstructor = objectAllocator.getSourceFileConstructor();
|
||||
@@ -564,7 +569,7 @@ namespace ts {
|
||||
scanner.setText(sourceText);
|
||||
scanner.setOnError(scanError);
|
||||
scanner.setScriptTarget(languageVersion);
|
||||
scanner.setLanguageVariant(allowsJsxExpressions(fileName) ? LanguageVariant.JSX : LanguageVariant.Standard);
|
||||
scanner.setLanguageVariant(getLanguageVariant(fileName));
|
||||
}
|
||||
|
||||
function clearState() {
|
||||
@@ -682,7 +687,7 @@ namespace ts {
|
||||
sourceFile.languageVersion = languageVersion;
|
||||
sourceFile.fileName = normalizePath(fileName);
|
||||
sourceFile.flags = fileExtensionIs(sourceFile.fileName, ".d.ts") ? NodeFlags.DeclarationFile : 0;
|
||||
sourceFile.languageVariant = allowsJsxExpressions(sourceFile.fileName) ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
sourceFile.languageVariant = getLanguageVariant(sourceFile.fileName);
|
||||
|
||||
return sourceFile;
|
||||
}
|
||||
@@ -722,10 +727,10 @@ namespace ts {
|
||||
const contextFlagsToClear = context & contextFlags;
|
||||
if (contextFlagsToClear) {
|
||||
// clear the requested context flags
|
||||
setContextFlag(false, contextFlagsToClear);
|
||||
setContextFlag(/*val*/ false, contextFlagsToClear);
|
||||
const result = func();
|
||||
// restore the context flags we just cleared
|
||||
setContextFlag(true, contextFlagsToClear);
|
||||
setContextFlag(/*val*/ true, contextFlagsToClear);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -743,10 +748,10 @@ namespace ts {
|
||||
const contextFlagsToSet = context & ~contextFlags;
|
||||
if (contextFlagsToSet) {
|
||||
// set the requested context flags
|
||||
setContextFlag(true, contextFlagsToSet);
|
||||
setContextFlag(/*val*/ true, contextFlagsToSet);
|
||||
const result = func();
|
||||
// reset the context flags we just set
|
||||
setContextFlag(false, contextFlagsToSet);
|
||||
setContextFlag(/*val*/ false, contextFlagsToSet);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1098,11 +1103,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parsePropertyName(): PropertyName {
|
||||
return parsePropertyNameWorker(/*allowComputedPropertyNames:*/ true);
|
||||
return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
|
||||
}
|
||||
|
||||
function parseSimplePropertyName(): Identifier | LiteralExpression {
|
||||
return <Identifier | LiteralExpression>parsePropertyNameWorker(/*allowComputedPropertyNames:*/ false);
|
||||
return <Identifier | LiteralExpression>parsePropertyNameWorker(/*allowComputedPropertyNames*/ false);
|
||||
}
|
||||
|
||||
function isSimplePropertyName() {
|
||||
@@ -1157,7 +1162,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseAnyContextualModifier(): boolean {
|
||||
return isModifier(token) && tryParse(nextTokenCanFollowModifier);
|
||||
return isModifierKind(token) && tryParse(nextTokenCanFollowModifier);
|
||||
}
|
||||
|
||||
function canFollowModifier(): boolean {
|
||||
@@ -1385,7 +1390,7 @@ namespace ts {
|
||||
function isInSomeParsingContext(): boolean {
|
||||
for (let kind = 0; kind < ParsingContext.Count; kind++) {
|
||||
if (parsingContext & (1 << kind)) {
|
||||
if (isListElement(kind, /* inErrorRecovery */ true) || isListTerminator(kind)) {
|
||||
if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1402,7 +1407,7 @@ namespace ts {
|
||||
result.pos = getNodePos();
|
||||
|
||||
while (!isListTerminator(kind)) {
|
||||
if (isListElement(kind, /* inErrorRecovery */ false)) {
|
||||
if (isListElement(kind, /*inErrorRecovery*/ false)) {
|
||||
const element = parseListElement(kind, parseElement);
|
||||
result.push(element);
|
||||
|
||||
@@ -1751,7 +1756,7 @@ namespace ts {
|
||||
|
||||
let commaStart = -1; // Meaning the previous token was not a comma
|
||||
while (true) {
|
||||
if (isListElement(kind, /* inErrorRecovery */ false)) {
|
||||
if (isListElement(kind, /*inErrorRecovery*/ false)) {
|
||||
result.push(parseListElement(kind, parseElement));
|
||||
commaStart = scanner.getTokenPos();
|
||||
if (parseOptional(SyntaxKind.CommaToken)) {
|
||||
@@ -1859,7 +1864,7 @@ namespace ts {
|
||||
// Report that we need an identifier. However, report it right after the dot,
|
||||
// and not on the next token. This is because the next token might actually
|
||||
// be an identifier and the error would be quite confusing.
|
||||
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentToken*/ true, Diagnostics.Identifier_expected);
|
||||
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1869,7 +1874,7 @@ namespace ts {
|
||||
function parseTemplateExpression(): TemplateExpression {
|
||||
const template = <TemplateExpression>createNode(SyntaxKind.TemplateExpression);
|
||||
|
||||
template.head = parseLiteralNode();
|
||||
template.head = parseTemplateLiteralFragment();
|
||||
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
|
||||
const templateSpans = <NodeArray<TemplateSpan>>[];
|
||||
@@ -1890,22 +1895,34 @@ namespace ts {
|
||||
const span = <TemplateSpan>createNode(SyntaxKind.TemplateSpan);
|
||||
span.expression = allowInAnd(parseExpression);
|
||||
|
||||
let literal: LiteralExpression;
|
||||
let literal: TemplateLiteralFragment;
|
||||
|
||||
if (token === SyntaxKind.CloseBraceToken) {
|
||||
reScanTemplateToken();
|
||||
literal = parseLiteralNode();
|
||||
literal = parseTemplateLiteralFragment();
|
||||
}
|
||||
else {
|
||||
literal = <LiteralExpression>parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
|
||||
literal = <TemplateLiteralFragment>parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
|
||||
}
|
||||
|
||||
span.literal = literal;
|
||||
return finishNode(span);
|
||||
}
|
||||
|
||||
function parseStringLiteralTypeNode(): StringLiteralTypeNode {
|
||||
return <StringLiteralTypeNode>parseLiteralLikeNode(SyntaxKind.StringLiteralType, /*internName*/ true);
|
||||
}
|
||||
|
||||
function parseLiteralNode(internName?: boolean): LiteralExpression {
|
||||
const node = <LiteralExpression>createNode(token);
|
||||
return <LiteralExpression>parseLiteralLikeNode(token, internName);
|
||||
}
|
||||
|
||||
function parseTemplateLiteralFragment(): TemplateLiteralFragment {
|
||||
return <TemplateLiteralFragment>parseLiteralLikeNode(token, /*internName*/ false);
|
||||
}
|
||||
|
||||
function parseLiteralLikeNode(kind: SyntaxKind, internName: boolean): LiteralLikeNode {
|
||||
const node = <LiteralExpression>createNode(kind);
|
||||
const text = scanner.getTokenValue();
|
||||
node.text = internName ? internIdentifier(text) : text;
|
||||
|
||||
@@ -1956,6 +1973,12 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseThisTypeNode(): TypeNode {
|
||||
const node = <TypeNode>createNode(SyntaxKind.ThisType);
|
||||
nextToken();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseTypeQuery(): TypeQueryNode {
|
||||
const node = <TypeQueryNode>createNode(SyntaxKind.TypeQuery);
|
||||
parseExpected(SyntaxKind.TypeOfKeyword);
|
||||
@@ -2004,7 +2027,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isStartOfParameter(): boolean {
|
||||
return token === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifier(token) || token === SyntaxKind.AtToken;
|
||||
return token === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifierKind(token) || token === SyntaxKind.AtToken;
|
||||
}
|
||||
|
||||
function setModifiers(node: Node, modifiers: ModifiersArray) {
|
||||
@@ -2025,7 +2048,7 @@ namespace ts {
|
||||
|
||||
node.name = parseIdentifierOrPattern();
|
||||
|
||||
if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifier(token)) {
|
||||
if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifierKind(token)) {
|
||||
// in cases like
|
||||
// 'use strict'
|
||||
// function foo(static)
|
||||
@@ -2132,8 +2155,8 @@ namespace ts {
|
||||
parseSemicolon();
|
||||
}
|
||||
|
||||
function parseSignatureMember(kind: SyntaxKind): SignatureDeclaration {
|
||||
const node = <SignatureDeclaration>createNode(kind);
|
||||
function parseSignatureMember(kind: SyntaxKind): CallSignatureDeclaration | ConstructSignatureDeclaration {
|
||||
const node = <CallSignatureDeclaration | ConstructSignatureDeclaration>createNode(kind);
|
||||
if (kind === SyntaxKind.ConstructSignature) {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
}
|
||||
@@ -2172,7 +2195,7 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isModifier(token)) {
|
||||
if (isModifierKind(token)) {
|
||||
nextToken();
|
||||
if (isIdentifier()) {
|
||||
return true;
|
||||
@@ -2215,13 +2238,13 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parsePropertyOrMethodSignature(): Declaration {
|
||||
function parsePropertyOrMethodSignature(): PropertySignature | MethodSignature {
|
||||
const fullStart = scanner.getStartPos();
|
||||
const name = parsePropertyName();
|
||||
const questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
||||
|
||||
if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
|
||||
const method = <MethodDeclaration>createNode(SyntaxKind.MethodSignature, fullStart);
|
||||
const method = <MethodSignature>createNode(SyntaxKind.MethodSignature, fullStart);
|
||||
method.name = name;
|
||||
method.questionToken = questionToken;
|
||||
|
||||
@@ -2232,10 +2255,18 @@ namespace ts {
|
||||
return finishNode(method);
|
||||
}
|
||||
else {
|
||||
const property = <PropertyDeclaration>createNode(SyntaxKind.PropertySignature, fullStart);
|
||||
const property = <PropertySignature>createNode(SyntaxKind.PropertySignature, fullStart);
|
||||
property.name = name;
|
||||
property.questionToken = questionToken;
|
||||
property.type = parseTypeAnnotation();
|
||||
|
||||
if (token === SyntaxKind.EqualsToken) {
|
||||
// Although type literal properties cannot not have initializers, we attempt
|
||||
// to parse an initializer so we can report in the checker that an interface
|
||||
// property or type literal property cannot have an initializer.
|
||||
property.initializer = parseNonParameterInitializer();
|
||||
}
|
||||
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(property);
|
||||
}
|
||||
@@ -2248,7 +2279,7 @@ namespace ts {
|
||||
case SyntaxKind.OpenBracketToken: // Both for indexers and computed properties
|
||||
return true;
|
||||
default:
|
||||
if (isModifier(token)) {
|
||||
if (isModifierKind(token)) {
|
||||
const result = lookAhead(isStartOfIndexSignatureDeclaration);
|
||||
if (result) {
|
||||
return result;
|
||||
@@ -2260,7 +2291,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isStartOfIndexSignatureDeclaration() {
|
||||
while (isModifier(token)) {
|
||||
while (isModifierKind(token)) {
|
||||
nextToken();
|
||||
}
|
||||
|
||||
@@ -2276,7 +2307,7 @@ namespace ts {
|
||||
canParseSemicolon();
|
||||
}
|
||||
|
||||
function parseTypeMember(): Declaration {
|
||||
function parseTypeMember(): TypeElement {
|
||||
switch (token) {
|
||||
case SyntaxKind.OpenParenToken:
|
||||
case SyntaxKind.LessThanToken:
|
||||
@@ -2301,7 +2332,7 @@ namespace ts {
|
||||
// when incrementally parsing as the parser will produce the Index declaration
|
||||
// if it has the same text regardless of whether it is inside a class or an
|
||||
// object type.
|
||||
if (isModifier(token)) {
|
||||
if (isModifierKind(token)) {
|
||||
const result = tryParse(parseIndexSignatureWithModifiers);
|
||||
if (result) {
|
||||
return result;
|
||||
@@ -2334,14 +2365,14 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseObjectTypeMembers(): NodeArray<Declaration> {
|
||||
let members: NodeArray<Declaration>;
|
||||
function parseObjectTypeMembers(): NodeArray<TypeElement> {
|
||||
let members: NodeArray<TypeElement>;
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken)) {
|
||||
members = parseList(ParsingContext.TypeMembers, parseTypeMember);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
else {
|
||||
members = createMissingList<Declaration>();
|
||||
members = createMissingList<TypeElement>();
|
||||
}
|
||||
|
||||
return members;
|
||||
@@ -2386,10 +2417,11 @@ namespace ts {
|
||||
const node = tryParse(parseKeywordAndNoDot);
|
||||
return node || parseTypeReferenceOrTypePredicate();
|
||||
case SyntaxKind.StringLiteral:
|
||||
return <StringLiteral>parseLiteralNode(/*internName*/ true);
|
||||
return parseStringLiteralTypeNode();
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return parseTokenNode<TypeNode>();
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return parseThisTypeNode();
|
||||
case SyntaxKind.TypeOfKeyword:
|
||||
return parseTypeQuery();
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
@@ -2483,11 +2515,11 @@ namespace ts {
|
||||
// ( ...
|
||||
return true;
|
||||
}
|
||||
if (isIdentifier() || isModifier(token)) {
|
||||
if (isIdentifier() || isModifierKind(token)) {
|
||||
nextToken();
|
||||
if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken ||
|
||||
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken ||
|
||||
isIdentifier() || isModifier(token)) {
|
||||
isIdentifier() || isModifierKind(token)) {
|
||||
// ( id :
|
||||
// ( id ,
|
||||
// ( id ?
|
||||
@@ -2609,7 +2641,7 @@ namespace ts {
|
||||
// clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator
|
||||
const saveDecoratorContext = inDecoratorContext();
|
||||
if (saveDecoratorContext) {
|
||||
setDecoratorContext(false);
|
||||
setDecoratorContext(/*val*/ false);
|
||||
}
|
||||
|
||||
let expr = parseAssignmentExpressionOrHigher();
|
||||
@@ -2619,7 +2651,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (saveDecoratorContext) {
|
||||
setDecoratorContext(true);
|
||||
setDecoratorContext(/*val*/ true);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
@@ -2773,7 +2805,7 @@ namespace ts {
|
||||
node.parameters.pos = parameter.pos;
|
||||
node.parameters.end = parameter.end;
|
||||
|
||||
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, false, Diagnostics._0_expected, "=>");
|
||||
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>");
|
||||
node.body = parseArrowFunctionExpressionBody(/*isAsync*/ false);
|
||||
|
||||
return finishNode(node);
|
||||
@@ -2894,7 +2926,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// This *could* be a parenthesized arrow function.
|
||||
// Return Unknown to const the caller know.
|
||||
// Return Unknown to let the caller know.
|
||||
return Tristate.Unknown;
|
||||
}
|
||||
else {
|
||||
@@ -2993,7 +3025,7 @@ namespace ts {
|
||||
// user meant to supply a block. For example, if the user wrote:
|
||||
//
|
||||
// a =>
|
||||
// const v = 0;
|
||||
// let v = 0;
|
||||
// }
|
||||
//
|
||||
// they may be missing an open brace. Check to see if that's the case so we can
|
||||
@@ -3220,7 +3252,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Parse ES7 unary expression and await expression
|
||||
*
|
||||
*
|
||||
* ES7 UnaryExpression:
|
||||
* 1) SimpleUnaryExpression[?yield]
|
||||
* 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
|
||||
@@ -3573,7 +3605,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
|
||||
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
|
||||
scanJsxText();
|
||||
}
|
||||
node = <JsxSelfClosingElement>createNode(SyntaxKind.JsxSelfClosingElement, fullStart);
|
||||
@@ -3609,7 +3641,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*advance*/ false);
|
||||
parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*shouldAdvance*/ false);
|
||||
scanJsxText();
|
||||
}
|
||||
|
||||
@@ -3654,7 +3686,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
|
||||
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
|
||||
scanJsxText();
|
||||
}
|
||||
return finishNode(node);
|
||||
@@ -3973,7 +4005,7 @@ namespace ts {
|
||||
// function BindingIdentifier[opt](FormalParameters){ FunctionBody }
|
||||
const saveDecoratorContext = inDecoratorContext();
|
||||
if (saveDecoratorContext) {
|
||||
setDecoratorContext(false);
|
||||
setDecoratorContext(/*val*/ false);
|
||||
}
|
||||
|
||||
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression);
|
||||
@@ -3993,7 +4025,7 @@ namespace ts {
|
||||
node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
|
||||
|
||||
if (saveDecoratorContext) {
|
||||
setDecoratorContext(true);
|
||||
setDecoratorContext(/*val*/ true);
|
||||
}
|
||||
|
||||
return finishNode(node);
|
||||
@@ -4039,13 +4071,13 @@ namespace ts {
|
||||
// arrow function. The body of the function is not in [Decorator] context.
|
||||
const saveDecoratorContext = inDecoratorContext();
|
||||
if (saveDecoratorContext) {
|
||||
setDecoratorContext(false);
|
||||
setDecoratorContext(/*val*/ false);
|
||||
}
|
||||
|
||||
const block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
|
||||
|
||||
if (saveDecoratorContext) {
|
||||
setDecoratorContext(true);
|
||||
setDecoratorContext(/*val*/ true);
|
||||
}
|
||||
|
||||
setYieldContext(savedYieldContext);
|
||||
@@ -4720,7 +4752,7 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, asteriskToken: Node, name: DeclarationName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
|
||||
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
|
||||
const method = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, fullStart);
|
||||
method.decorators = decorators;
|
||||
setModifiers(method, modifiers);
|
||||
@@ -4734,7 +4766,7 @@ namespace ts {
|
||||
return finishNode(method);
|
||||
}
|
||||
|
||||
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, name: DeclarationName, questionToken: Node): ClassElement {
|
||||
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, name: PropertyName, questionToken: Node): ClassElement {
|
||||
const property = <PropertyDeclaration>createNode(SyntaxKind.PropertyDeclaration, fullStart);
|
||||
property.decorators = decorators;
|
||||
setModifiers(property, modifiers);
|
||||
@@ -4808,7 +4840,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
|
||||
while (isModifier(token)) {
|
||||
while (isModifierKind(token)) {
|
||||
idToken = token;
|
||||
// If the idToken is a class modifier (protected, private, public, and static), it is
|
||||
// certain that we are starting to parse class member. This allows better error recovery
|
||||
@@ -4878,7 +4910,7 @@ namespace ts {
|
||||
|
||||
if (!decorators) {
|
||||
decorators = <NodeArray<Decorator>>[];
|
||||
decorators.pos = scanner.getStartPos();
|
||||
decorators.pos = decoratorStart;
|
||||
}
|
||||
|
||||
const decorator = <Decorator>createNode(SyntaxKind.Decorator, decoratorStart);
|
||||
@@ -5018,8 +5050,8 @@ namespace ts {
|
||||
// implements is a future reserved word so
|
||||
// 'class implements' might mean either
|
||||
// - class expression with omitted name, 'implements' starts heritage clause
|
||||
// - class with name 'implements'
|
||||
// 'isImplementsClause' helps to disambiguate between these two cases
|
||||
// - class with name 'implements'
|
||||
// 'isImplementsClause' helps to disambiguate between these two cases
|
||||
return isIdentifier() && !isImplementsClause()
|
||||
? parseIdentifier()
|
||||
: undefined;
|
||||
@@ -5278,16 +5310,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseModuleSpecifier(): Expression {
|
||||
// We allow arbitrary expressions here, even though the grammar only allows string
|
||||
// literals. We check to ensure that it is only a string literal later in the grammar
|
||||
// walker.
|
||||
const result = parseExpression();
|
||||
// Ensure the string being required is in our 'identifier' table. This will ensure
|
||||
// that features like 'find refs' will look inside this file when search for its name.
|
||||
if (result.kind === SyntaxKind.StringLiteral) {
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
const result = parseLiteralNode();
|
||||
internIdentifier((<LiteralExpression>result).text);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
// We allow arbitrary expressions here, even though the grammar only allows string
|
||||
// literals. We check to ensure that it is only a string literal later in the grammar
|
||||
// check pass.
|
||||
return parseExpression();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseNamespaceImport(): NamespaceImport {
|
||||
@@ -5404,11 +5437,13 @@ namespace ts {
|
||||
// reference comment.
|
||||
while (true) {
|
||||
const kind = triviaScanner.scan();
|
||||
if (kind === SyntaxKind.WhitespaceTrivia || kind === SyntaxKind.NewLineTrivia || kind === SyntaxKind.MultiLineCommentTrivia) {
|
||||
continue;
|
||||
}
|
||||
if (kind !== SyntaxKind.SingleLineCommentTrivia) {
|
||||
break;
|
||||
if (isTrivia(kind)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
|
||||
@@ -6162,7 +6197,7 @@ namespace ts {
|
||||
if (sourceFile.statements.length === 0) {
|
||||
// If we don't have any statements in the current source file, then there's no real
|
||||
// way to incrementally parse. So just do a full parse instead.
|
||||
return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setNodeParents*/ true);
|
||||
return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true);
|
||||
}
|
||||
|
||||
// Make sure we're not trying to incrementally update a source file more than once. Once
|
||||
@@ -6226,7 +6261,7 @@ namespace ts {
|
||||
// inconsistent tree. Setting the parents on the new tree should be very fast. We
|
||||
// will immediately bail out of walking any subtrees when we can see that their parents
|
||||
// are already correct.
|
||||
const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true);
|
||||
const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+287
-58
@@ -14,10 +14,10 @@ namespace ts {
|
||||
|
||||
export const version = "1.8.0";
|
||||
|
||||
export function findConfigFile(searchPath: string): string {
|
||||
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean): string {
|
||||
let fileName = "tsconfig.json";
|
||||
while (true) {
|
||||
if (sys.fileExists(fileName)) {
|
||||
if (fileExists(fileName)) {
|
||||
return fileName;
|
||||
}
|
||||
const parentPath = getDirectoryPath(searchPath);
|
||||
@@ -42,24 +42,24 @@ namespace ts {
|
||||
: compilerOptions.module === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
|
||||
|
||||
switch (moduleResolution) {
|
||||
case ModuleResolutionKind.NodeJs: return nodeModuleNameResolver(moduleName, containingFile, host);
|
||||
case ModuleResolutionKind.NodeJs: return nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host);
|
||||
case ModuleResolutionKind.Classic: return classicNameResolver(moduleName, containingFile, compilerOptions, host);
|
||||
}
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
|
||||
const supportedExtensions = getSupportedExtensions(compilerOptions);
|
||||
if (getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
|
||||
const failedLookupLocations: string[] = [];
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
let resolvedFileName = loadNodeModuleFromFile(supportedJsExtensions, candidate, failedLookupLocations, host);
|
||||
let resolvedFileName = loadNodeModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host);
|
||||
|
||||
if (resolvedFileName) {
|
||||
return { resolvedModule: { resolvedFileName }, failedLookupLocations };
|
||||
}
|
||||
|
||||
resolvedFileName = loadNodeModuleFromDirectory(supportedJsExtensions, candidate, failedLookupLocations, host);
|
||||
resolvedFileName = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, host);
|
||||
return resolvedFileName
|
||||
? { resolvedModule: { resolvedFileName }, failedLookupLocations }
|
||||
: { resolvedModule: undefined, failedLookupLocations };
|
||||
@@ -122,12 +122,13 @@ namespace ts {
|
||||
if (baseName !== "node_modules") {
|
||||
const nodeModulesFolder = combinePaths(directory, "node_modules");
|
||||
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
|
||||
let result = loadNodeModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host);
|
||||
// Load only typescript files irrespective of allowJs option if loading from node modules
|
||||
let result = loadNodeModuleFromFile(supportedTypeScriptExtensions, candidate, failedLookupLocations, host);
|
||||
if (result) {
|
||||
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
|
||||
}
|
||||
|
||||
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, host);
|
||||
result = loadNodeModuleFromDirectory(supportedTypeScriptExtensions, candidate, failedLookupLocations, host);
|
||||
if (result) {
|
||||
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
|
||||
}
|
||||
@@ -162,10 +163,10 @@ namespace ts {
|
||||
const failedLookupLocations: string[] = [];
|
||||
|
||||
let referencedSourceFile: string;
|
||||
const extensions = compilerOptions.allowNonTsExtensions ? supportedJsExtensions : supportedExtensions;
|
||||
const supportedExtensions = getSupportedExtensions(compilerOptions);
|
||||
while (true) {
|
||||
searchName = normalizePath(combinePaths(searchPath, moduleName));
|
||||
referencedSourceFile = forEach(extensions, extension => {
|
||||
referencedSourceFile = forEach(supportedExtensions, extension => {
|
||||
if (extension === ".tsx" && !compilerOptions.jsx) {
|
||||
// resolve .tsx files only if jsx support is enabled
|
||||
// 'logical not' handles both undefined and None cases
|
||||
@@ -285,13 +286,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
|
||||
const diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
program.getGlobalDiagnostics(cancellationToken),
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
||||
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
diagnostics = diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
}
|
||||
|
||||
return sortAndDeduplicateDiagnostics(diagnostics);
|
||||
@@ -335,10 +336,13 @@ namespace ts {
|
||||
let classifiableNames: Map<string>;
|
||||
|
||||
let skipDefaultLib = options.noLib;
|
||||
const supportedExtensions = getSupportedExtensions(options);
|
||||
|
||||
const start = new Date().getTime();
|
||||
|
||||
host = host || createCompilerHost(options);
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createFileMap<boolean>(getCanonicalFileName);
|
||||
|
||||
const currentDirectory = host.getCurrentDirectory();
|
||||
const resolveModuleNamesWorker = host.resolveModuleNames
|
||||
@@ -358,29 +362,26 @@ namespace ts {
|
||||
(oldOptions.noResolve !== options.noResolve) ||
|
||||
(oldOptions.target !== options.target) ||
|
||||
(oldOptions.noLib !== options.noLib) ||
|
||||
(oldOptions.jsx !== options.jsx)) {
|
||||
(oldOptions.jsx !== options.jsx) ||
|
||||
(oldOptions.allowJs !== options.allowJs)) {
|
||||
oldProgram = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tryReuseStructureFromOldProgram()) {
|
||||
forEach(rootNames, name => processRootFile(name, false));
|
||||
forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false));
|
||||
// Do not process the default library if:
|
||||
// - The '--noLib' flag is used.
|
||||
// - A 'no-default-lib' reference comment is encountered in
|
||||
// processing the root files.
|
||||
if (!skipDefaultLib) {
|
||||
processRootFile(host.getDefaultLibFileName(options), true);
|
||||
processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
verifyCompilerOptions();
|
||||
|
||||
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
|
||||
oldProgram = undefined;
|
||||
|
||||
programTime += new Date().getTime() - start;
|
||||
|
||||
program = {
|
||||
getRootFileNames: () => rootNames,
|
||||
getSourceFile,
|
||||
@@ -394,7 +395,7 @@ namespace ts {
|
||||
getTypeChecker,
|
||||
getClassifiableNames,
|
||||
getDiagnosticsProducingTypeChecker,
|
||||
getCommonSourceDirectory: () => commonSourceDirectory,
|
||||
getCommonSourceDirectory,
|
||||
emit,
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
getNodeCount: () => getDiagnosticsProducingTypeChecker().getNodeCount(),
|
||||
@@ -403,8 +404,32 @@ namespace ts {
|
||||
getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(),
|
||||
getFileProcessingDiagnostics: () => fileProcessingDiagnostics
|
||||
};
|
||||
|
||||
verifyCompilerOptions();
|
||||
|
||||
programTime += new Date().getTime() - start;
|
||||
|
||||
return program;
|
||||
|
||||
function getCommonSourceDirectory() {
|
||||
if (typeof commonSourceDirectory === "undefined") {
|
||||
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
|
||||
// If a rootDir is specified and is valid use it as the commonSourceDirectory
|
||||
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
|
||||
}
|
||||
else {
|
||||
commonSourceDirectory = computeCommonSourceDirectory(files);
|
||||
}
|
||||
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
|
||||
// Make sure directory path ends with directory separator so this string can directly
|
||||
// used to replace with "" to get the relative path of the source file and the relative path doesn't
|
||||
// start with / making it rooted path
|
||||
commonSourceDirectory += directorySeparator;
|
||||
}
|
||||
}
|
||||
return commonSourceDirectory;
|
||||
}
|
||||
|
||||
function getClassifiableNames() {
|
||||
if (!classifiableNames) {
|
||||
// Initialize a checker so that all our files are bound.
|
||||
@@ -524,6 +549,7 @@ namespace ts {
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
writeFile: writeFileCallback || (
|
||||
(fileName, data, writeByteOrderMark, onError) => host.writeFile(fileName, data, writeByteOrderMark, onError)),
|
||||
isEmitBlocked,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -539,6 +565,10 @@ namespace ts {
|
||||
return runWithCancellationToken(() => emitWorker(this, sourceFile, writeFileCallback, cancellationToken));
|
||||
}
|
||||
|
||||
function isEmitBlocked(emitFileName: string): boolean {
|
||||
return hasEmitBlockingDiagnostics.contains(toPath(emitFileName, currentDirectory, getCanonicalFileName));
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken): EmitResult {
|
||||
// If the noEmitOnError flag is set, then check if we have any errors so far. If so,
|
||||
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
|
||||
@@ -636,7 +666,12 @@ namespace ts {
|
||||
|
||||
Debug.assert(!!sourceFile.bindDiagnostics);
|
||||
const bindDiagnostics = sourceFile.bindDiagnostics;
|
||||
const checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||
// For JavaScript files, we don't want to report the normal typescript semantic errors.
|
||||
// Instead, we just report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file.
|
||||
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ?
|
||||
getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) :
|
||||
typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
|
||||
@@ -644,6 +679,165 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getJavaScriptSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
walk(sourceFile);
|
||||
|
||||
return diagnostics;
|
||||
|
||||
function walk(node: Node): boolean {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
let classDeclaration = <ClassDeclaration>node;
|
||||
if (checkModifiers(classDeclaration.modifiers) ||
|
||||
checkTypeParameters(classDeclaration.typeParameters)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.HeritageClause:
|
||||
let heritageClause = <HeritageClause>node;
|
||||
if (heritageClause.token === SyntaxKind.ImplementsKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
const functionDeclaration = <FunctionLikeDeclaration>node;
|
||||
if (checkModifiers(functionDeclaration.modifiers) ||
|
||||
checkTypeParameters(functionDeclaration.typeParameters) ||
|
||||
checkTypeAnnotation(functionDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableStatement:
|
||||
const variableStatement = <VariableStatement>node;
|
||||
if (checkModifiers(variableStatement.modifiers)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
const variableDeclaration = <VariableDeclaration>node;
|
||||
if (checkTypeAnnotation(variableDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
const expression = <CallExpression>node;
|
||||
if (expression.typeArguments && expression.typeArguments.length > 0) {
|
||||
const start = expression.typeArguments.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, expression.typeArguments.end - start,
|
||||
Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
const parameter = <ParameterDeclaration>node;
|
||||
if (parameter.modifiers) {
|
||||
const start = parameter.modifiers.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, parameter.modifiers.end - start,
|
||||
Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
if (parameter.questionToken) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
|
||||
return true;
|
||||
}
|
||||
if (parameter.type) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.property_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
let typeAssertionExpression = <TypeAssertion>node;
|
||||
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.Decorator:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.decorators_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return forEachChild(node, walk);
|
||||
}
|
||||
|
||||
function checkTypeParameters(typeParameters: NodeArray<TypeParameterDeclaration>): boolean {
|
||||
if (typeParameters) {
|
||||
const start = typeParameters.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, typeParameters.end - start, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkTypeAnnotation(type: TypeNode): boolean {
|
||||
if (type) {
|
||||
diagnostics.push(createDiagnosticForNode(type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkModifiers(modifiers: ModifiersArray): boolean {
|
||||
if (modifiers) {
|
||||
for (const modifier of modifiers) {
|
||||
switch (modifier.kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
return true;
|
||||
|
||||
// These are all legal modifiers.
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
if (!isDeclarationFile(sourceFile)) {
|
||||
@@ -693,7 +887,7 @@ namespace ts {
|
||||
|
||||
let imports: LiteralExpression[];
|
||||
for (const node of file.statements) {
|
||||
collect(node, /* allowRelativeModuleNames */ true, /* collectOnlyRequireCalls */ false);
|
||||
collect(node, /*allowRelativeModuleNames*/ true, /*collectOnlyRequireCalls*/ false);
|
||||
}
|
||||
|
||||
file.imports = imports || emptyArray;
|
||||
@@ -729,7 +923,7 @@ namespace ts {
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
|
||||
// only through top - level external module names. Relative external module names are not permitted.
|
||||
collect(node, /* allowRelativeModuleNames */ false, collectOnlyRequireCalls);
|
||||
collect(node, /*allowRelativeModuleNames*/ false, collectOnlyRequireCalls);
|
||||
});
|
||||
}
|
||||
break;
|
||||
@@ -741,7 +935,7 @@ namespace ts {
|
||||
(imports || (imports = [])).push(<StringLiteral>(<CallExpression>node).arguments[0]);
|
||||
}
|
||||
else {
|
||||
forEachChild(node, node => collect(node, allowRelativeModuleNames, /* collectOnlyRequireCalls */ true));
|
||||
forEachChild(node, node => collect(node, allowRelativeModuleNames, /*collectOnlyRequireCalls*/ true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -800,12 +994,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Get source file from normalized fileName
|
||||
function findSourceFile(fileName: string, normalizedAbsolutePath: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
|
||||
if (filesByName.contains(normalizedAbsolutePath)) {
|
||||
const file = filesByName.get(normalizedAbsolutePath);
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
|
||||
if (filesByName.contains(path)) {
|
||||
const file = filesByName.get(path);
|
||||
// try to check if we've already seen this file but with a different casing in path
|
||||
// NOTE: this only makes sense for case-insensitive file systems
|
||||
if (file && options.forceConsistentCasingInFileNames && getNormalizedAbsolutePath(file.fileName, currentDirectory) !== normalizedAbsolutePath) {
|
||||
if (file && options.forceConsistentCasingInFileNames && getNormalizedAbsolutePath(file.fileName, currentDirectory) !== getNormalizedAbsolutePath(fileName, currentDirectory)) {
|
||||
reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd);
|
||||
}
|
||||
|
||||
@@ -823,18 +1017,18 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
|
||||
filesByName.set(normalizedAbsolutePath, file);
|
||||
filesByName.set(path, file);
|
||||
if (file) {
|
||||
file.path = normalizedAbsolutePath;
|
||||
file.path = path;
|
||||
|
||||
if (host.useCaseSensitiveFileNames()) {
|
||||
// for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
|
||||
const existingFile = filesByNameIgnoreCase.get(normalizedAbsolutePath);
|
||||
const existingFile = filesByNameIgnoreCase.get(path);
|
||||
if (existingFile) {
|
||||
reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
|
||||
}
|
||||
else {
|
||||
filesByNameIgnoreCase.set(normalizedAbsolutePath, file);
|
||||
filesByNameIgnoreCase.set(path, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,7 +1056,7 @@ namespace ts {
|
||||
function processReferencedFiles(file: SourceFile, basePath: string) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
||||
processSourceFile(referencedFileName, /* isDefaultLib */ false, file, ref.pos, ref.end);
|
||||
processSourceFile(referencedFileName, /*isDefaultLib*/ false, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -880,9 +1074,11 @@ namespace ts {
|
||||
const resolution = resolutions[i];
|
||||
setResolvedModule(file, moduleNames[i], resolution);
|
||||
if (resolution && !options.noResolve) {
|
||||
const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /* isDefaultLib */ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end);
|
||||
const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end);
|
||||
|
||||
if (importedFile && resolution.isExternalLibraryImport) {
|
||||
// Since currently irrespective of allowJs, we only look for supportedTypeScript extension external module files,
|
||||
// this check is ok. Otherwise this would be never true for javascript file
|
||||
if (!isExternalModule(importedFile)) {
|
||||
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));
|
||||
@@ -904,7 +1100,7 @@ namespace ts {
|
||||
|
||||
function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string {
|
||||
let commonPathComponents: string[];
|
||||
forEach(files, sourceFile => {
|
||||
const failed = forEach(files, sourceFile => {
|
||||
// Each file contributes into common source file path
|
||||
if (isDeclarationFile(sourceFile)) {
|
||||
return;
|
||||
@@ -920,10 +1116,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
for (let i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); i < n; i++) {
|
||||
if (commonPathComponents[i] !== sourcePathComponents[i]) {
|
||||
if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
|
||||
if (i === 0) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
|
||||
return;
|
||||
// Failed to find any common path component
|
||||
return true;
|
||||
}
|
||||
|
||||
// New common path found that is 0 -> i-1
|
||||
@@ -938,6 +1134,11 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
|
||||
// A common path can not be found when paths span multiple drives on windows, for example
|
||||
if (failed) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!commonPathComponents) { // Can happen when all input files are .d.ts files
|
||||
return currentDirectory;
|
||||
}
|
||||
@@ -990,16 +1191,15 @@ namespace ts {
|
||||
if (options.mapRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"));
|
||||
}
|
||||
if (options.sourceRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceRoot", "inlineSourceMap"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (options.inlineSources) {
|
||||
if (!options.sourceMap && !options.inlineSourceMap) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided));
|
||||
}
|
||||
if (options.sourceRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceRoot", "inlineSources"));
|
||||
}
|
||||
}
|
||||
|
||||
if (options.out && options.outFile) {
|
||||
@@ -1011,10 +1211,9 @@ namespace ts {
|
||||
if (options.mapRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap"));
|
||||
}
|
||||
if (options.sourceRoot) {
|
||||
if (options.sourceRoot && !options.inlineSourceMap) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "sourceRoot", "sourceMap"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const languageVersion = options.target || ScriptTarget.ES3;
|
||||
@@ -1054,20 +1253,12 @@ namespace ts {
|
||||
options.sourceRoot || // there is --sourceRoot specified
|
||||
options.mapRoot) { // there is --mapRoot specified
|
||||
|
||||
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
|
||||
// If a rootDir is specified and is valid use it as the commonSourceDirectory
|
||||
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
|
||||
}
|
||||
else {
|
||||
// Compute the commonSourceDirectory from the input files
|
||||
commonSourceDirectory = computeCommonSourceDirectory(files);
|
||||
}
|
||||
// Precalculate and cache the common source directory
|
||||
const dir = getCommonSourceDirectory();
|
||||
|
||||
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
|
||||
// Make sure directory path ends with directory separator so this string can directly
|
||||
// used to replace with "" to get the relative path of the source file and the relative path doesn't
|
||||
// start with / making it rooted path
|
||||
commonSourceDirectory += directorySeparator;
|
||||
// If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
|
||||
if (options.outDir && dir === "" && forEach(files, file => getRootLength(file.fileName) > 1)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1088,11 +1279,49 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "declaration"));
|
||||
}
|
||||
}
|
||||
else if (options.allowJs && options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"));
|
||||
}
|
||||
|
||||
if (options.emitDecoratorMetadata &&
|
||||
!options.experimentalDecorators) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
|
||||
}
|
||||
|
||||
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
|
||||
if (!options.noEmit) {
|
||||
const emitHost = getEmitHost();
|
||||
const emitFilesSeen = createFileMap<boolean>(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined);
|
||||
forEachExpectedEmitFile(emitHost, (emitFileNames, sourceFiles, isBundledEmit) => {
|
||||
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
|
||||
verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
|
||||
});
|
||||
}
|
||||
|
||||
// Verify that all the emit files are unique and don't overwrite input files
|
||||
function verifyEmitFilePath(emitFileName: string, emitFilesSeen: FileMap<boolean>) {
|
||||
if (emitFileName) {
|
||||
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
|
||||
// Report error if the output overwrites input file
|
||||
if (filesByName.contains(emitFilePath)) {
|
||||
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
|
||||
}
|
||||
|
||||
// Report error if multiple files write into same file
|
||||
if (emitFilesSeen.contains(emitFilePath)) {
|
||||
// Already seen the same emit file - report error
|
||||
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
|
||||
}
|
||||
else {
|
||||
emitFilesSeen.set(emitFilePath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createEmitBlockingDiagnostics(emitFileName: string, emitFilePath: Path, message: DiagnosticMessage) {
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-4
@@ -425,6 +425,12 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number {
|
||||
// Using ! with a greater than test is a fast way of testing the following conditions:
|
||||
// pos === undefined || pos === null || isNaN(pos) || pos < 0;
|
||||
if (!(pos >= 0)) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Keep in sync with couldStartTrivia
|
||||
while (true) {
|
||||
const ch = text.charCodeAt(pos);
|
||||
@@ -567,12 +573,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract comments from text prefixing the token closest following `pos`.
|
||||
* Extract comments from text prefixing the token closest following `pos`.
|
||||
* The return value is an array containing a TextRange for each comment.
|
||||
* Single-line comment ranges include the beginning '//' characters but not the ending line break.
|
||||
* Multi - line comment ranges include the beginning '/* and ending '<asterisk>/' characters.
|
||||
* The return value is undefined if no comments were found.
|
||||
* @param trailing
|
||||
* @param trailing
|
||||
* If false, whitespace is skipped until the first line break and comments between that location
|
||||
* and the next token are returned.
|
||||
* If true, comments occurring between the given position and the next line break are returned.
|
||||
@@ -1634,11 +1640,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function lookAhead<T>(callback: () => T): T {
|
||||
return speculationHelper(callback, /*isLookahead:*/ true);
|
||||
return speculationHelper(callback, /*isLookahead*/ true);
|
||||
}
|
||||
|
||||
function tryScan<T>(callback: () => T): T {
|
||||
return speculationHelper(callback, /*isLookahead:*/ false);
|
||||
return speculationHelper(callback, /*isLookahead*/ false);
|
||||
}
|
||||
|
||||
function setText(newText: string, start: number, length: number) {
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
/// <reference path="checker.ts"/>
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface SourceMapWriter {
|
||||
getSourceMapData(): SourceMapData;
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
emitPos(pos: number): void;
|
||||
emitStart(range: TextRange): void;
|
||||
emitEnd(range: TextRange): void;
|
||||
getText(): string;
|
||||
getSourceMappingURL(): string;
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
const nop = <(...args: any[]) => any>Function.prototype;
|
||||
let nullSourceMapWriter: SourceMapWriter;
|
||||
|
||||
export function getNullSourceMapWriter(): SourceMapWriter {
|
||||
if (nullSourceMapWriter === undefined) {
|
||||
nullSourceMapWriter = {
|
||||
getSourceMapData(): SourceMapData { return undefined; },
|
||||
setSourceFile(sourceFile: SourceFile): void { },
|
||||
emitStart(range: TextRange): void { },
|
||||
emitEnd(range: TextRange): void { },
|
||||
emitPos(pos: number): void { },
|
||||
getText(): string { return undefined; },
|
||||
getSourceMappingURL(): string { return undefined; },
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void { },
|
||||
reset(): void { },
|
||||
};
|
||||
}
|
||||
|
||||
return nullSourceMapWriter;
|
||||
}
|
||||
|
||||
export function createSourceMapWriter(host: EmitHost, writer: EmitTextWriter): SourceMapWriter {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
let currentSourceFile: SourceFile;
|
||||
let sourceMapDir: string; // The directory in which sourcemap will be
|
||||
|
||||
// Current source map file and its index in the sources list
|
||||
let sourceMapSourceIndex: number;
|
||||
|
||||
// Last recorded and encoded spans
|
||||
let lastRecordedSourceMapSpan: SourceMapSpan;
|
||||
let lastEncodedSourceMapSpan: SourceMapSpan;
|
||||
let lastEncodedNameIndex: number;
|
||||
|
||||
// Source map data
|
||||
let sourceMapData: SourceMapData;
|
||||
|
||||
return {
|
||||
getSourceMapData: () => sourceMapData,
|
||||
setSourceFile,
|
||||
emitPos,
|
||||
emitStart,
|
||||
emitEnd,
|
||||
getText,
|
||||
getSourceMappingURL,
|
||||
initialize,
|
||||
reset,
|
||||
};
|
||||
|
||||
function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
if (sourceMapData) {
|
||||
reset();
|
||||
}
|
||||
|
||||
currentSourceFile = undefined;
|
||||
|
||||
// Current source map file and its index in the sources list
|
||||
sourceMapSourceIndex = -1;
|
||||
|
||||
// Last recorded and encoded spans
|
||||
lastRecordedSourceMapSpan = undefined;
|
||||
lastEncodedSourceMapSpan = {
|
||||
emittedLine: 1,
|
||||
emittedColumn: 1,
|
||||
sourceLine: 1,
|
||||
sourceColumn: 1,
|
||||
sourceIndex: 0
|
||||
};
|
||||
lastEncodedNameIndex = 0;
|
||||
|
||||
// Initialize source map data
|
||||
sourceMapData = {
|
||||
sourceMapFilePath: sourceMapFilePath,
|
||||
jsSourceMappingURL: !compilerOptions.inlineSourceMap ? getBaseFileName(normalizeSlashes(sourceMapFilePath)) : undefined,
|
||||
sourceMapFile: getBaseFileName(normalizeSlashes(filePath)),
|
||||
sourceMapSourceRoot: compilerOptions.sourceRoot || "",
|
||||
sourceMapSources: [],
|
||||
inputSourceFileNames: [],
|
||||
sourceMapNames: [],
|
||||
sourceMapMappings: "",
|
||||
sourceMapSourcesContent: compilerOptions.inlineSources ? [] : undefined,
|
||||
sourceMapDecodedMappings: []
|
||||
};
|
||||
|
||||
// Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
|
||||
// relative paths of the sources list in the sourcemap
|
||||
sourceMapData.sourceMapSourceRoot = ts.normalizeSlashes(sourceMapData.sourceMapSourceRoot);
|
||||
if (sourceMapData.sourceMapSourceRoot.length && sourceMapData.sourceMapSourceRoot.charCodeAt(sourceMapData.sourceMapSourceRoot.length - 1) !== CharacterCodes.slash) {
|
||||
sourceMapData.sourceMapSourceRoot += directorySeparator;
|
||||
}
|
||||
|
||||
if (compilerOptions.mapRoot) {
|
||||
sourceMapDir = normalizeSlashes(compilerOptions.mapRoot);
|
||||
if (!isBundledEmit) { // emitting single module file
|
||||
Debug.assert(sourceFiles.length === 1);
|
||||
// For modules or multiple emit files the mapRoot will have directory structure like the sources
|
||||
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
|
||||
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFiles[0], host, sourceMapDir));
|
||||
}
|
||||
|
||||
if (!isRootedDiskPath(sourceMapDir) && !isUrl(sourceMapDir)) {
|
||||
// The relative paths are relative to the common directory
|
||||
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
|
||||
sourceMapData.jsSourceMappingURL = getRelativePathToDirectoryOrUrl(
|
||||
getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
|
||||
combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true);
|
||||
}
|
||||
else {
|
||||
sourceMapData.jsSourceMappingURL = combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sourceMapDir = getDirectoryPath(normalizePath(filePath));
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
currentSourceFile = undefined;
|
||||
sourceMapDir = undefined;
|
||||
sourceMapSourceIndex = undefined;
|
||||
lastRecordedSourceMapSpan = undefined;
|
||||
lastEncodedSourceMapSpan = undefined;
|
||||
lastEncodedNameIndex = undefined;
|
||||
sourceMapData = undefined;
|
||||
}
|
||||
|
||||
// Encoding for sourcemap span
|
||||
function encodeLastRecordedSourceMapSpan() {
|
||||
if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) {
|
||||
return;
|
||||
}
|
||||
|
||||
let prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
|
||||
// Line/Comma delimiters
|
||||
if (lastEncodedSourceMapSpan.emittedLine === lastRecordedSourceMapSpan.emittedLine) {
|
||||
// Emit comma to separate the entry
|
||||
if (sourceMapData.sourceMapMappings) {
|
||||
sourceMapData.sourceMapMappings += ",";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Emit line delimiters
|
||||
for (let encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
|
||||
sourceMapData.sourceMapMappings += ";";
|
||||
}
|
||||
prevEncodedEmittedColumn = 1;
|
||||
}
|
||||
|
||||
// 1. Relative Column 0 based
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn);
|
||||
|
||||
// 2. Relative sourceIndex
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex);
|
||||
|
||||
// 3. Relative sourceLine 0 based
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine);
|
||||
|
||||
// 4. Relative sourceColumn 0 based
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn);
|
||||
|
||||
// 5. Relative namePosition 0 based
|
||||
if (lastRecordedSourceMapSpan.nameIndex >= 0) {
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
|
||||
lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
|
||||
}
|
||||
|
||||
lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
|
||||
sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
|
||||
}
|
||||
|
||||
function emitPos(pos: number) {
|
||||
if (pos === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceLinePos = getLineAndCharacterOfPosition(currentSourceFile, pos);
|
||||
|
||||
// Convert the location to be one-based.
|
||||
sourceLinePos.line++;
|
||||
sourceLinePos.character++;
|
||||
|
||||
const emittedLine = writer.getLine();
|
||||
const emittedColumn = writer.getColumn();
|
||||
|
||||
// If this location wasn't recorded or the location in source is going backwards, record the span
|
||||
if (!lastRecordedSourceMapSpan ||
|
||||
lastRecordedSourceMapSpan.emittedLine !== emittedLine ||
|
||||
lastRecordedSourceMapSpan.emittedColumn !== emittedColumn ||
|
||||
(lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex &&
|
||||
(lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
|
||||
(lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
|
||||
|
||||
// Encode the last recordedSpan before assigning new
|
||||
encodeLastRecordedSourceMapSpan();
|
||||
|
||||
// New span
|
||||
lastRecordedSourceMapSpan = {
|
||||
emittedLine: emittedLine,
|
||||
emittedColumn: emittedColumn,
|
||||
sourceLine: sourceLinePos.line,
|
||||
sourceColumn: sourceLinePos.character,
|
||||
sourceIndex: sourceMapSourceIndex
|
||||
};
|
||||
}
|
||||
else {
|
||||
// Take the new pos instead since there is no change in emittedLine and column since last location
|
||||
lastRecordedSourceMapSpan.sourceLine = sourceLinePos.line;
|
||||
lastRecordedSourceMapSpan.sourceColumn = sourceLinePos.character;
|
||||
lastRecordedSourceMapSpan.sourceIndex = sourceMapSourceIndex;
|
||||
}
|
||||
}
|
||||
|
||||
function emitStart(range: TextRange) {
|
||||
const rangeHasDecorators = !!(range as Node).decorators;
|
||||
emitPos(range.pos !== -1 ? skipTrivia(currentSourceFile.text, rangeHasDecorators ? (range as Node).decorators.end : range.pos) : -1);
|
||||
}
|
||||
|
||||
function emitEnd(range: TextRange) {
|
||||
emitPos(range.end);
|
||||
}
|
||||
|
||||
function setSourceFile(sourceFile: SourceFile) {
|
||||
currentSourceFile = sourceFile;
|
||||
|
||||
// Add the file to tsFilePaths
|
||||
// If sourceroot option: Use the relative path corresponding to the common directory path
|
||||
// otherwise source locations relative to map file location
|
||||
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
|
||||
|
||||
const source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
|
||||
currentSourceFile.fileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true);
|
||||
|
||||
sourceMapSourceIndex = indexOf(sourceMapData.sourceMapSources, source);
|
||||
if (sourceMapSourceIndex === -1) {
|
||||
sourceMapSourceIndex = sourceMapData.sourceMapSources.length;
|
||||
sourceMapData.sourceMapSources.push(source);
|
||||
|
||||
// The one that can be used from program to get the actual source file
|
||||
sourceMapData.inputSourceFileNames.push(sourceFile.fileName);
|
||||
|
||||
if (compilerOptions.inlineSources) {
|
||||
sourceMapData.sourceMapSourcesContent.push(sourceFile.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getText() {
|
||||
encodeLastRecordedSourceMapSpan();
|
||||
|
||||
return stringify({
|
||||
version: 3,
|
||||
file: sourceMapData.sourceMapFile,
|
||||
sourceRoot: sourceMapData.sourceMapSourceRoot,
|
||||
sources: sourceMapData.sourceMapSources,
|
||||
names: sourceMapData.sourceMapNames,
|
||||
mappings: sourceMapData.sourceMapMappings,
|
||||
sourcesContent: sourceMapData.sourceMapSourcesContent,
|
||||
});
|
||||
}
|
||||
|
||||
function getSourceMappingURL() {
|
||||
if (compilerOptions.inlineSourceMap) {
|
||||
// Encode the sourceMap into the sourceMap url
|
||||
const base64SourceMapText = convertToBase64(getText());
|
||||
return sourceMapData.jsSourceMappingURL = `data:application/json;base64,${base64SourceMapText}`;
|
||||
}
|
||||
else {
|
||||
return sourceMapData.jsSourceMappingURL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
function base64FormatEncode(inValue: number) {
|
||||
if (inValue < 64) {
|
||||
return base64Chars.charAt(inValue);
|
||||
}
|
||||
|
||||
throw TypeError(inValue + ": not a 64 based value");
|
||||
}
|
||||
|
||||
function base64VLQFormatEncode(inValue: number) {
|
||||
// Add a new least significant bit that has the sign of the value.
|
||||
// if negative number the least significant bit that gets added to the number has value 1
|
||||
// else least significant bit value that gets added is 0
|
||||
// eg. -1 changes to binary : 01 [1] => 3
|
||||
// +1 changes to binary : 01 [0] => 2
|
||||
if (inValue < 0) {
|
||||
inValue = ((-inValue) << 1) + 1;
|
||||
}
|
||||
else {
|
||||
inValue = inValue << 1;
|
||||
}
|
||||
|
||||
// Encode 5 bits at a time starting from least significant bits
|
||||
let encodedStr = "";
|
||||
do {
|
||||
let currentDigit = inValue & 31; // 11111
|
||||
inValue = inValue >> 5;
|
||||
if (inValue > 0) {
|
||||
// There are still more digits to decode, set the msb (6th bit)
|
||||
currentDigit = currentDigit | 32;
|
||||
}
|
||||
encodedStr = encodedStr + base64FormatEncode(currentDigit);
|
||||
} while (inValue > 0);
|
||||
|
||||
return encodedStr;
|
||||
}
|
||||
}
|
||||
+54
-2
@@ -47,6 +47,21 @@ namespace ts {
|
||||
constructor(o: any);
|
||||
}
|
||||
|
||||
declare var ChakraHost: {
|
||||
args: string[];
|
||||
currentDirectory: string;
|
||||
executingFile: string;
|
||||
echo(s: string): void;
|
||||
quit(exitCode?: number): void;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
resolvePath(path: string): string;
|
||||
readFile(path: string): string;
|
||||
writeFile(path: string, contents: string): void;
|
||||
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
|
||||
};
|
||||
|
||||
export var sys: System = (function () {
|
||||
|
||||
function getWScriptSystem(): System {
|
||||
@@ -194,6 +209,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getNodeSystem(): System {
|
||||
const _fs = require("fs");
|
||||
const _path = require("path");
|
||||
@@ -281,7 +297,7 @@ namespace ts {
|
||||
// REVIEW: for now this implementation uses polling.
|
||||
// The advantage of polling is that it works reliably
|
||||
// on all os and with network mounted files.
|
||||
// For 90 referenced files, the average time to detect
|
||||
// For 90 referenced files, the average time to detect
|
||||
// changes is 2*msInterval (by default 5 seconds).
|
||||
// The overhead of this is .04 percent (1/2500) with
|
||||
// average pause of < 1 millisecond (and max
|
||||
@@ -406,7 +422,7 @@ namespace ts {
|
||||
};
|
||||
},
|
||||
watchDirectory: (path, callback, recursive) => {
|
||||
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
|
||||
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
|
||||
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
|
||||
return _fs.watch(
|
||||
path,
|
||||
@@ -454,6 +470,37 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getChakraSystem(): System {
|
||||
|
||||
return {
|
||||
newLine: "\r\n",
|
||||
args: ChakraHost.args,
|
||||
useCaseSensitiveFileNames: false,
|
||||
write: ChakraHost.echo,
|
||||
readFile(path: string, encoding?: string) {
|
||||
// encoding is automatically handled by the implementation in ChakraHost
|
||||
return ChakraHost.readFile(path);
|
||||
},
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean) {
|
||||
// If a BOM is required, emit one
|
||||
if (writeByteOrderMark) {
|
||||
data = "\uFEFF" + data;
|
||||
}
|
||||
|
||||
ChakraHost.writeFile(path, data);
|
||||
},
|
||||
resolvePath: ChakraHost.resolvePath,
|
||||
fileExists: ChakraHost.fileExists,
|
||||
directoryExists: ChakraHost.directoryExists,
|
||||
createDirectory: ChakraHost.createDirectory,
|
||||
getExecutingFilePath: () => ChakraHost.executingFile,
|
||||
getCurrentDirectory: () => ChakraHost.currentDirectory,
|
||||
readDirectory: ChakraHost.readDirectory,
|
||||
exit: ChakraHost.quit,
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
|
||||
return getWScriptSystem();
|
||||
}
|
||||
@@ -462,8 +509,13 @@ namespace ts {
|
||||
// process.browser check excludes webpack and browserify
|
||||
return getNodeSystem();
|
||||
}
|
||||
else if (typeof ChakraHost !== "undefined") {
|
||||
return getChakraSystem();
|
||||
}
|
||||
else {
|
||||
return undefined; // Unsupported host
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+21
-6
@@ -280,7 +280,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (commandLine.options.version) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Version_0, ts.version), /* compilerHost */ undefined);
|
||||
printVersion();
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
@@ -295,15 +295,30 @@ namespace ts {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--project"), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
configFileName = normalizePath(combinePaths(commandLine.options.project, "tsconfig.json"));
|
||||
if (commandLine.fileNames.length !== 0) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
|
||||
const fileOrDirectory = normalizePath(commandLine.options.project);
|
||||
if (!fileOrDirectory /* current directory "." */ || sys.directoryExists(fileOrDirectory)) {
|
||||
configFileName = combinePaths(fileOrDirectory, "tsconfig.json");
|
||||
if (!sys.fileExists(configFileName)) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
}
|
||||
else {
|
||||
configFileName = fileOrDirectory;
|
||||
if (!sys.fileExists(configFileName)) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
|
||||
const searchPath = normalizePath(sys.getCurrentDirectory());
|
||||
configFileName = findConfigFile(searchPath);
|
||||
configFileName = findConfigFile(searchPath, sys.fileExists);
|
||||
}
|
||||
|
||||
if (commandLine.fileNames.length === 0 && !configFileName) {
|
||||
@@ -360,7 +375,7 @@ namespace ts {
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
return;
|
||||
}
|
||||
const configParseResult = parseJsonConfigFileContent(configObject, sys, getDirectoryPath(configFileName));
|
||||
const configParseResult = parseJsonConfigFileContent(configObject, sys, getDirectoryPath(configFileName), commandLine.options);
|
||||
if (configParseResult.errors.length > 0) {
|
||||
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
@@ -376,7 +391,7 @@ namespace ts {
|
||||
if (configFileName) {
|
||||
const configParseResult = parseConfigFile();
|
||||
rootFileNames = configParseResult.fileNames;
|
||||
compilerOptions = extend(commandLine.options, configParseResult.options);
|
||||
compilerOptions = configParseResult.options;
|
||||
}
|
||||
else {
|
||||
rootFileNames = commandLine.fileNames;
|
||||
@@ -469,7 +484,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function watchedDirectoryChanged(fileName: string) {
|
||||
if (fileName && !ts.isSupportedSourceFileName(fileName)) {
|
||||
if (fileName && !ts.isSupportedSourceFileName(fileName, commandLine.options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+331
-66
File diff suppressed because it is too large
Load Diff
+182
-55
@@ -38,6 +38,8 @@ namespace ts {
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
getNewLine(): string;
|
||||
|
||||
isEmitBlocked(emitFileName: string): boolean;
|
||||
|
||||
writeFile: WriteFileCallback;
|
||||
}
|
||||
|
||||
@@ -464,9 +466,6 @@ namespace ts {
|
||||
return true;
|
||||
case SyntaxKind.VoidKeyword:
|
||||
return node.parent.kind !== SyntaxKind.VoidExpression;
|
||||
case SyntaxKind.StringLiteral:
|
||||
// Specialized signatures can have string literals as their parameters' type names
|
||||
return node.parent.kind === SyntaxKind.Parameter;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
|
||||
|
||||
@@ -907,23 +906,6 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function childIsDecorated(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return forEach((<ClassDeclaration>node).members, nodeOrChildIsDecorated);
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return forEach((<FunctionLikeDeclaration>node).parameters, nodeIsDecorated);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function nodeOrChildIsDecorated(node: Node): boolean {
|
||||
return nodeIsDecorated(node) || childIsDecorated(node);
|
||||
}
|
||||
|
||||
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
|
||||
return node.kind === SyntaxKind.PropertyAccessExpression;
|
||||
}
|
||||
@@ -1327,7 +1309,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// True if the given identifier, string literal, or number literal is the name of a declaration node
|
||||
export function isDeclarationName(name: Node): boolean {
|
||||
export function isDeclarationName(name: Node): name is Identifier | StringLiteral | LiteralExpression {
|
||||
if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) {
|
||||
return false;
|
||||
}
|
||||
@@ -1545,7 +1527,7 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
|
||||
}
|
||||
|
||||
export function isModifier(token: SyntaxKind): boolean {
|
||||
export function isModifierKind(token: SyntaxKind): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
@@ -1578,20 +1560,60 @@ namespace ts {
|
||||
return isFunctionLike(n) || n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
export function cloneEntityName(node: EntityName): EntityName {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
const clone = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
||||
clone.text = (<Identifier>node).text;
|
||||
return clone;
|
||||
/**
|
||||
* Creates a shallow, memberwise clone of a node. The "kind", "pos", "end", "flags", and "parent"
|
||||
* properties are excluded by default, and can be provided via the "location", "flags", and
|
||||
* "parent" parameters.
|
||||
* @param node The node to clone.
|
||||
* @param location An optional TextRange to use to supply the new position.
|
||||
* @param flags The NodeFlags to use for the cloned node.
|
||||
* @param parent The parent for the new node.
|
||||
*/
|
||||
export function cloneNode<T extends Node>(node: T, location?: TextRange, flags?: NodeFlags, parent?: Node): T {
|
||||
// We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
|
||||
// the original node. We also need to exclude specific properties and only include own-
|
||||
// properties (to skip members already defined on the shared prototype).
|
||||
const clone = location !== undefined
|
||||
? <T>createNode(node.kind, location.pos, location.end)
|
||||
: <T>createSynthesizedNode(node.kind);
|
||||
|
||||
for (const key in node) {
|
||||
if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(<any>clone)[key] = (<any>node)[key];
|
||||
}
|
||||
else {
|
||||
const clone = <QualifiedName>createSynthesizedNode(SyntaxKind.QualifiedName);
|
||||
clone.left = cloneEntityName((<QualifiedName>node).left);
|
||||
clone.left.parent = clone;
|
||||
clone.right = <Identifier>cloneEntityName((<QualifiedName>node).right);
|
||||
clone.right.parent = clone;
|
||||
return clone;
|
||||
|
||||
if (flags !== undefined) {
|
||||
clone.flags = flags;
|
||||
}
|
||||
|
||||
if (parent !== undefined) {
|
||||
clone.parent = parent;
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep clone of an EntityName, with new parent pointers.
|
||||
* @param node The EntityName to clone.
|
||||
* @param parent The parent for the cloned node.
|
||||
*/
|
||||
export function cloneEntityName(node: EntityName, parent?: Node): EntityName {
|
||||
const clone = cloneNode(node, node, node.flags, parent);
|
||||
if (isQualifiedName(clone)) {
|
||||
const { left, right } = clone;
|
||||
clone.left = cloneEntityName(left, clone);
|
||||
clone.right = cloneNode(right, right, right.flags, parent);
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
export function isQualifiedName(node: Node): node is QualifiedName {
|
||||
return node.kind === SyntaxKind.QualifiedName;
|
||||
}
|
||||
|
||||
export function nodeIsSynthesized(node: Node): boolean {
|
||||
@@ -1867,8 +1889,10 @@ namespace ts {
|
||||
* Resolves a local path to a path which is absolute to the base of the emit
|
||||
*/
|
||||
export function getExternalModuleNameFromPath(host: EmitHost, fileName: string): string {
|
||||
const dir = host.getCurrentDirectory();
|
||||
const relativePath = getRelativePathToDirectoryOrUrl(dir, fileName, dir, f => host.getCanonicalFileName(f), /*isAbsolutePathAnUrl*/ false);
|
||||
const getCanonicalFileName = (f: string) => host.getCanonicalFileName(f);
|
||||
const dir = toPath(host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
|
||||
const filePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
|
||||
const relativePath = getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
|
||||
return removeFileExtension(relativePath);
|
||||
}
|
||||
|
||||
@@ -1885,15 +1909,85 @@ namespace ts {
|
||||
return emitOutputFilePathWithoutExtension + extension;
|
||||
}
|
||||
|
||||
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
|
||||
return compilerOptions.target || ScriptTarget.ES3;
|
||||
}
|
||||
|
||||
export function getEmitModuleKind(compilerOptions: CompilerOptions) {
|
||||
return compilerOptions.module ?
|
||||
compilerOptions.module :
|
||||
getEmitScriptTarget(compilerOptions) === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
|
||||
}
|
||||
|
||||
export interface EmitFileNames {
|
||||
jsFilePath: string;
|
||||
sourceMapFilePath: string;
|
||||
declarationFilePath: string;
|
||||
}
|
||||
|
||||
export function forEachExpectedEmitFile(host: EmitHost,
|
||||
action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) => void,
|
||||
targetSourceFile?: SourceFile) {
|
||||
const options = host.getCompilerOptions();
|
||||
// Emit on each source file
|
||||
if (options.outFile || options.out) {
|
||||
onBundledEmit(host);
|
||||
}
|
||||
else {
|
||||
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
|
||||
for (const sourceFile of sourceFiles) {
|
||||
if (!isDeclarationFile(sourceFile)) {
|
||||
onSingleFileEmit(host, sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onSingleFileEmit(host: EmitHost, sourceFile: SourceFile) {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host,
|
||||
sourceFile.languageVariant === LanguageVariant.JSX && options.jsx === JsxEmit.Preserve ? ".jsx" : ".js");
|
||||
const emitFileNames: EmitFileNames = {
|
||||
jsFilePath,
|
||||
sourceMapFilePath: getSourceMapFilePath(jsFilePath, options),
|
||||
declarationFilePath: !isSourceFileJavaScript(sourceFile) ? getDeclarationEmitFilePath(jsFilePath, options) : undefined
|
||||
};
|
||||
action(emitFileNames, [sourceFile], /*isBundledEmit*/false);
|
||||
}
|
||||
|
||||
function onBundledEmit(host: EmitHost) {
|
||||
// Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
|
||||
const bundledSources = filter(host.getSourceFiles(),
|
||||
sourceFile => !isDeclarationFile(sourceFile) && // Not a declaration file
|
||||
(!isExternalModule(sourceFile) || // non module file
|
||||
(getEmitModuleKind(options) && isExternalModule(sourceFile)))); // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
|
||||
if (bundledSources.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const emitFileNames: EmitFileNames = {
|
||||
jsFilePath,
|
||||
sourceMapFilePath: getSourceMapFilePath(jsFilePath, options),
|
||||
declarationFilePath: getDeclarationEmitFilePath(jsFilePath, options)
|
||||
};
|
||||
action(emitFileNames, bundledSources, /*isBundledEmit*/true);
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) {
|
||||
return options.sourceMap ? jsFilePath + ".map" : undefined;
|
||||
}
|
||||
|
||||
function getDeclarationEmitFilePath(jsFilePath: string, options: CompilerOptions) {
|
||||
return options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) {
|
||||
let sourceFilePath = getNormalizedAbsolutePath(sourceFile.fileName, host.getCurrentDirectory());
|
||||
sourceFilePath = sourceFilePath.replace(host.getCommonSourceDirectory(), "");
|
||||
return combinePaths(newDirPath, sourceFilePath);
|
||||
}
|
||||
|
||||
export function writeFile(host: EmitHost, diagnostics: Diagnostic[], fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
export function writeFile(host: EmitHost, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
host.writeFile(fileName, data, writeByteOrderMark, hostErrorMessage => {
|
||||
diagnostics.push(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1917,18 +2011,6 @@ namespace ts {
|
||||
return accessor && accessor.parameters.length > 0 && accessor.parameters[0].type;
|
||||
}
|
||||
|
||||
export function shouldEmitToOwnFile(sourceFile: SourceFile, compilerOptions: CompilerOptions): boolean {
|
||||
if (!isDeclarationFile(sourceFile)) {
|
||||
if ((isExternalModule(sourceFile) || !(compilerOptions.outFile || compilerOptions.out))) {
|
||||
// 1. in-browser single file compilation scenario
|
||||
// 2. non .js file
|
||||
return compilerOptions.isolatedModules || !fileExtensionIs(sourceFile.fileName, ".js");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getAllAccessorDeclarations(declarations: NodeArray<Declaration>, accessor: AccessorDeclaration) {
|
||||
let firstAccessor: AccessorDeclaration;
|
||||
let secondAccessor: AccessorDeclaration;
|
||||
@@ -2273,11 +2355,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function hasJavaScriptFileExtension(fileName: string) {
|
||||
return fileExtensionIs(fileName, ".js") || fileExtensionIs(fileName, ".jsx");
|
||||
}
|
||||
|
||||
export function allowsJsxExpressions(fileName: string) {
|
||||
return fileExtensionIs(fileName, ".tsx") || fileExtensionIs(fileName, ".jsx");
|
||||
return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2318,6 +2396,55 @@ namespace ts {
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize an object graph into a JSON string. This is intended only for use on an acyclic graph
|
||||
* as the fallback implementation does not check for circular references by default.
|
||||
*/
|
||||
export const stringify: (value: any) => string = typeof JSON !== "undefined" && JSON.stringify
|
||||
? JSON.stringify
|
||||
: stringifyFallback;
|
||||
|
||||
/**
|
||||
* Serialize an object graph into a JSON string.
|
||||
*/
|
||||
function stringifyFallback(value: any): string {
|
||||
// JSON.stringify returns `undefined` here, instead of the string "undefined".
|
||||
return value === undefined ? undefined : stringifyValue(value);
|
||||
}
|
||||
|
||||
function stringifyValue(value: any): string {
|
||||
return typeof value === "string" ? `"${escapeString(value)}"`
|
||||
: typeof value === "number" ? isFinite(value) ? String(value) : "null"
|
||||
: typeof value === "boolean" ? value ? "true" : "false"
|
||||
: typeof value === "object" && value ? isArray(value) ? cycleCheck(stringifyArray, value) : cycleCheck(stringifyObject, value)
|
||||
: /*fallback*/ "null";
|
||||
}
|
||||
|
||||
function cycleCheck(cb: (value: any) => string, value: any) {
|
||||
Debug.assert(!value.hasOwnProperty("__cycle"), "Converting circular structure to JSON");
|
||||
value.__cycle = true;
|
||||
const result = cb(value);
|
||||
delete value.__cycle;
|
||||
return result;
|
||||
}
|
||||
|
||||
function stringifyArray(value: any) {
|
||||
return `[${reduceLeft(value, stringifyElement, "")}]`;
|
||||
}
|
||||
|
||||
function stringifyElement(memo: string, value: any) {
|
||||
return (memo ? memo + "," : memo) + stringifyValue(value);
|
||||
}
|
||||
|
||||
function stringifyObject(value: any) {
|
||||
return `{${reduceProperties(value, stringifyProperty, "")}}`;
|
||||
}
|
||||
|
||||
function stringifyProperty(memo: string, value: any, key: string) {
|
||||
return value === undefined || typeof value === "function" || key === "__cycle" ? memo
|
||||
: (memo ? memo + "," : memo) + `"${escapeString(key)}":${stringifyValue(value)}`;
|
||||
}
|
||||
|
||||
const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,89 +40,79 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
this.basePath += "/" + this.testSuiteName;
|
||||
}
|
||||
|
||||
private makeUnitName(name: string, root: string) {
|
||||
return ts.isRootedDiskPath(name) ? name : ts.combinePaths(root, name);
|
||||
};
|
||||
|
||||
public checkTestCodeOutput(fileName: string) {
|
||||
describe("compiler tests for " + fileName, () => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
let justName: string;
|
||||
let content: string;
|
||||
let testCaseContent: { settings: Harness.TestCaseParser.CompilerSettings; testUnitData: Harness.TestCaseParser.TestUnitData[]; };
|
||||
|
||||
let units: Harness.TestCaseParser.TestUnitData[];
|
||||
let tcSettings: Harness.TestCaseParser.CompilerSettings;
|
||||
|
||||
let lastUnit: Harness.TestCaseParser.TestUnitData;
|
||||
let rootDir: string;
|
||||
let harnessSettings: Harness.TestCaseParser.CompilerSettings;
|
||||
let hasNonDtsFiles: boolean;
|
||||
|
||||
let result: Harness.Compiler.CompilerResult;
|
||||
let program: ts.Program;
|
||||
let options: ts.CompilerOptions;
|
||||
// equivalent to the files that will be passed on the command line
|
||||
let toBeCompiled: { unitName: string; content: string }[];
|
||||
let toBeCompiled: Harness.Compiler.TestFile[];
|
||||
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
|
||||
let otherFiles: { unitName: string; content: string }[];
|
||||
let harnessCompiler: Harness.Compiler.HarnessCompiler;
|
||||
let otherFiles: Harness.Compiler.TestFile[];
|
||||
|
||||
before(() => {
|
||||
justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path.
|
||||
content = Harness.IO.readFile(fileName);
|
||||
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
|
||||
units = testCaseContent.testUnitData;
|
||||
tcSettings = testCaseContent.settings;
|
||||
const content = Harness.IO.readFile(fileName);
|
||||
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
|
||||
const units = testCaseContent.testUnitData;
|
||||
harnessSettings = testCaseContent.settings;
|
||||
lastUnit = units[units.length - 1];
|
||||
rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/";
|
||||
harnessCompiler = Harness.Compiler.getCompiler();
|
||||
hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ".d.ts"));
|
||||
const rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/";
|
||||
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
|
||||
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
|
||||
// otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another.
|
||||
toBeCompiled = [];
|
||||
otherFiles = [];
|
||||
if (/require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) {
|
||||
toBeCompiled.push({ unitName: rootDir + lastUnit.name, content: lastUnit.content });
|
||||
toBeCompiled.push({ unitName: this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content });
|
||||
units.forEach(unit => {
|
||||
if (unit.name !== lastUnit.name) {
|
||||
otherFiles.push({ unitName: rootDir + unit.name, content: unit.content });
|
||||
otherFiles.push({ unitName: this.makeUnitName(unit.name, rootDir), content: unit.content });
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
toBeCompiled = units.map(unit => {
|
||||
return { unitName: rootDir + unit.name, content: unit.content };
|
||||
return { unitName: this.makeUnitName(unit.name, rootDir), content: unit.content };
|
||||
});
|
||||
}
|
||||
|
||||
options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult, _program) {
|
||||
result = compileResult;
|
||||
// The program will be used by typeWriter
|
||||
program = _program;
|
||||
}, function (settings) {
|
||||
harnessCompiler.setCompilerSettings(tcSettings);
|
||||
});
|
||||
const output = Harness.Compiler.compileFiles(
|
||||
toBeCompiled, otherFiles, harnessSettings, /* options */ undefined, /* currentDirectory */ undefined);
|
||||
|
||||
options = output.options;
|
||||
result = output.result;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
justName = undefined;
|
||||
content = undefined;
|
||||
testCaseContent = undefined;
|
||||
units = undefined;
|
||||
tcSettings = undefined;
|
||||
lastUnit = undefined;
|
||||
rootDir = undefined;
|
||||
hasNonDtsFiles = undefined;
|
||||
result = undefined;
|
||||
program = undefined;
|
||||
options = undefined;
|
||||
toBeCompiled = undefined;
|
||||
otherFiles = undefined;
|
||||
harnessCompiler = undefined;
|
||||
});
|
||||
|
||||
function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string {
|
||||
return file.writeByteOrderMark ? "\u00EF\u00BB\u00BF" : "";
|
||||
}
|
||||
|
||||
function getErrorBaseline(toBeCompiled: { unitName: string; content: string }[], otherFiles: { unitName: string; content: string }[], result: Harness.Compiler.CompilerResult) {
|
||||
function getErrorBaseline(toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], result: Harness.Compiler.CompilerResult) {
|
||||
return Harness.Compiler.getErrorBaseline(toBeCompiled.concat(otherFiles), result.errors);
|
||||
}
|
||||
|
||||
@@ -151,8 +141,8 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
it("Correct JS output for " + fileName, () => {
|
||||
if (!ts.fileExtensionIs(lastUnit.name, ".d.ts") && this.emit) {
|
||||
if (result.files.length === 0 && result.errors.length === 0) {
|
||||
if (hasNonDtsFiles && this.emit) {
|
||||
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
|
||||
@@ -184,9 +174,9 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
}
|
||||
|
||||
const declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
|
||||
harnessCompiler.setCompilerSettings(tcSettings);
|
||||
}, options);
|
||||
const declFileCompilationResult =
|
||||
Harness.Compiler.compileDeclarationFiles(
|
||||
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
@@ -257,10 +247,11 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
// These types are equivalent, but depend on what order the compiler observed
|
||||
// certain parts of the program.
|
||||
|
||||
const program = result.program;
|
||||
const allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName));
|
||||
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ true);
|
||||
const pullWalker = new TypeWriterWalker(program, /*fullTypeCheck:*/ false);
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
|
||||
const pullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ false);
|
||||
|
||||
const fullResults: ts.Map<TypeWriterResult[]> = {};
|
||||
const pullResults: ts.Map<TypeWriterResult[]> = {};
|
||||
@@ -274,14 +265,14 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
// The second gives symbols for all identifiers.
|
||||
let e1: Error, e2: Error;
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine:*/ false);
|
||||
checkBaseLines(/*isSymbolBaseLine*/ false);
|
||||
}
|
||||
catch (e) {
|
||||
e1 = e;
|
||||
}
|
||||
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine:*/ true);
|
||||
checkBaseLines(/*isSymbolBaseLine*/ true);
|
||||
}
|
||||
catch (e) {
|
||||
e2 = e;
|
||||
@@ -367,7 +358,6 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
public initializeTests() {
|
||||
describe(this.testSuiteName + " tests", () => {
|
||||
describe("Setup compiler for compiler baselines", () => {
|
||||
const harnessCompiler = Harness.Compiler.getCompiler();
|
||||
this.parseOptions();
|
||||
});
|
||||
|
||||
|
||||
+715
-280
File diff suppressed because it is too large
Load Diff
@@ -58,56 +58,6 @@ class FourSlashRunner extends RunnerBase {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Generate Tao XML", () => {
|
||||
const invalidReasons: any = {};
|
||||
FourSlash.xmlData.forEach(xml => {
|
||||
if (xml.invalidReason !== null) {
|
||||
invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1;
|
||||
}
|
||||
});
|
||||
const invalidReport: { reason: string; count: number }[] = [];
|
||||
for (const reason in invalidReasons) {
|
||||
if (invalidReasons.hasOwnProperty(reason)) {
|
||||
invalidReport.push({ reason: reason, count: invalidReasons[reason] });
|
||||
}
|
||||
}
|
||||
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
|
||||
|
||||
const lines: string[] = [];
|
||||
lines.push("<!-- Blocked Test Report");
|
||||
invalidReport.forEach((reasonAndCount) => {
|
||||
lines.push(reasonAndCount.count + " tests blocked by " + reasonAndCount.reason);
|
||||
});
|
||||
lines.push("-->");
|
||||
lines.push("<TaoTest xmlns=\"http://microsoft.com/schemas/VSLanguages/TAO\">");
|
||||
lines.push(" <InitTest>");
|
||||
lines.push(" <StartTarget />");
|
||||
lines.push(" </InitTest>");
|
||||
lines.push(" <ScenarioList>");
|
||||
FourSlash.xmlData.forEach(xml => {
|
||||
if (xml.invalidReason !== null) {
|
||||
lines.push("<!-- Skipped " + xml.originalName + ", reason: " + xml.invalidReason + " -->");
|
||||
}
|
||||
else {
|
||||
lines.push(" <Scenario Name=\"" + xml.originalName + "\">");
|
||||
xml.actions.forEach(action => {
|
||||
lines.push(" " + action);
|
||||
});
|
||||
lines.push(" </Scenario>");
|
||||
}
|
||||
});
|
||||
lines.push(" </ScenarioList>");
|
||||
lines.push(" <CleanupScenario>");
|
||||
lines.push(" <CloseAllDocuments />");
|
||||
lines.push(" <CleanupCreatedFiles />");
|
||||
lines.push(" </CleanupScenario>");
|
||||
lines.push(" <CleanupTest>");
|
||||
lines.push(" <CloseTarget />");
|
||||
lines.push(" </CleanupTest>");
|
||||
lines.push("</TaoTest>");
|
||||
Harness.IO.writeFile("built/local/fourslash.xml", lines.join("\r\n"));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+152
-263
@@ -176,7 +176,9 @@ namespace Utils {
|
||||
ts.forEachChild(node, child => { childNodesAndArrays.push(child); }, array => { childNodesAndArrays.push(array); });
|
||||
|
||||
for (const childName in node) {
|
||||
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator") {
|
||||
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator" ||
|
||||
// for now ignore jsdoc comments
|
||||
childName === "jsDocComment") {
|
||||
continue;
|
||||
}
|
||||
const child = (<any>node)[childName];
|
||||
@@ -628,7 +630,7 @@ namespace Harness {
|
||||
function getResolvedPathFromServer(path: string) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
try {
|
||||
xhr.open("GET", path + "?resolve", false);
|
||||
xhr.open("GET", path + "?resolve", /*async*/ false);
|
||||
xhr.send();
|
||||
}
|
||||
catch (e) {
|
||||
@@ -647,7 +649,7 @@ namespace Harness {
|
||||
export function getFileFromServerSync(url: string): XHRResponse {
|
||||
const xhr = new XMLHttpRequest();
|
||||
try {
|
||||
xhr.open("GET", url, false);
|
||||
xhr.open("GET", url, /*async*/ false);
|
||||
xhr.send();
|
||||
}
|
||||
catch (e) {
|
||||
@@ -662,7 +664,7 @@ namespace Harness {
|
||||
const xhr = new XMLHttpRequest();
|
||||
try {
|
||||
const actionMsg = "?action=" + action;
|
||||
xhr.open("POST", url + actionMsg, false);
|
||||
xhr.open("POST", url + actionMsg, /*async*/ false);
|
||||
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
|
||||
xhr.send(contents);
|
||||
}
|
||||
@@ -767,26 +769,9 @@ namespace Harness {
|
||||
}
|
||||
|
||||
namespace Harness {
|
||||
let tcServicesFileName = "typescriptServices.js";
|
||||
|
||||
export let libFolder: string;
|
||||
switch (Utils.getExecutionEnvironment()) {
|
||||
case Utils.ExecutionEnvironment.CScript:
|
||||
libFolder = "built/local/";
|
||||
tcServicesFileName = "built/local/typescriptServices.js";
|
||||
break;
|
||||
case Utils.ExecutionEnvironment.Node:
|
||||
libFolder = "built/local/";
|
||||
tcServicesFileName = "built/local/typescriptServices.js";
|
||||
break;
|
||||
case Utils.ExecutionEnvironment.Browser:
|
||||
libFolder = "built/local/";
|
||||
tcServicesFileName = "built/local/typescriptServices.js";
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown context");
|
||||
}
|
||||
export let tcServicesFile = IO.readFile(tcServicesFileName);
|
||||
export const libFolder = "built/local/";
|
||||
const tcServicesFileName = ts.combinePaths(libFolder, "typescriptServices.js");
|
||||
export const tcServicesFile = IO.readFile(tcServicesFileName);
|
||||
|
||||
export interface SourceMapEmitterCallback {
|
||||
(emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void;
|
||||
@@ -827,57 +812,14 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export interface IEmitterIOHost {
|
||||
writeFile(path: string, contents: string, writeByteOrderMark: boolean): void;
|
||||
resolvePath(path: string): string;
|
||||
}
|
||||
|
||||
/** Mimics having multiple files, later concatenated to a single file. */
|
||||
export class EmitterIOHost implements IEmitterIOHost {
|
||||
private fileCollection: any = {};
|
||||
|
||||
/** create file gets the whole path to create, so this works as expected with the --out parameter */
|
||||
public writeFile(s: string, contents: string, writeByteOrderMark: boolean): void {
|
||||
let writer: ITextWriter;
|
||||
if (this.fileCollection[s]) {
|
||||
writer = <ITextWriter>this.fileCollection[s];
|
||||
}
|
||||
else {
|
||||
writer = new Harness.Compiler.WriterAggregator();
|
||||
this.fileCollection[s] = writer;
|
||||
}
|
||||
|
||||
writer.Write(contents);
|
||||
writer.Close();
|
||||
}
|
||||
|
||||
public resolvePath(s: string) { return s; }
|
||||
|
||||
public reset() { this.fileCollection = {}; }
|
||||
|
||||
public toArray(): { fileName: string; file: WriterAggregator; }[] {
|
||||
const result: { fileName: string; file: WriterAggregator; }[] = [];
|
||||
for (const p in this.fileCollection) {
|
||||
if (this.fileCollection.hasOwnProperty(p)) {
|
||||
const current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
|
||||
if (current.lines.length > 0) {
|
||||
if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); }
|
||||
result.push({ fileName: p, file: this.fileCollection[p] });
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export function createSourceFileAndAssertInvariants(
|
||||
fileName: string,
|
||||
sourceText: string,
|
||||
languageVersion: ts.ScriptTarget) {
|
||||
// We'll only assert inletiants outside of light mode.
|
||||
// We'll only assert invariants outside of light mode.
|
||||
const shouldAssertInvariants = !Harness.lightMode;
|
||||
|
||||
// Only set the parent nodes if we're asserting inletiants. We don't need them otherwise.
|
||||
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
|
||||
const result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
|
||||
|
||||
if (shouldAssertInvariants) {
|
||||
@@ -890,12 +832,12 @@ namespace Harness {
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
|
||||
export let defaultLibFileName = "lib.d.ts";
|
||||
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export const defaultLibFileName = "lib.d.ts";
|
||||
export const defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export const defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
|
||||
// Cache these between executions so we don't have to re-parse them for every test
|
||||
export let fourslashFileName = "fourslash.ts";
|
||||
export const fourslashFileName = "fourslash.ts";
|
||||
export let fourslashSourceFile: ts.SourceFile;
|
||||
|
||||
export function getCanonicalFileName(fileName: string): string {
|
||||
@@ -903,41 +845,32 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export function createCompilerHost(
|
||||
inputFiles: { unitName: string; content: string; }[],
|
||||
inputFiles: TestFile[],
|
||||
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
|
||||
scriptTarget: ts.ScriptTarget,
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
|
||||
currentDirectory?: string,
|
||||
currentDirectory: string,
|
||||
newLineKind?: ts.NewLineKind): ts.CompilerHost {
|
||||
|
||||
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
|
||||
function getCanonicalFileName(fileName: string): string {
|
||||
return useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
||||
const filemap: { [fileName: string]: ts.SourceFile; } = {};
|
||||
const getCurrentDirectory = currentDirectory === undefined ? Harness.IO.getCurrentDirectory : () => currentDirectory;
|
||||
|
||||
// Register input files
|
||||
function register(file: { unitName: string; content: string; }) {
|
||||
const fileMap: ts.FileMap<ts.SourceFile> = ts.createFileMap<ts.SourceFile>();
|
||||
for (const file of inputFiles) {
|
||||
if (file.content !== undefined) {
|
||||
const fileName = ts.normalizePath(file.unitName);
|
||||
const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
|
||||
filemap[getCanonicalFileName(fileName)] = sourceFile;
|
||||
filemap[getCanonicalFileName(ts.getNormalizedAbsolutePath(fileName, getCurrentDirectory()))] = sourceFile;
|
||||
const path = ts.toPath(file.unitName, currentDirectory, getCanonicalFileName);
|
||||
fileMap.set(path, sourceFile);
|
||||
}
|
||||
};
|
||||
inputFiles.forEach(register);
|
||||
}
|
||||
|
||||
function getSourceFile(fn: string, languageVersion: ts.ScriptTarget) {
|
||||
fn = ts.normalizePath(fn);
|
||||
if (Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(fn))) {
|
||||
return filemap[getCanonicalFileName(fn)];
|
||||
}
|
||||
else if (currentDirectory) {
|
||||
const canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
|
||||
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
|
||||
const path = ts.toPath(fn, currentDirectory, getCanonicalFileName);
|
||||
if (fileMap.contains(path)) {
|
||||
return fileMap.get(path);
|
||||
}
|
||||
else if (fn === fourslashFileName) {
|
||||
const tsFn = "tests/cases/fourslash/" + fourslashFileName;
|
||||
@@ -959,7 +892,7 @@ namespace Harness {
|
||||
Harness.IO.newLine();
|
||||
|
||||
return {
|
||||
getCurrentDirectory,
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
getSourceFile,
|
||||
getDefaultLibFileName: options => defaultLibFileName,
|
||||
writeFile,
|
||||
@@ -975,6 +908,7 @@ namespace Harness {
|
||||
useCaseSensitiveFileNames?: boolean;
|
||||
includeBuiltFile?: string;
|
||||
baselineFile?: string;
|
||||
libFiles?: string;
|
||||
}
|
||||
|
||||
// Additional options not already in ts.optionDeclarations
|
||||
@@ -984,6 +918,7 @@ namespace Harness {
|
||||
{ name: "baselineFile", type: "string" },
|
||||
{ name: "includeBuiltFile", type: "string" },
|
||||
{ name: "fileName", type: "string" },
|
||||
{ name: "libFiles", type: "string" },
|
||||
{ name: "noErrorTruncation", type: "boolean" }
|
||||
];
|
||||
|
||||
@@ -1034,177 +969,144 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export class HarnessCompiler {
|
||||
private inputFiles: { unitName: string; content: string }[] = [];
|
||||
private compileOptions: ts.CompilerOptions;
|
||||
private settings: Harness.TestCaseParser.CompilerSettings = {};
|
||||
export interface TestFile {
|
||||
unitName: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
private lastErrors: ts.Diagnostic[];
|
||||
export interface CompilationOutput {
|
||||
result: CompilerResult;
|
||||
options: ts.CompilerOptions & HarnessOptions;
|
||||
}
|
||||
|
||||
public reset() {
|
||||
this.inputFiles = [];
|
||||
this.settings = {};
|
||||
this.lastErrors = [];
|
||||
export function compileFiles(
|
||||
inputFiles: TestFile[],
|
||||
otherFiles: TestFile[],
|
||||
harnessSettings: TestCaseParser.CompilerSettings,
|
||||
compilerOptions: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string): CompilationOutput {
|
||||
|
||||
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.clone(compilerOptions) : { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
options.module = options.module || ts.ModuleKind.None;
|
||||
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
|
||||
options.noErrorTruncation = true;
|
||||
options.skipDefaultLibCheck = true;
|
||||
|
||||
currentDirectory = currentDirectory || Harness.IO.getCurrentDirectory();
|
||||
|
||||
// Parse settings
|
||||
if (harnessSettings) {
|
||||
setCompilerOptionsFromHarnessSetting(harnessSettings, options);
|
||||
}
|
||||
|
||||
public reportCompilationErrors() {
|
||||
return this.lastErrors;
|
||||
const useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : Harness.IO.useCaseSensitiveFileNames();
|
||||
const programFiles: TestFile[] = inputFiles.slice();
|
||||
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
|
||||
// Treat them as library files, so include them in build, but not in baselines.
|
||||
if (options.includeBuiltFile) {
|
||||
const builtFileName = ts.combinePaths(libFolder, options.includeBuiltFile);
|
||||
const builtFile: TestFile = {
|
||||
unitName: builtFileName,
|
||||
content: normalizeLineEndings(IO.readFile(builtFileName), Harness.IO.newLine()),
|
||||
};
|
||||
programFiles.push(builtFile);
|
||||
}
|
||||
|
||||
public setCompilerSettings(tcSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
this.settings = tcSettings;
|
||||
}
|
||||
const fileOutputs: GeneratedFile[] = [];
|
||||
|
||||
public addInputFiles(files: { unitName: string; content: string }[]) {
|
||||
files.forEach(file => this.addInputFile(file));
|
||||
}
|
||||
|
||||
public addInputFile(file: { unitName: string; content: string }) {
|
||||
this.inputFiles.push(file);
|
||||
}
|
||||
|
||||
public setCompilerOptions(options?: ts.CompilerOptions) {
|
||||
this.compileOptions = options || { noResolve: false };
|
||||
}
|
||||
|
||||
public emitAll(ioHost?: IEmitterIOHost) {
|
||||
this.compileFiles(this.inputFiles,
|
||||
/*otherFiles*/ [],
|
||||
/*onComplete*/ result => {
|
||||
result.files.forEach(writeFile);
|
||||
result.declFilesCode.forEach(writeFile);
|
||||
result.sourceMaps.forEach(writeFile);
|
||||
},
|
||||
/*settingsCallback*/ () => { },
|
||||
this.compileOptions);
|
||||
|
||||
function writeFile(file: GeneratedFile) {
|
||||
ioHost.writeFile(file.fileName, file.code, false);
|
||||
// Files from tests\lib that are requested by "@libFiles"
|
||||
if (options.libFiles) {
|
||||
for (const fileName of options.libFiles.split(",")) {
|
||||
const libFileName = "tests/lib/" + fileName;
|
||||
programFiles.push({ unitName: libFileName, content: normalizeLineEndings(IO.readFile(libFileName), Harness.IO.newLine()) });
|
||||
}
|
||||
}
|
||||
|
||||
public compileFiles(inputFiles: { unitName: string; content: string }[],
|
||||
otherFiles: { unitName: string; content: string }[],
|
||||
onComplete: (result: CompilerResult, program: ts.Program) => void,
|
||||
settingsCallback?: (settings: ts.CompilerOptions) => void,
|
||||
options?: ts.CompilerOptions & HarnessOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory?: string) {
|
||||
|
||||
options = options || { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
options.module = options.module || ts.ModuleKind.None;
|
||||
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
|
||||
options.noErrorTruncation = true;
|
||||
options.skipDefaultLibCheck = true;
|
||||
const programFileNames = programFiles.map(file => file.unitName);
|
||||
|
||||
if (settingsCallback) {
|
||||
settingsCallback(null);
|
||||
}
|
||||
const compilerHost = createCompilerHost(
|
||||
programFiles.concat(otherFiles),
|
||||
(fileName, code, writeByteOrderMark) => fileOutputs.push({ fileName, code, writeByteOrderMark }),
|
||||
options.target,
|
||||
useCaseSensitiveFileNames,
|
||||
currentDirectory,
|
||||
options.newLine);
|
||||
const program = ts.createProgram(programFileNames, options, compilerHost);
|
||||
|
||||
const newLine = "\r\n";
|
||||
const emitResult = program.emit();
|
||||
|
||||
// Parse settings
|
||||
setCompilerOptionsFromHarnessSetting(this.settings, options);
|
||||
const errors = ts.getPreEmitDiagnostics(program);
|
||||
|
||||
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
|
||||
// Treat them as library files, so include them in build, but not in baselines.
|
||||
const includeBuiltFiles: { unitName: string; content: string }[] = [];
|
||||
if (options.includeBuiltFile) {
|
||||
const builtFileName = libFolder + options.includeBuiltFile;
|
||||
includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) });
|
||||
}
|
||||
const result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
|
||||
return { result, options };
|
||||
}
|
||||
|
||||
const useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : Harness.IO.useCaseSensitiveFileNames();
|
||||
|
||||
const fileOutputs: GeneratedFile[] = [];
|
||||
|
||||
const programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
|
||||
|
||||
const compilerHost = createCompilerHost(
|
||||
inputFiles.concat(includeBuiltFiles).concat(otherFiles),
|
||||
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
|
||||
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
|
||||
const program = ts.createProgram(programFiles, options, compilerHost);
|
||||
|
||||
const emitResult = program.emit();
|
||||
|
||||
const errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
||||
this.lastErrors = errors;
|
||||
|
||||
const result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
|
||||
onComplete(result, program);
|
||||
|
||||
return options;
|
||||
export function compileDeclarationFiles(inputFiles: TestFile[],
|
||||
otherFiles: TestFile[],
|
||||
result: CompilerResult,
|
||||
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions,
|
||||
options: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string) {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
|
||||
}
|
||||
|
||||
public compileDeclarationFiles(inputFiles: { unitName: string; content: string; }[],
|
||||
otherFiles: { unitName: string; content: string; }[],
|
||||
result: CompilerResult,
|
||||
settingsCallback?: (settings: ts.CompilerOptions) => void,
|
||||
options?: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory?: string) {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
|
||||
const declInputFiles: TestFile[] = [];
|
||||
const declOtherFiles: TestFile[] = [];
|
||||
|
||||
// if the .d.ts is non-empty, confirm it compiles correctly as well
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
|
||||
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory);
|
||||
return { declInputFiles, declOtherFiles, declResult: output.result };
|
||||
}
|
||||
|
||||
function addDtsFile(file: TestFile, dtsFiles: TestFile[]) {
|
||||
if (isDTS(file.unitName)) {
|
||||
dtsFiles.push(file);
|
||||
}
|
||||
|
||||
const declInputFiles: { unitName: string; content: string }[] = [];
|
||||
const declOtherFiles: { unitName: string; content: string }[] = [];
|
||||
let declResult: Harness.Compiler.CompilerResult;
|
||||
|
||||
// if the .d.ts is non-empty, confirm it compiles correctly as well
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
|
||||
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) { declResult = compileResult; },
|
||||
settingsCallback, options, currentDirectory);
|
||||
|
||||
return { declInputFiles, declOtherFiles, declResult };
|
||||
}
|
||||
|
||||
function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) {
|
||||
if (isDTS(file.unitName)) {
|
||||
dtsFiles.push(file);
|
||||
}
|
||||
else if (isTS(file.unitName)) {
|
||||
const declFile = findResultCodeFile(file.unitName);
|
||||
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||
}
|
||||
}
|
||||
|
||||
function findResultCodeFile(fileName: string) {
|
||||
const sourceFile = result.program.getSourceFile(fileName);
|
||||
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
|
||||
// Is this file going to be emitted separately
|
||||
let sourceFileName: string;
|
||||
const outFile = options.outFile || options.out;
|
||||
if (ts.isExternalModule(sourceFile) || !outFile) {
|
||||
if (options.outDir) {
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
|
||||
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
|
||||
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
|
||||
}
|
||||
else {
|
||||
sourceFileName = sourceFile.fileName;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Goes to single --out file
|
||||
sourceFileName = outFile;
|
||||
}
|
||||
|
||||
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
|
||||
|
||||
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
|
||||
}
|
||||
|
||||
function findUnit(fileName: string, units: { unitName: string; content: string; }[]) {
|
||||
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
|
||||
else if (isTS(file.unitName)) {
|
||||
const declFile = findResultCodeFile(file.unitName);
|
||||
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findResultCodeFile(fileName: string) {
|
||||
const sourceFile = result.program.getSourceFile(fileName);
|
||||
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
|
||||
// Is this file going to be emitted separately
|
||||
let sourceFileName: string;
|
||||
const outFile = options.outFile || options.out;
|
||||
if (!outFile) {
|
||||
if (options.outDir) {
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
|
||||
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
|
||||
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
|
||||
}
|
||||
else {
|
||||
sourceFileName = sourceFile.fileName;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Goes to single --out file
|
||||
sourceFileName = outFile;
|
||||
}
|
||||
|
||||
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
|
||||
|
||||
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
|
||||
}
|
||||
|
||||
function findUnit(fileName: string, units: TestFile[]) {
|
||||
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeLineEndings(text: string, lineEnding: string): string {
|
||||
@@ -1230,7 +1132,7 @@ namespace Harness {
|
||||
return errorOutput;
|
||||
}
|
||||
|
||||
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) {
|
||||
export function getErrorBaseline(inputFiles: TestFile[], diagnostics: ts.Diagnostic[]) {
|
||||
diagnostics.sort(ts.compareDiagnostics);
|
||||
const outputLines: string[] = [];
|
||||
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
|
||||
@@ -1371,16 +1273,6 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
/** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */
|
||||
let harnessCompiler: HarnessCompiler;
|
||||
|
||||
/** Returns the singleton harness compiler instance for generating and running tests.
|
||||
If required a fresh compiler instance will be created, otherwise the existing singleton will be re-used.
|
||||
*/
|
||||
export function getCompiler() {
|
||||
return harnessCompiler = harnessCompiler || new HarnessCompiler();
|
||||
}
|
||||
|
||||
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
|
||||
export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) {
|
||||
// NEWTODO: Re-implement 'compileString'
|
||||
@@ -1431,7 +1323,7 @@ namespace Harness {
|
||||
constructor(fileResults: GeneratedFile[], errors: ts.Diagnostic[], public program: ts.Program,
|
||||
public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) {
|
||||
|
||||
fileResults.forEach(emittedFile => {
|
||||
for (const emittedFile of fileResults) {
|
||||
if (isDTS(emittedFile.fileName)) {
|
||||
// .d.ts file, add to declFiles emit
|
||||
this.declFilesCode.push(emittedFile);
|
||||
@@ -1446,7 +1338,7 @@ namespace Harness {
|
||||
else {
|
||||
throw new Error("Unrecognized file extension for file " + emittedFile.fileName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.errors = errors;
|
||||
}
|
||||
@@ -1555,7 +1447,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
// normalize the fileName for the single file case
|
||||
currentFileName = testUnitData.length > 0 ? currentFileName : Path.getFileName(fileName);
|
||||
currentFileName = testUnitData.length > 0 || currentFileName ? currentFileName : Path.getFileName(fileName);
|
||||
|
||||
// EOF, push whatever remains
|
||||
const newTestFile2 = {
|
||||
@@ -1674,7 +1566,7 @@ namespace Harness {
|
||||
const encoded_actual = Utils.encodeString(actual);
|
||||
if (expected != encoded_actual) {
|
||||
// Overwrite & issue error
|
||||
const errMsg = "The baseline file " + relativeFileName + " has changed";
|
||||
const errMsg = "The baseline file " + relativeFileName + " has changed.";
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
}
|
||||
@@ -1711,12 +1603,9 @@ namespace Harness {
|
||||
return filePath.indexOf(Harness.libFolder) === 0;
|
||||
}
|
||||
|
||||
export function getDefaultLibraryFile(io: Harness.IO): { unitName: string, content: string } {
|
||||
export function getDefaultLibraryFile(io: Harness.IO): Harness.Compiler.TestFile {
|
||||
const libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts";
|
||||
return {
|
||||
unitName: libFile,
|
||||
content: io.readFile(libFile)
|
||||
};
|
||||
return { unitName: libFile, content: io.readFile(libFile) };
|
||||
}
|
||||
|
||||
if (Error) (<any>Error).stackTraceLimit = 1;
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Harness.LanguageService {
|
||||
export class ScriptInfo {
|
||||
public version: number = 1;
|
||||
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
|
||||
public lineMap: number[] = undefined;
|
||||
private lineMap: number[] = undefined;
|
||||
|
||||
constructor(public fileName: string, public content: string) {
|
||||
this.setContent(content);
|
||||
@@ -15,7 +15,11 @@ namespace Harness.LanguageService {
|
||||
|
||||
private setContent(content: string): void {
|
||||
this.content = content;
|
||||
this.lineMap = ts.computeLineStarts(content);
|
||||
this.lineMap = undefined;
|
||||
}
|
||||
|
||||
public getLineMap(): number[] {
|
||||
return this.lineMap || (this.lineMap = ts.computeLineStarts(this.content));
|
||||
}
|
||||
|
||||
public updateContent(content: string): void {
|
||||
@@ -153,7 +157,7 @@ namespace Harness.LanguageService {
|
||||
throw new Error("No script with name '" + fileName + "'");
|
||||
}
|
||||
|
||||
public openFile(fileName: string): void {
|
||||
public openFile(fileName: string, content?: string): void {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +168,7 @@ namespace Harness.LanguageService {
|
||||
const script: ScriptInfo = this.fileNameToScript[fileName];
|
||||
assert.isNotNull(script);
|
||||
|
||||
return ts.computeLineAndCharacterOfPosition(script.lineMap, position);
|
||||
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,9 +497,9 @@ namespace Harness.LanguageService {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
openFile(fileName: string): void {
|
||||
super.openFile(fileName);
|
||||
this.client.openFile(fileName);
|
||||
openFile(fileName: string, content?: string): void {
|
||||
super.openFile(fileName, content);
|
||||
this.client.openFile(fileName, content);
|
||||
}
|
||||
|
||||
editScript(fileName: string, start: number, end: number, newText: string) {
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Playback {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return findResultByFields(replayLog.fileExists, { path }, false);
|
||||
return findResultByFields(replayLog.fileExists, { path }, /*defaultValue*/ false);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
+119
-67
@@ -7,19 +7,11 @@ interface ProjectRunnerTestCase {
|
||||
scenario: string;
|
||||
projectRoot: string; // project where it lives - this also is the current directory when compiling
|
||||
inputFiles: string[]; // list of input files to be given to program
|
||||
out?: string; // --out
|
||||
outDir?: string; // --outDir
|
||||
sourceMap?: boolean; // --map
|
||||
mapRoot?: string; // --mapRoot
|
||||
resolveMapRoot?: boolean; // should we resolve this map root and give compiler the absolute disk path as map root?
|
||||
sourceRoot?: string; // --sourceRoot
|
||||
resolveSourceRoot?: boolean; // should we resolve this source root and give compiler the absolute disk path as map root?
|
||||
declaration?: boolean; // --d
|
||||
baselineCheck?: boolean; // Verify the baselines of output files, if this is false, we will write to output to the disk but there is no verification of baselines
|
||||
runTest?: boolean; // Run the resulting test
|
||||
bug?: string; // If there is any bug associated with this test case
|
||||
noResolve?: boolean;
|
||||
rootDir?: string; // --rootDir
|
||||
}
|
||||
|
||||
interface ProjectRunnerTestCaseResolutionInfo extends ProjectRunnerTestCase {
|
||||
@@ -34,14 +26,14 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
|
||||
|
||||
interface CompileProjectFilesResult {
|
||||
moduleKind: ts.ModuleKind;
|
||||
program: ts.Program;
|
||||
program?: ts.Program;
|
||||
compilerOptions?: ts.CompilerOptions;
|
||||
errors: ts.Diagnostic[];
|
||||
sourceMapData: ts.SourceMapData[];
|
||||
sourceMapData?: ts.SourceMapData[];
|
||||
}
|
||||
|
||||
interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
|
||||
outputFiles: BatchCompileProjectTestCaseEmittedFile[];
|
||||
nonSubfolderDiskFiles: number;
|
||||
outputFiles?: BatchCompileProjectTestCaseEmittedFile[];
|
||||
}
|
||||
|
||||
class ProjectRunner extends RunnerBase {
|
||||
@@ -59,7 +51,7 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
private runProjectTestCase(testCaseFileName: string) {
|
||||
let testCase: ProjectRunnerTestCase;
|
||||
let testCase: ProjectRunnerTestCase & ts.CompilerOptions;
|
||||
|
||||
let testFileText: string = null;
|
||||
try {
|
||||
@@ -70,7 +62,7 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
try {
|
||||
testCase = <ProjectRunnerTestCase>JSON.parse(testFileText);
|
||||
testCase = <ProjectRunnerTestCase & ts.CompilerOptions>JSON.parse(testFileText);
|
||||
}
|
||||
catch (e) {
|
||||
assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
|
||||
@@ -128,9 +120,10 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[],
|
||||
getSourceFileTextImpl: (fileName: string) => string,
|
||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult {
|
||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void,
|
||||
compilerOptions: ts.CompilerOptions): CompileProjectFilesResult {
|
||||
|
||||
const program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
|
||||
const program = ts.createProgram(getInputFiles(), compilerOptions, createCompilerHost());
|
||||
let errors = ts.getPreEmitDiagnostics(program);
|
||||
|
||||
const emitResult = program.emit();
|
||||
@@ -155,21 +148,6 @@ class ProjectRunner extends RunnerBase {
|
||||
sourceMapData
|
||||
};
|
||||
|
||||
function createCompilerOptions(): ts.CompilerOptions {
|
||||
return {
|
||||
declaration: !!testCase.declaration,
|
||||
sourceMap: !!testCase.sourceMap,
|
||||
outFile: testCase.out,
|
||||
outDir: testCase.outDir,
|
||||
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot,
|
||||
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
|
||||
module: moduleKind,
|
||||
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
|
||||
noResolve: testCase.noResolve,
|
||||
rootDir: testCase.rootDir
|
||||
};
|
||||
}
|
||||
|
||||
function getSourceFileText(fileName: string): string {
|
||||
const text = getSourceFileTextImpl(fileName);
|
||||
return text !== undefined ? text : getSourceFileTextImpl(ts.getNormalizedAbsolutePath(fileName, getCurrentDirectory()));
|
||||
@@ -209,23 +187,105 @@ class ProjectRunner extends RunnerBase {
|
||||
let nonSubfolderDiskFiles = 0;
|
||||
|
||||
const outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
||||
let inputFiles = testCase.inputFiles;
|
||||
let compilerOptions = createCompilerOptions();
|
||||
|
||||
const projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
|
||||
let configFileName: string;
|
||||
if (compilerOptions.project) {
|
||||
// Parse project
|
||||
configFileName = ts.normalizePath(ts.combinePaths(compilerOptions.project, "tsconfig.json"));
|
||||
assert(!inputFiles || inputFiles.length === 0, "cannot specify input files and project option together");
|
||||
}
|
||||
else if (!inputFiles || inputFiles.length === 0) {
|
||||
configFileName = ts.findConfigFile("", fileExists);
|
||||
}
|
||||
|
||||
if (configFileName) {
|
||||
const result = ts.readConfigFile(configFileName, getSourceFileText);
|
||||
if (result.error) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: [result.error]
|
||||
};
|
||||
}
|
||||
|
||||
const configObject = result.config;
|
||||
const configParseResult = ts.parseJsonConfigFileContent(configObject, { readDirectory }, ts.getDirectoryPath(configFileName), compilerOptions);
|
||||
if (configParseResult.errors.length > 0) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: configParseResult.errors
|
||||
};
|
||||
}
|
||||
inputFiles = configParseResult.fileNames;
|
||||
compilerOptions = configParseResult.options;
|
||||
}
|
||||
|
||||
const projectCompilerResult = compileProjectFiles(moduleKind, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
|
||||
return {
|
||||
moduleKind,
|
||||
program: projectCompilerResult.program,
|
||||
compilerOptions,
|
||||
sourceMapData: projectCompilerResult.sourceMapData,
|
||||
outputFiles,
|
||||
errors: projectCompilerResult.errors,
|
||||
nonSubfolderDiskFiles,
|
||||
};
|
||||
|
||||
function createCompilerOptions() {
|
||||
// Set the special options that depend on other testcase options
|
||||
const compilerOptions: ts.CompilerOptions = {
|
||||
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot,
|
||||
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
|
||||
module: moduleKind,
|
||||
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
|
||||
};
|
||||
// Set the values specified using json
|
||||
const optionNameMap: ts.Map<ts.CommandLineOption> = {};
|
||||
ts.forEach(ts.optionDeclarations, option => {
|
||||
optionNameMap[option.name] = option;
|
||||
});
|
||||
for (const name in testCase) {
|
||||
if (name !== "mapRoot" && name !== "sourceRoot" && ts.hasProperty(optionNameMap, name)) {
|
||||
const option = optionNameMap[name];
|
||||
const optType = option.type;
|
||||
let value = <any>testCase[name];
|
||||
if (typeof optType !== "string") {
|
||||
const key = value.toLowerCase();
|
||||
if (ts.hasProperty(optType, key)) {
|
||||
value = optType[key];
|
||||
}
|
||||
}
|
||||
compilerOptions[option.name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
function getFileNameInTheProjectTest(fileName: string): string {
|
||||
return ts.isRootedDiskPath(fileName)
|
||||
? fileName
|
||||
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName);
|
||||
}
|
||||
|
||||
function readDirectory(rootDir: string, extension: string, exclude: string[]): string[] {
|
||||
const harnessReadDirectoryResult = Harness.IO.readDirectory(getFileNameInTheProjectTest(rootDir), extension, exclude);
|
||||
const result: string[] = [];
|
||||
for (let i = 0; i < harnessReadDirectoryResult.length; i++) {
|
||||
result[i] = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, harnessReadDirectoryResult[i],
|
||||
getCurrentDirectory(), Harness.Compiler.getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function fileExists(fileName: string): boolean {
|
||||
return Harness.IO.fileExists(getFileNameInTheProjectTest(fileName));
|
||||
}
|
||||
|
||||
function getSourceFileText(fileName: string): string {
|
||||
let text: string = undefined;
|
||||
try {
|
||||
text = Harness.IO.readFile(ts.isRootedDiskPath(fileName)
|
||||
? fileName
|
||||
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName));
|
||||
text = Harness.IO.readFile(getFileNameInTheProjectTest(fileName));
|
||||
}
|
||||
catch (e) {
|
||||
// text doesn't get defined.
|
||||
@@ -288,13 +348,16 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
|
||||
const allInputFiles: { emittedFileName: string; code: string; }[] = [];
|
||||
if (!compilerResult.program) {
|
||||
return;
|
||||
}
|
||||
const compilerOptions = compilerResult.program.getCompilerOptions();
|
||||
|
||||
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
|
||||
if (Harness.Compiler.isDTS(sourceFile.fileName)) {
|
||||
if (ts.isDeclarationFile(sourceFile)) {
|
||||
allInputFiles.unshift({ emittedFileName: sourceFile.fileName, code: sourceFile.text });
|
||||
}
|
||||
else if (ts.shouldEmitToOwnFile(sourceFile, compilerResult.program.getCompilerOptions())) {
|
||||
else if (!(compilerOptions.outFile || compilerOptions.out)) {
|
||||
let emitOutputFilePathWithoutExtension: string = undefined;
|
||||
if (compilerOptions.outDir) {
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program.getCurrentDirectory());
|
||||
@@ -320,7 +383,8 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
});
|
||||
|
||||
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile);
|
||||
// Dont allow config files since we are compiling existing source options
|
||||
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions);
|
||||
|
||||
function findOutpuDtsFile(fileName: string) {
|
||||
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
|
||||
@@ -346,11 +410,16 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
||||
const inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||
const inputFiles = compilerResult.program ? ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||
sourceFile => sourceFile.fileName !== "lib.d.ts"),
|
||||
sourceFile => {
|
||||
return { unitName: RunnerBase.removeFullPaths(sourceFile.fileName), content: sourceFile.text };
|
||||
});
|
||||
return {
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
};
|
||||
}) : [];
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
@@ -363,30 +432,13 @@ class ProjectRunner extends RunnerBase {
|
||||
let compilerResult: BatchCompileProjectTestCaseResult;
|
||||
|
||||
function getCompilerResolutionInfo() {
|
||||
const resolutionInfo: ProjectRunnerTestCaseResolutionInfo = {
|
||||
scenario: testCase.scenario,
|
||||
projectRoot: testCase.projectRoot,
|
||||
inputFiles: testCase.inputFiles,
|
||||
out: testCase.out,
|
||||
outDir: testCase.outDir,
|
||||
sourceMap: testCase.sourceMap,
|
||||
mapRoot: testCase.mapRoot,
|
||||
resolveMapRoot: testCase.resolveMapRoot,
|
||||
sourceRoot: testCase.sourceRoot,
|
||||
resolveSourceRoot: testCase.resolveSourceRoot,
|
||||
declaration: testCase.declaration,
|
||||
baselineCheck: testCase.baselineCheck,
|
||||
runTest: testCase.runTest,
|
||||
bug: testCase.bug,
|
||||
rootDir: testCase.rootDir,
|
||||
resolvedInputFiles: ts.map(compilerResult.program.getSourceFiles(), inputFile => {
|
||||
return ts.convertToRelativePath(inputFile.fileName, getCurrentDirectory(), path => Harness.Compiler.getCanonicalFileName(path));
|
||||
}),
|
||||
emittedFiles: ts.map(compilerResult.outputFiles, outputFile => {
|
||||
return ts.convertToRelativePath(outputFile.emittedFileName, getCurrentDirectory(), path => Harness.Compiler.getCanonicalFileName(path));
|
||||
})
|
||||
};
|
||||
|
||||
const resolutionInfo: ProjectRunnerTestCaseResolutionInfo & ts.CompilerOptions = JSON.parse(JSON.stringify(testCase));
|
||||
resolutionInfo.resolvedInputFiles = ts.map(compilerResult.program.getSourceFiles(), inputFile => {
|
||||
return ts.convertToRelativePath(inputFile.fileName, getCurrentDirectory(), path => Harness.Compiler.getCanonicalFileName(path));
|
||||
});
|
||||
resolutionInfo.emittedFiles = ts.map(compilerResult.outputFiles, outputFile => {
|
||||
return ts.convertToRelativePath(outputFile.emittedFileName, getCurrentDirectory(), path => Harness.Compiler.getCanonicalFileName(path));
|
||||
});
|
||||
return resolutionInfo;
|
||||
}
|
||||
|
||||
@@ -442,7 +494,7 @@ class ProjectRunner extends RunnerBase {
|
||||
it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
if (!compilerResult.errors.length && testCase.declaration) {
|
||||
const dTsCompileResult = compileCompileDTsFiles(compilerResult);
|
||||
if (dTsCompileResult.errors.length) {
|
||||
if (dTsCompileResult && dTsCompileResult.errors.length) {
|
||||
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
|
||||
return getErrorsBaseline(dTsCompileResult);
|
||||
});
|
||||
|
||||
+13
-11
@@ -27,8 +27,8 @@ namespace RWC {
|
||||
|
||||
export function runRWCTest(jsonPath: string) {
|
||||
describe("Testing a RWC project: " + jsonPath, () => {
|
||||
let inputFiles: { unitName: string; content: string; }[] = [];
|
||||
let otherFiles: { unitName: string; content: string; }[] = [];
|
||||
let inputFiles: Harness.Compiler.TestFile[] = [];
|
||||
let otherFiles: Harness.Compiler.TestFile[] = [];
|
||||
let compilerResult: Harness.Compiler.CompilerResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
let baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
@@ -55,7 +55,6 @@ namespace RWC {
|
||||
});
|
||||
|
||||
it("can compile", () => {
|
||||
const harnessCompiler = Harness.Compiler.getCompiler();
|
||||
let opts: ts.ParsedCommandLine;
|
||||
|
||||
const ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
@@ -71,8 +70,6 @@ namespace RWC {
|
||||
});
|
||||
|
||||
runWithIOLog(ioLog, oldIO => {
|
||||
harnessCompiler.reset();
|
||||
|
||||
let fileNames = opts.fileNames;
|
||||
|
||||
const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined);
|
||||
@@ -128,17 +125,21 @@ namespace RWC {
|
||||
opts.options.noLib = true;
|
||||
|
||||
// Emit the results
|
||||
compilerOptions = harnessCompiler.compileFiles(
|
||||
compilerOptions = null;
|
||||
const output = Harness.Compiler.compileFiles(
|
||||
inputFiles,
|
||||
otherFiles,
|
||||
newCompilerResults => { compilerResult = newCompilerResults; },
|
||||
/*settingsCallback*/ undefined, opts.options,
|
||||
/* harnessOptions */ undefined,
|
||||
opts.options,
|
||||
// Since each RWC json file specifies its current directory in its json file, we need
|
||||
// to pass this information in explicitly instead of acquiring it from the process.
|
||||
currentDirectory);
|
||||
|
||||
compilerOptions = output.options;
|
||||
compilerResult = output.result;
|
||||
});
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string) {
|
||||
function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile {
|
||||
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
|
||||
let content: string = null;
|
||||
try {
|
||||
@@ -201,8 +202,9 @@ namespace RWC {
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
|
||||
const declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
|
||||
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(
|
||||
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined, compilerOptions, currentDirectory);
|
||||
|
||||
if (declFileCompilationResult.declResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,6 @@ namespace Harness.SourceMapRecoder {
|
||||
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
|
||||
}
|
||||
// 5. Check if there is name:
|
||||
decodeOfEncodedMapping.nameIndex = -1;
|
||||
if (!isSourceMappingSegmentEnd()) {
|
||||
prevNameIndex += base64VLQFormatDecode();
|
||||
decodeOfEncodedMapping.nameIndex = prevNameIndex;
|
||||
@@ -190,7 +189,7 @@ namespace Harness.SourceMapRecoder {
|
||||
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
|
||||
}
|
||||
|
||||
createErrorIfCondition(true, "No encoded entry found");
|
||||
createErrorIfCondition(/*condition*/ true, "No encoded entry found");
|
||||
}
|
||||
|
||||
export function hasCompletedDecoding() {
|
||||
@@ -249,7 +248,7 @@ namespace Harness.SourceMapRecoder {
|
||||
mapString += " name (" + sourceMapNames[mapEntry.nameIndex] + ")";
|
||||
}
|
||||
else {
|
||||
if (mapEntry.nameIndex !== -1 || getAbsentNameIndex) {
|
||||
if ((mapEntry.nameIndex && mapEntry.nameIndex !== -1) || getAbsentNameIndex) {
|
||||
mapString += " nameIndex (" + mapEntry.nameIndex + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
class Test262BaselineRunner extends RunnerBase {
|
||||
private static basePath = "internal/cases/test262";
|
||||
private static helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
|
||||
private static helperFile = {
|
||||
private static helperFile: Harness.Compiler.TestFile = {
|
||||
unitName: Test262BaselineRunner.helpersFilePath,
|
||||
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath)
|
||||
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath),
|
||||
};
|
||||
private static testFileExtensionRegex = /\.js$/;
|
||||
private static options: ts.CompilerOptions = {
|
||||
@@ -31,8 +31,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
let testState: {
|
||||
filename: string;
|
||||
compilerResult: Harness.Compiler.CompilerResult;
|
||||
inputFiles: { unitName: string; content: string }[];
|
||||
program: ts.Program;
|
||||
inputFiles: Harness.Compiler.TestFile[];
|
||||
};
|
||||
|
||||
before(() => {
|
||||
@@ -40,8 +39,9 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
const testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
|
||||
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
|
||||
|
||||
const inputFiles = testCaseContent.testUnitData.map(unit => {
|
||||
return { unitName: Test262BaselineRunner.getTestFilePath(unit.name), content: unit.content };
|
||||
const inputFiles: Harness.Compiler.TestFile[] = testCaseContent.testUnitData.map(unit => {
|
||||
const unitName = Test262BaselineRunner.getTestFilePath(unit.name);
|
||||
return { unitName, content: unit.content };
|
||||
});
|
||||
|
||||
// Emit the results
|
||||
@@ -49,13 +49,16 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
filename: testFilename,
|
||||
inputFiles: inputFiles,
|
||||
compilerResult: undefined,
|
||||
program: undefined,
|
||||
};
|
||||
|
||||
Harness.Compiler.getCompiler().compileFiles([Test262BaselineRunner.helperFile].concat(inputFiles), /*otherFiles*/ [], (compilerResult, program) => {
|
||||
testState.compilerResult = compilerResult;
|
||||
testState.program = program;
|
||||
}, /*settingsCallback*/ undefined, Test262BaselineRunner.options);
|
||||
const output = Harness.Compiler.compileFiles(
|
||||
[Test262BaselineRunner.helperFile].concat(inputFiles),
|
||||
/*otherFiles*/ [],
|
||||
/* harnessOptions */ undefined,
|
||||
Test262BaselineRunner.options,
|
||||
/* currentDirectory */ undefined
|
||||
);
|
||||
testState.compilerResult = output.result;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
@@ -80,14 +83,14 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it("satisfies inletiants", () => {
|
||||
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
it("satisfies invariants", () => {
|
||||
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
|
||||
});
|
||||
|
||||
it("has the expected AST", () => {
|
||||
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
|
||||
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
return Utils.sourceFileToJSON(sourceFile);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
Vendored
+13
-10
@@ -2058,6 +2058,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven
|
||||
* Gets or sets the version attribute specified in the declaration of an XML document.
|
||||
*/
|
||||
xmlVersion: string;
|
||||
currentScript: HTMLScriptElement;
|
||||
adoptNode(source: Node): Node;
|
||||
captureEvents(): void;
|
||||
clear(): void;
|
||||
@@ -2977,6 +2978,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec
|
||||
webkitRequestFullScreen(): void;
|
||||
webkitRequestFullscreen(): void;
|
||||
getElementsByClassName(classNames: string): NodeListOf<Element>;
|
||||
matches(selector: string): boolean;
|
||||
addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
@@ -3961,7 +3963,6 @@ interface HTMLElement extends Element {
|
||||
title: string;
|
||||
blur(): void;
|
||||
click(): void;
|
||||
contains(child: HTMLElement): boolean;
|
||||
dragDrop(): boolean;
|
||||
focus(): void;
|
||||
insertAdjacentElement(position: string, insertedElement: Element): Element;
|
||||
@@ -6135,7 +6136,7 @@ interface HTMLSelectElement extends HTMLElement {
|
||||
* Sets or retrieves the name of the object.
|
||||
*/
|
||||
name: string;
|
||||
options: HTMLSelectElement;
|
||||
options: HTMLCollection;
|
||||
/**
|
||||
* When present, marks an element that can't be submitted without a value.
|
||||
*/
|
||||
@@ -6421,19 +6422,19 @@ interface HTMLTableElement extends HTMLElement {
|
||||
/**
|
||||
* Creates an empty caption element in the table.
|
||||
*/
|
||||
createCaption(): HTMLElement;
|
||||
createCaption(): HTMLTableCaptionElement;
|
||||
/**
|
||||
* Creates an empty tBody element in the table.
|
||||
*/
|
||||
createTBody(): HTMLElement;
|
||||
createTBody(): HTMLTableSectionElement;
|
||||
/**
|
||||
* Creates an empty tFoot element in the table.
|
||||
*/
|
||||
createTFoot(): HTMLElement;
|
||||
createTFoot(): HTMLTableSectionElement;
|
||||
/**
|
||||
* Returns the tHead element object if successful, or null otherwise.
|
||||
*/
|
||||
createTHead(): HTMLElement;
|
||||
createTHead(): HTMLTableSectionElement;
|
||||
/**
|
||||
* Deletes the caption element and its contents from the table.
|
||||
*/
|
||||
@@ -6455,7 +6456,7 @@ interface HTMLTableElement extends HTMLElement {
|
||||
* Creates a new row (tr) in the table, and adds the row to the rows collection.
|
||||
* @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection.
|
||||
*/
|
||||
insertRow(index?: number): HTMLElement;
|
||||
insertRow(index?: number): HTMLTableRowElement;
|
||||
}
|
||||
|
||||
declare var HTMLTableElement: {
|
||||
@@ -6506,7 +6507,7 @@ interface HTMLTableRowElement extends HTMLElement, HTMLTableAlignment {
|
||||
* Creates a new cell in the table row, and adds the cell to the cells collection.
|
||||
* @param index Number that specifies where to insert the cell in the tr. The default value is -1, which appends the new cell to the end of the cells collection.
|
||||
*/
|
||||
insertCell(index?: number): HTMLElement;
|
||||
insertCell(index?: number): HTMLTableCellElement;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
@@ -6533,7 +6534,7 @@ interface HTMLTableSectionElement extends HTMLElement, HTMLTableAlignment {
|
||||
* Creates a new row (tr) in the table, and adds the row to the rows collection.
|
||||
* @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection.
|
||||
*/
|
||||
insertRow(index?: number): HTMLElement;
|
||||
insertRow(index?: number): HTMLTableRowElement;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
@@ -7071,7 +7072,7 @@ declare var IDBVersionChangeEvent: {
|
||||
}
|
||||
|
||||
interface ImageData {
|
||||
data: number[];
|
||||
data: Uint8ClampedArray;
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
@@ -7869,6 +7870,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte
|
||||
getGamepads(): Gamepad[];
|
||||
javaEnabled(): boolean;
|
||||
msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
|
||||
vibrate(pattern: number | number[]): boolean;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
@@ -7909,6 +7911,7 @@ interface Node extends EventTarget {
|
||||
normalize(): void;
|
||||
removeChild(oldChild: Node): Node;
|
||||
replaceChild(newChild: Node, oldChild: Node): Node;
|
||||
contains(node: Node): boolean;
|
||||
ATTRIBUTE_NODE: number;
|
||||
CDATA_SECTION_NODE: number;
|
||||
COMMENT_NODE: number;
|
||||
|
||||
Vendored
+1
-1
@@ -460,7 +460,7 @@ declare var IDBVersionChangeEvent: {
|
||||
}
|
||||
|
||||
interface ImageData {
|
||||
data: number[];
|
||||
data: Uint8ClampedArray;
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
@@ -120,8 +120,8 @@ namespace ts.server {
|
||||
return response;
|
||||
}
|
||||
|
||||
openFile(fileName: string): void {
|
||||
var args: protocol.FileRequestArgs = { file: fileName };
|
||||
openFile(fileName: string, content?: string): void {
|
||||
var args: protocol.OpenRequestArgs = { file: fileName, fileContent: content };
|
||||
this.processRequest(CommandNames.Open, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
openReferencedFile(filename: string) {
|
||||
return this.projectService.openFile(filename, false);
|
||||
return this.projectService.openFile(filename, /*openedByClient*/ false);
|
||||
}
|
||||
|
||||
getRootFiles() {
|
||||
@@ -564,7 +564,7 @@ namespace ts.server {
|
||||
// If a change was made inside "folder/file", node will trigger the callback twice:
|
||||
// one with the fileName being "folder/file", and the other one with "folder".
|
||||
// We don't respond to the second one.
|
||||
if (fileName && !ts.isSupportedSourceFileName(fileName)) {
|
||||
if (fileName && !ts.isSupportedSourceFileName(fileName, project.projectOptions ? project.projectOptions.compilerOptions : undefined)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1006,14 +1006,15 @@ namespace ts.server {
|
||||
|
||||
/**
|
||||
* @param filename is absolute pathname
|
||||
* @param fileContent is a known version of the file content that is more up to date than the one on disk
|
||||
*/
|
||||
openFile(fileName: string, openedByClient: boolean) {
|
||||
openFile(fileName: string, openedByClient: boolean, fileContent?: string) {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let info = ts.lookUp(this.filenameToScriptInfo, fileName);
|
||||
if (!info) {
|
||||
let content: string;
|
||||
if (this.host.fileExists(fileName)) {
|
||||
content = this.host.readFile(fileName);
|
||||
content = fileContent || this.host.readFile(fileName);
|
||||
}
|
||||
if (!content) {
|
||||
if (openedByClient) {
|
||||
@@ -1030,6 +1031,9 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
if (info) {
|
||||
if (fileContent) {
|
||||
info.svc.reload(fileContent);
|
||||
}
|
||||
if (openedByClient) {
|
||||
info.isOpen = true;
|
||||
}
|
||||
@@ -1060,10 +1064,11 @@ namespace ts.server {
|
||||
/**
|
||||
* Open file whose contents is managed by the client
|
||||
* @param filename is absolute pathname
|
||||
* @param fileContent is a known version of the file content that is more up to date than the one on disk
|
||||
*/
|
||||
openClientFile(fileName: string) {
|
||||
openClientFile(fileName: string, fileContent?: string) {
|
||||
this.openOrUpdateConfiguredProjectForFile(fileName);
|
||||
const info = this.openFile(fileName, true);
|
||||
const info = this.openFile(fileName, /*openedByClient*/ true, fileContent);
|
||||
this.addOpenFile(info);
|
||||
this.printProjects();
|
||||
return info;
|
||||
@@ -1272,7 +1277,7 @@ namespace ts.server {
|
||||
for (const fileName of fileNamesToAdd) {
|
||||
let info = this.getScriptInfo(fileName);
|
||||
if (!info) {
|
||||
info = this.openFile(fileName, false);
|
||||
info = this.openFile(fileName, /*openedByClient*/ false);
|
||||
}
|
||||
else {
|
||||
// if the root file was opened by client, it would belong to either
|
||||
|
||||
Vendored
+5
@@ -513,6 +513,11 @@ declare namespace ts.server.protocol {
|
||||
* Information found in an "open" request.
|
||||
*/
|
||||
export interface OpenRequestArgs extends FileRequestArgs {
|
||||
/**
|
||||
* Used when a version of the file content is known to be more up to date than the one on disk.
|
||||
* Then the known content will be used upon opening instead of the disk copy
|
||||
*/
|
||||
fileContent?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -532,9 +532,13 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
private openClientFile(fileName: string) {
|
||||
/**
|
||||
* @param fileName is the name of the file to be opened
|
||||
* @param fileContent is a version of the file content that is known to be more up to date than the one on disk
|
||||
*/
|
||||
private openClientFile(fileName: string, fileContent?: string) {
|
||||
const file = ts.normalizePath(fileName);
|
||||
this.projectService.openClientFile(file);
|
||||
this.projectService.openClientFile(file, fileContent);
|
||||
}
|
||||
|
||||
private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody {
|
||||
@@ -897,7 +901,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getDiagnosticsForProject(delay: number, fileName: string) {
|
||||
const { configFileName, fileNames } = this.getProjectInfo(fileName, true);
|
||||
const { configFileName, fileNames } = this.getProjectInfo(fileName, /*needFileNameList*/ true);
|
||||
// No need to analyze lib.d.ts
|
||||
let fileNamesInProject = fileNames.filter((value, index, array) => value.indexOf("lib.d.ts") < 0);
|
||||
|
||||
@@ -968,7 +972,7 @@ namespace ts.server {
|
||||
},
|
||||
[CommandNames.Open]: (request: protocol.Request) => {
|
||||
const openArgs = <protocol.OpenRequestArgs>request.arguments;
|
||||
this.openClientFile(openArgs.file);
|
||||
this.openClientFile(openArgs.file, openArgs.fileContent);
|
||||
return {responseRequired: false};
|
||||
},
|
||||
[CommandNames.Quickinfo]: (request: protocol.Request) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace ts.BreakpointResolver {
|
||||
|
||||
let tokenAtLocation = getTokenAtPosition(sourceFile, position);
|
||||
let lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
|
||||
if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart()).line > lineOfPosition) {
|
||||
if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
|
||||
// Get previous token if the token is returned starts on new line
|
||||
// eg: let x =10; |--- cursor is here
|
||||
// let y = 10;
|
||||
@@ -39,16 +39,23 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(tokenAtLocation);
|
||||
|
||||
function textSpan(startNode: Node, endNode?: Node) {
|
||||
return createTextSpanFromBounds(startNode.getStart(), (endNode || startNode).getEnd());
|
||||
const start = startNode.decorators ?
|
||||
skipTrivia(sourceFile.text, startNode.decorators.end) :
|
||||
startNode.getStart(sourceFile);
|
||||
return createTextSpanFromBounds(start, (endNode || startNode).getEnd());
|
||||
}
|
||||
|
||||
function spanInNodeIfStartsOnSameLine(node: Node, otherwiseOnNode?: Node): TextSpan {
|
||||
if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart()).line) {
|
||||
if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line) {
|
||||
return spanInNode(node);
|
||||
}
|
||||
return spanInNode(otherwiseOnNode);
|
||||
}
|
||||
|
||||
function spanInNodeArray<T>(nodeArray: NodeArray<T>) {
|
||||
return createTextSpanFromBounds(skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
|
||||
}
|
||||
|
||||
function spanInPreviousNode(node: Node): TextSpan {
|
||||
return spanInNode(findPrecedingToken(node.pos, sourceFile));
|
||||
}
|
||||
@@ -65,6 +72,11 @@ namespace ts.BreakpointResolver {
|
||||
return spanInPreviousNode(node);
|
||||
}
|
||||
|
||||
if (node.parent.kind === SyntaxKind.Decorator) {
|
||||
// Set breakpoint on the decorator emit
|
||||
return spanInNode(node.parent);
|
||||
}
|
||||
|
||||
if (node.parent.kind === SyntaxKind.ForStatement) {
|
||||
// For now lets set the span on this expression, fix it later
|
||||
return textSpan(node);
|
||||
@@ -207,6 +219,9 @@ namespace ts.BreakpointResolver {
|
||||
// span in statement
|
||||
return spanInNode((<WithStatement>node).statement);
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
return spanInNodeArray(node.parent.decorators);
|
||||
|
||||
// No breakpoint in interface, type alias
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts.NavigationBar {
|
||||
export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] {
|
||||
export function getNavigationBarItems(sourceFile: SourceFile, compilerOptions: CompilerOptions): ts.NavigationBarItem[] {
|
||||
// If the source file has any child items, then it included in the tree
|
||||
// and takes lexical ownership of all other top-level items.
|
||||
let hasGlobalNode = false;
|
||||
|
||||
+97
-247
@@ -132,43 +132,43 @@ namespace ts {
|
||||
let scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
|
||||
|
||||
let emptyArray: any[] = [];
|
||||
|
||||
|
||||
const jsDocTagNames = [
|
||||
"augments",
|
||||
"author",
|
||||
"argument",
|
||||
"borrows",
|
||||
"class",
|
||||
"constant",
|
||||
"constructor",
|
||||
"constructs",
|
||||
"default",
|
||||
"deprecated",
|
||||
"description",
|
||||
"event",
|
||||
"example",
|
||||
"extends",
|
||||
"field",
|
||||
"fileOverview",
|
||||
"function",
|
||||
"ignore",
|
||||
"inner",
|
||||
"lends",
|
||||
"link",
|
||||
"memberOf",
|
||||
"name",
|
||||
"namespace",
|
||||
"param",
|
||||
"private",
|
||||
"property",
|
||||
"public",
|
||||
"requires",
|
||||
"returns",
|
||||
"see",
|
||||
"since",
|
||||
"static",
|
||||
"throws",
|
||||
"type",
|
||||
"augments",
|
||||
"author",
|
||||
"argument",
|
||||
"borrows",
|
||||
"class",
|
||||
"constant",
|
||||
"constructor",
|
||||
"constructs",
|
||||
"default",
|
||||
"deprecated",
|
||||
"description",
|
||||
"event",
|
||||
"example",
|
||||
"extends",
|
||||
"field",
|
||||
"fileOverview",
|
||||
"function",
|
||||
"ignore",
|
||||
"inner",
|
||||
"lends",
|
||||
"link",
|
||||
"memberOf",
|
||||
"name",
|
||||
"namespace",
|
||||
"param",
|
||||
"private",
|
||||
"property",
|
||||
"public",
|
||||
"requires",
|
||||
"returns",
|
||||
"see",
|
||||
"since",
|
||||
"static",
|
||||
"throws",
|
||||
"type",
|
||||
"version"
|
||||
];
|
||||
let jsDocCompletionEntries: CompletionEntry[];
|
||||
@@ -817,7 +817,7 @@ namespace ts {
|
||||
constructor(kind: SyntaxKind, pos: number, end: number) {
|
||||
super(kind, pos, end)
|
||||
}
|
||||
|
||||
|
||||
public update(newText: string, textChangeRange: TextChangeRange): SourceFile {
|
||||
return updateSourceFile(this, newText, textChangeRange);
|
||||
}
|
||||
@@ -1031,7 +1031,7 @@ namespace ts {
|
||||
|
||||
/*
|
||||
* LS host can optionally implement this method if it wants to be completely in charge of module name resolution.
|
||||
* if implementation is omitted then language service will use built-in module resolution logic and get answers to
|
||||
* if implementation is omitted then language service will use built-in module resolution logic and get answers to
|
||||
* host specific questions using 'getScriptSnapshot'.
|
||||
*/
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
|
||||
@@ -1861,7 +1861,7 @@ namespace ts {
|
||||
* - allowNonTsExtensions = true
|
||||
* - noLib = true
|
||||
* - noResolve = true
|
||||
*/
|
||||
*/
|
||||
export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput {
|
||||
let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions();
|
||||
|
||||
@@ -1901,7 +1901,7 @@ namespace ts {
|
||||
sourceMapText = text;
|
||||
}
|
||||
else {
|
||||
Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
|
||||
Debug.assert(outputText === undefined, `Unexpected multiple outputs for the file: '${name}'`);
|
||||
outputText = text;
|
||||
}
|
||||
},
|
||||
@@ -2023,7 +2023,7 @@ namespace ts {
|
||||
let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames);
|
||||
|
||||
function getKeyFromCompilationSettings(settings: CompilerOptions): string {
|
||||
return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx;
|
||||
return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + +"|" + settings.allowJs;
|
||||
}
|
||||
|
||||
function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap<DocumentRegistryEntry> {
|
||||
@@ -2320,7 +2320,7 @@ namespace ts {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2339,7 +2339,7 @@ namespace ts {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function tryConsumeDefine(): boolean {
|
||||
let token = scanner.getToken();
|
||||
if (token === SyntaxKind.Identifier && scanner.getTokenValue() === "define") {
|
||||
@@ -2365,7 +2365,7 @@ namespace ts {
|
||||
if (token !== SyntaxKind.OpenBracketToken) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// skip open bracket
|
||||
token = scanner.scan();
|
||||
let i = 0;
|
||||
@@ -2380,7 +2380,7 @@ namespace ts {
|
||||
token = scanner.scan();
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2670,7 +2670,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function createLanguageService(host: LanguageServiceHost,
|
||||
export function createLanguageService(host: LanguageServiceHost,
|
||||
documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService {
|
||||
|
||||
let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host);
|
||||
@@ -2746,7 +2746,8 @@ namespace ts {
|
||||
(oldSettings.target !== newSettings.target ||
|
||||
oldSettings.module !== newSettings.module ||
|
||||
oldSettings.noResolve !== newSettings.noResolve ||
|
||||
oldSettings.jsx !== newSettings.jsx);
|
||||
oldSettings.jsx !== newSettings.jsx ||
|
||||
oldSettings.allowJs !== newSettings.allowJs);
|
||||
|
||||
// Now create a new compiler
|
||||
let compilerHost: CompilerHost = {
|
||||
@@ -2758,10 +2759,10 @@ namespace ts {
|
||||
getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),
|
||||
writeFile: (fileName, data, writeByteOrderMark) => { },
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
fileExists: (fileName): boolean => {
|
||||
fileExists: (fileName): boolean => {
|
||||
// stub missing host functionality
|
||||
Debug.assert(!host.resolveModuleNames);
|
||||
return hostCache.getOrCreateEntry(fileName) !== undefined;
|
||||
return hostCache.getOrCreateEntry(fileName) !== undefined;
|
||||
},
|
||||
readFile: (fileName): string => {
|
||||
// stub missing host functionality
|
||||
@@ -2847,8 +2848,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function sourceFileUpToDate(sourceFile: SourceFile): boolean {
|
||||
if (!sourceFile) {
|
||||
return false;
|
||||
}
|
||||
let path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName);
|
||||
return sourceFile && sourceFile.version === hostCache.getVersion(path);
|
||||
return sourceFile.version === hostCache.getVersion(path);
|
||||
}
|
||||
|
||||
function programUpToDate(): boolean {
|
||||
@@ -2908,13 +2912,6 @@ namespace ts {
|
||||
|
||||
let targetSourceFile = getValidSourceFile(fileName);
|
||||
|
||||
// For JavaScript files, we don't want to report the normal typescript semantic errors.
|
||||
// Instead, we just report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file.
|
||||
if (isSourceFileJavaScript(targetSourceFile)) {
|
||||
return getJavaScriptSemanticDiagnostics(targetSourceFile);
|
||||
}
|
||||
|
||||
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
|
||||
// Therefore only get diagnostics for given file.
|
||||
|
||||
@@ -2928,163 +2925,6 @@ namespace ts {
|
||||
return concatenate(semanticDiagnostics, declarationDiagnostics);
|
||||
}
|
||||
|
||||
function getJavaScriptSemanticDiagnostics(sourceFile: SourceFile): Diagnostic[] {
|
||||
let diagnostics: Diagnostic[] = [];
|
||||
walk(sourceFile);
|
||||
|
||||
return diagnostics;
|
||||
|
||||
function walk(node: Node): boolean {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
let classDeclaration = <ClassDeclaration>node;
|
||||
if (checkModifiers(classDeclaration.modifiers) ||
|
||||
checkTypeParameters(classDeclaration.typeParameters)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.HeritageClause:
|
||||
let heritageClause = <HeritageClause>node;
|
||||
if (heritageClause.token === SyntaxKind.ImplementsKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
let functionDeclaration = <FunctionLikeDeclaration>node;
|
||||
if (checkModifiers(functionDeclaration.modifiers) ||
|
||||
checkTypeParameters(functionDeclaration.typeParameters) ||
|
||||
checkTypeAnnotation(functionDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableStatement:
|
||||
let variableStatement = <VariableStatement>node;
|
||||
if (checkModifiers(variableStatement.modifiers)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
let variableDeclaration = <VariableDeclaration>node;
|
||||
if (checkTypeAnnotation(variableDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
let expression = <CallExpression>node;
|
||||
if (expression.typeArguments && expression.typeArguments.length > 0) {
|
||||
let start = expression.typeArguments.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, expression.typeArguments.end - start,
|
||||
Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
let parameter = <ParameterDeclaration>node;
|
||||
if (parameter.modifiers) {
|
||||
let start = parameter.modifiers.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, parameter.modifiers.end - start,
|
||||
Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
if (parameter.questionToken) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics._0_can_only_be_used_in_a_ts_file, '?'));
|
||||
return true;
|
||||
}
|
||||
if (parameter.type) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.property_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
let typeAssertionExpression = <TypeAssertion>node;
|
||||
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.Decorator:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.decorators_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return forEachChild(node, walk);
|
||||
}
|
||||
|
||||
function checkTypeParameters(typeParameters: NodeArray<TypeParameterDeclaration>): boolean {
|
||||
if (typeParameters) {
|
||||
let start = typeParameters.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, typeParameters.end - start, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkTypeAnnotation(type: TypeNode): boolean {
|
||||
if (type) {
|
||||
diagnostics.push(createDiagnosticForNode(type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkModifiers(modifiers: ModifiersArray): boolean {
|
||||
if (modifiers) {
|
||||
for (let modifier of modifiers) {
|
||||
switch (modifier.kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
return true;
|
||||
|
||||
// These are all legal modifiers.
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getCompilerOptionsDiagnostics() {
|
||||
synchronizeHostData();
|
||||
return program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
@@ -3164,7 +3004,7 @@ namespace ts {
|
||||
log("getCompletionData: Is inside comment: " + (new Date().getTime() - start));
|
||||
|
||||
if (insideComment) {
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// Provide a full list of tag names
|
||||
if (hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
|
||||
isJsDocTagName = true;
|
||||
@@ -3197,7 +3037,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!insideJsDocTagExpression) {
|
||||
// Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
|
||||
// Proceed if the current position is in jsDoc tag expression; otherwise it is a normal
|
||||
// comment or the plain text part of a jsDoc comment, so no completion should be available
|
||||
log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment.");
|
||||
return undefined;
|
||||
@@ -3532,6 +3372,7 @@ namespace ts {
|
||||
|
||||
function isInStringOrRegularExpressionOrTemplateLiteral(contextToken: Node): boolean {
|
||||
if (contextToken.kind === SyntaxKind.StringLiteral
|
||||
|| contextToken.kind === SyntaxKind.StringLiteralType
|
||||
|| contextToken.kind === SyntaxKind.RegularExpressionLiteral
|
||||
|| isTemplateLiteralKind(contextToken.kind)) {
|
||||
let start = contextToken.getStart();
|
||||
@@ -3718,8 +3559,8 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
if (parent &&
|
||||
parent.kind === SyntaxKind.JsxExpression &&
|
||||
parent.parent &&
|
||||
parent.kind === SyntaxKind.JsxExpression &&
|
||||
parent.parent &&
|
||||
(parent.parent.kind === SyntaxKind.JsxAttribute)) {
|
||||
return <JsxOpeningLikeElement>parent.parent.parent;
|
||||
}
|
||||
@@ -3768,7 +3609,7 @@ namespace ts {
|
||||
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A<T, |
|
||||
containingNodeKind === SyntaxKind.ArrayBindingPattern || // var [x, y|
|
||||
containingNodeKind === SyntaxKind.TypeAliasDeclaration; // type Map, K, |
|
||||
|
||||
|
||||
case SyntaxKind.DotToken:
|
||||
return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [.|
|
||||
|
||||
@@ -3982,7 +3823,7 @@ namespace ts {
|
||||
let sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
let entries: CompletionEntry[] = [];
|
||||
|
||||
|
||||
if (isRightOfDot && isSourceFileJavaScript(sourceFile)) {
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries);
|
||||
addRange(entries, getJavaScriptCompletionEntries(sourceFile, uniqueNames));
|
||||
@@ -4407,28 +4248,31 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// Method/function type parameter
|
||||
let container = getContainingFunction(location);
|
||||
if (container) {
|
||||
let signatureDeclaration = <SignatureDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent;
|
||||
let signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration);
|
||||
if (signatureDeclaration.kind === SyntaxKind.ConstructSignature) {
|
||||
displayParts.push(keywordPart(SyntaxKind.NewKeyword));
|
||||
let declaration = <Node>getDeclarationOfKind(symbol, SyntaxKind.TypeParameter);
|
||||
Debug.assert(declaration !== undefined);
|
||||
declaration = declaration.parent;
|
||||
|
||||
if (declaration) {
|
||||
if (isFunctionLikeKind(declaration.kind)) {
|
||||
const signature = typeChecker.getSignatureFromDeclaration(<SignatureDeclaration>declaration);
|
||||
if (declaration.kind === SyntaxKind.ConstructSignature) {
|
||||
displayParts.push(keywordPart(SyntaxKind.NewKeyword));
|
||||
displayParts.push(spacePart());
|
||||
}
|
||||
else if (declaration.kind !== SyntaxKind.CallSignature && (<SignatureDeclaration>declaration).name) {
|
||||
addFullSymbolName(declaration.symbol);
|
||||
}
|
||||
addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature));
|
||||
}
|
||||
else {
|
||||
// Type alias type parameter
|
||||
// For example
|
||||
// type list<T> = T[]; // Both T will go through same code path
|
||||
displayParts.push(keywordPart(SyntaxKind.TypeKeyword));
|
||||
displayParts.push(spacePart());
|
||||
addFullSymbolName(declaration.symbol);
|
||||
writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
|
||||
}
|
||||
else if (signatureDeclaration.kind !== SyntaxKind.CallSignature && signatureDeclaration.name) {
|
||||
addFullSymbolName(signatureDeclaration.symbol);
|
||||
}
|
||||
addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature));
|
||||
}
|
||||
else {
|
||||
// Type aliash type parameter
|
||||
// For example
|
||||
// type list<T> = T[]; // Both T will go through same code path
|
||||
let declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent;
|
||||
displayParts.push(keywordPart(SyntaxKind.TypeKeyword));
|
||||
displayParts.push(spacePart());
|
||||
addFullSymbolName(declaration.symbol);
|
||||
writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4601,6 +4445,7 @@ namespace ts {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.QualifiedName:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
// For the identifiers/this/super etc get the type at position
|
||||
let type = typeChecker.getTypeAtLocation(node);
|
||||
@@ -4872,6 +4717,7 @@ namespace ts {
|
||||
function getSemanticDocumentHighlights(node: Node): DocumentHighlights[] {
|
||||
if (node.kind === SyntaxKind.Identifier ||
|
||||
node.kind === SyntaxKind.ThisKeyword ||
|
||||
node.kind === SyntaxKind.ThisType ||
|
||||
node.kind === SyntaxKind.SuperKeyword ||
|
||||
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
|
||||
isNameOfExternalModuleImportOrDeclaration(node)) {
|
||||
@@ -5003,7 +4849,7 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isModifier(node.kind) && node.parent &&
|
||||
if (isModifierKind(node.kind) && node.parent &&
|
||||
(isDeclaration(node.parent) || node.parent.kind === SyntaxKind.VariableStatement)) {
|
||||
return getModifierOccurrences(node.kind, node.parent);
|
||||
}
|
||||
@@ -5567,7 +5413,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.ThisKeyword) {
|
||||
if (node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.ThisType) {
|
||||
return getReferencesForThisKeyword(node, sourceFiles);
|
||||
}
|
||||
|
||||
@@ -6049,7 +5895,7 @@ namespace ts {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
let node = getTouchingWord(sourceFile, position);
|
||||
if (!node || node.kind !== SyntaxKind.ThisKeyword) {
|
||||
if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6411,7 +6257,8 @@ namespace ts {
|
||||
|
||||
return node.parent.kind === SyntaxKind.TypeReference ||
|
||||
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent)) ||
|
||||
node.kind === SyntaxKind.ThisKeyword && !isExpression(node);
|
||||
(node.kind === SyntaxKind.ThisKeyword && !isExpression(node)) ||
|
||||
node.kind === SyntaxKind.ThisType;
|
||||
}
|
||||
|
||||
function isNamespaceReference(node: Node): boolean {
|
||||
@@ -6526,11 +6373,13 @@ namespace ts {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.QualifiedName:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.StringLiteralType:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.Identifier:
|
||||
break;
|
||||
|
||||
@@ -6578,7 +6427,7 @@ namespace ts {
|
||||
function getNavigationBarItems(fileName: string): NavigationBarItem[] {
|
||||
let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
|
||||
return NavigationBar.getNavigationBarItems(sourceFile);
|
||||
return NavigationBar.getNavigationBarItems(sourceFile, host.getCompilationSettings());
|
||||
}
|
||||
|
||||
function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
|
||||
@@ -6986,7 +6835,7 @@ namespace ts {
|
||||
else if (tokenKind === SyntaxKind.NumericLiteral) {
|
||||
return ClassificationType.numericLiteral;
|
||||
}
|
||||
else if (tokenKind === SyntaxKind.StringLiteral) {
|
||||
else if (tokenKind === SyntaxKind.StringLiteral || tokenKind === SyntaxKind.StringLiteralType) {
|
||||
return ClassificationType.stringLiteral;
|
||||
}
|
||||
else if (tokenKind === SyntaxKind.RegularExpressionLiteral) {
|
||||
@@ -7905,7 +7754,7 @@ namespace ts {
|
||||
addResult(start, end, classFromKind(token));
|
||||
|
||||
if (end >= text.length) {
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
if (token === SyntaxKind.StringLiteral || token === SyntaxKind.StringLiteralType) {
|
||||
// Check to see if we finished up on a multiline string literal.
|
||||
let tokenText = scanner.getTokenText();
|
||||
if (scanner.isUnterminated()) {
|
||||
@@ -8055,6 +7904,7 @@ namespace ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return ClassificationType.numericLiteral;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.StringLiteralType:
|
||||
return ClassificationType.stringLiteral;
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
return ClassificationType.regularExpressionLiteral;
|
||||
|
||||
@@ -257,14 +257,14 @@ namespace ts {
|
||||
return syntaxList;
|
||||
}
|
||||
|
||||
/* Gets the token whose text has range [start, end) and
|
||||
/* Gets the token whose text has range [start, end) and
|
||||
* position >= start and (position < end or (position === end && token is keyword or identifier))
|
||||
*/
|
||||
export function getTouchingWord(sourceFile: SourceFile, position: number): Node {
|
||||
return getTouchingToken(sourceFile, position, n => isWord(n.kind));
|
||||
}
|
||||
|
||||
/* Gets the token whose text has range [start, end) and position >= start
|
||||
/* Gets the token whose text has range [start, end) and position >= start
|
||||
* and (position < end or (position === end && token is keyword or identifier or numeric\string litera))
|
||||
*/
|
||||
export function getTouchingPropertyName(sourceFile: SourceFile, position: number): Node {
|
||||
@@ -391,8 +391,8 @@ namespace ts {
|
||||
const start = child.getStart(sourceFile);
|
||||
const lookInPreviousChild =
|
||||
(start >= position) || // cursor in the leading trivia
|
||||
(child.kind === SyntaxKind.JsxText && start === child.end); // whitespace only JsxText
|
||||
|
||||
(child.kind === SyntaxKind.JsxText && start === child.end); // whitespace only JsxText
|
||||
|
||||
if (lookInPreviousChild) {
|
||||
// actual start of the node is past the position - previous token should be at the end of previous child
|
||||
let candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i);
|
||||
@@ -407,7 +407,7 @@ namespace ts {
|
||||
|
||||
Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile);
|
||||
|
||||
// Here we know that none of child token nodes embrace the position,
|
||||
// Here we know that none of child token nodes embrace the position,
|
||||
// the only known case is when position is at the end of the file.
|
||||
// Try to find the rightmost token in the file without filtering.
|
||||
// Namely we are skipping the check: 'position < node.end'
|
||||
@@ -429,7 +429,7 @@ namespace ts {
|
||||
|
||||
export function isInString(sourceFile: SourceFile, position: number) {
|
||||
let token = getTokenAtPosition(sourceFile, position);
|
||||
return token && token.kind === SyntaxKind.StringLiteral && position > token.getStart();
|
||||
return token && (token.kind === SyntaxKind.StringLiteral || token.kind === SyntaxKind.StringLiteralType) && position > token.getStart();
|
||||
}
|
||||
|
||||
export function isInComment(sourceFile: SourceFile, position: number) {
|
||||
@@ -445,7 +445,7 @@ namespace ts {
|
||||
|
||||
if (token && position <= token.getStart()) {
|
||||
let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
|
||||
|
||||
// The end marker of a single-line comment does not include the newline character.
|
||||
// In the following case, we are inside a comment (^ denotes the cursor position):
|
||||
//
|
||||
@@ -565,6 +565,7 @@ namespace ts {
|
||||
|
||||
export function isStringOrRegularExpressionOrTemplateLiteral(kind: SyntaxKind): boolean {
|
||||
if (kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.StringLiteralType
|
||||
|| kind === SyntaxKind.RegularExpressionLiteral
|
||||
|| isTemplateLiteralKind(kind)) {
|
||||
return true;
|
||||
|
||||
@@ -40,6 +40,7 @@ compile(process.argv.slice(2), {
|
||||
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
var ts = require("typescript");
|
||||
function compile(fileNames, options) {
|
||||
var program = ts.createProgram(fileNames, options);
|
||||
|
||||
@@ -70,6 +70,7 @@ fileNames.forEach(fileName => {
|
||||
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
var ts = require("typescript");
|
||||
function delint(sourceFile) {
|
||||
delintNode(sourceFile);
|
||||
|
||||
@@ -22,6 +22,7 @@ console.log(JSON.stringify(result));
|
||||
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-simple-transform-function
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
var ts = require("typescript");
|
||||
var source = "let x: string = 'string'";
|
||||
var result = ts.transpile(source, { module: ts.ModuleKind.CommonJS });
|
||||
|
||||
@@ -109,6 +109,7 @@ watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS });
|
||||
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
var ts = require("typescript");
|
||||
function watch(rootFileNames, options) {
|
||||
var files = {};
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
//// [ES5For-of8.js.map]
|
||||
{"version":3,"file":"ES5For-of8.js","sourceRoot":"","sources":["ES5For-of8.ts"],"names":["foo"],"mappings":"AAAA;IACIA,MAAMA,CAACA,EAAEA,CAACA,EAAEA,CAACA,EAAEA,CAACA;AACpBA,CAACA;AACD,GAAG,CAAC,CAAY,UAAe,EAAf,MAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAA1B,cAAO,EAAP,IAA0B,CAAC;IAA3B,GAAG,EAAE,CAAC,CAAC,SAAA;IACR,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;CACnB"}
|
||||
{"version":3,"file":"ES5For-of8.js","sourceRoot":"","sources":["ES5For-of8.ts"],"names":[],"mappings":"AAAA;IACI,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACpB,CAAC;AACD,GAAG,CAAC,CAAY,UAAe,EAAf,MAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAA1B,cAAO,EAAP,IAA0B,CAAC;IAA3B,GAAG,EAAE,CAAC,CAAC,SAAA;IACR,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;CACnB"}
|
||||
@@ -34,15 +34,15 @@ sourceFile:ES5For-of8.ts
|
||||
7 > 0
|
||||
8 > }
|
||||
9 > ;
|
||||
1->Emitted(2, 5) Source(2, 5) + SourceIndex(0) name (foo)
|
||||
2 >Emitted(2, 11) Source(2, 11) + SourceIndex(0) name (foo)
|
||||
3 >Emitted(2, 12) Source(2, 12) + SourceIndex(0) name (foo)
|
||||
4 >Emitted(2, 14) Source(2, 14) + SourceIndex(0) name (foo)
|
||||
5 >Emitted(2, 15) Source(2, 15) + SourceIndex(0) name (foo)
|
||||
6 >Emitted(2, 17) Source(2, 17) + SourceIndex(0) name (foo)
|
||||
7 >Emitted(2, 18) Source(2, 18) + SourceIndex(0) name (foo)
|
||||
8 >Emitted(2, 20) Source(2, 20) + SourceIndex(0) name (foo)
|
||||
9 >Emitted(2, 21) Source(2, 21) + SourceIndex(0) name (foo)
|
||||
1->Emitted(2, 5) Source(2, 5) + SourceIndex(0)
|
||||
2 >Emitted(2, 11) Source(2, 11) + SourceIndex(0)
|
||||
3 >Emitted(2, 12) Source(2, 12) + SourceIndex(0)
|
||||
4 >Emitted(2, 14) Source(2, 14) + SourceIndex(0)
|
||||
5 >Emitted(2, 15) Source(2, 15) + SourceIndex(0)
|
||||
6 >Emitted(2, 17) Source(2, 17) + SourceIndex(0)
|
||||
7 >Emitted(2, 18) Source(2, 18) + SourceIndex(0)
|
||||
8 >Emitted(2, 20) Source(2, 20) + SourceIndex(0)
|
||||
9 >Emitted(2, 21) Source(2, 21) + SourceIndex(0)
|
||||
---
|
||||
>>>}
|
||||
1 >
|
||||
@@ -51,8 +51,8 @@ sourceFile:ES5For-of8.ts
|
||||
1 >
|
||||
>
|
||||
2 >}
|
||||
1 >Emitted(3, 1) Source(3, 1) + SourceIndex(0) name (foo)
|
||||
2 >Emitted(3, 2) Source(3, 2) + SourceIndex(0) name (foo)
|
||||
1 >Emitted(3, 1) Source(3, 1) + SourceIndex(0)
|
||||
2 >Emitted(3, 2) Source(3, 2) + SourceIndex(0)
|
||||
---
|
||||
>>>for (var _i = 0, _a = ['a', 'b', 'c']; _i < _a.length; _i++) {
|
||||
1->
|
||||
|
||||
@@ -5,6 +5,7 @@ export class C {
|
||||
export = B;
|
||||
|
||||
//// [ExportAssignment7.js]
|
||||
"use strict";
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ export class C {
|
||||
}
|
||||
|
||||
//// [ExportAssignment8.js]
|
||||
"use strict";
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
|
||||
+2
@@ -30,6 +30,7 @@ export module A {
|
||||
|
||||
|
||||
//// [part1.js]
|
||||
"use strict";
|
||||
var A;
|
||||
(function (A) {
|
||||
var Utils;
|
||||
@@ -42,6 +43,7 @@ var A;
|
||||
A.Origin = { x: 0, y: 0 };
|
||||
})(A = exports.A || (exports.A = {}));
|
||||
//// [part2.js]
|
||||
"use strict";
|
||||
var A;
|
||||
(function (A) {
|
||||
// collision with 'Origin' var in other part of merged module
|
||||
|
||||
@@ -14,6 +14,7 @@ y = moduleA; // should be error
|
||||
|
||||
|
||||
//// [aliasAssignments_moduleA.js]
|
||||
"use strict";
|
||||
var someClass = (function () {
|
||||
function someClass() {
|
||||
}
|
||||
@@ -21,6 +22,7 @@ var someClass = (function () {
|
||||
})();
|
||||
exports.someClass = someClass;
|
||||
//// [aliasAssignments_1.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasAssignments_moduleA");
|
||||
var x = moduleA;
|
||||
x = 1; // Should be error
|
||||
|
||||
@@ -23,6 +23,7 @@ var x: foo.A = foo.bar("hello"); // foo.A should be ok but foo.bar should be err
|
||||
|
||||
//// [aliasOnMergedModuleInterface_0.js]
|
||||
//// [aliasOnMergedModuleInterface_1.js]
|
||||
"use strict";
|
||||
var z;
|
||||
z.bar("hello"); // This should be ok
|
||||
var x = foo.bar("hello"); // foo.A should be ok but foo.bar should be error
|
||||
|
||||
@@ -28,6 +28,7 @@ class C2 {
|
||||
}
|
||||
|
||||
//// [aliasUsage1_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -35,6 +36,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsage1_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -50,6 +52,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsage1_main.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasUsage1_moduleA");
|
||||
var C2 = (function () {
|
||||
function C2() {
|
||||
|
||||
@@ -22,6 +22,7 @@ var xs: IHasVisualizationModel[] = [moduleA];
|
||||
var xs2: typeof moduleA[] = [moduleA];
|
||||
|
||||
//// [aliasUsageInArray_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -29,6 +30,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInArray_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -44,6 +46,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInArray_main.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasUsageInArray_moduleA");
|
||||
var xs = [moduleA];
|
||||
var xs2 = [moduleA];
|
||||
|
||||
@@ -21,6 +21,7 @@ var f = (x: IHasVisualizationModel) => x;
|
||||
f = (x) => moduleA;
|
||||
|
||||
//// [aliasUsageInFunctionExpression_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -28,6 +29,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInFunctionExpression_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -43,6 +45,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInFunctionExpression_main.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasUsageInFunctionExpression_moduleA");
|
||||
var f = function (x) { return x; };
|
||||
f = function (x) { return moduleA; };
|
||||
|
||||
@@ -25,6 +25,7 @@ var r2 = foo({ a: <IHasVisualizationModel>null });
|
||||
|
||||
|
||||
//// [aliasUsageInGenericFunction_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -32,6 +33,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInGenericFunction_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -47,6 +49,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInGenericFunction_main.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasUsageInGenericFunction_moduleA");
|
||||
function foo(x) {
|
||||
return x;
|
||||
|
||||
@@ -27,6 +27,7 @@ class N2 {
|
||||
}
|
||||
|
||||
//// [aliasUsageInIndexerOfClass_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -34,6 +35,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInIndexerOfClass_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -49,6 +51,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInIndexerOfClass_main.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasUsageInIndexerOfClass_moduleA");
|
||||
var N = (function () {
|
||||
function N() {
|
||||
|
||||
@@ -22,6 +22,7 @@ var b: { x: IHasVisualizationModel } = { x: moduleA };
|
||||
var c: { y: { z: IHasVisualizationModel } } = { y: { z: moduleA } };
|
||||
|
||||
//// [aliasUsageInObjectLiteral_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -29,6 +30,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInObjectLiteral_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -44,6 +46,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInObjectLiteral_main.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasUsageInObjectLiteral_moduleA");
|
||||
var a = { x: moduleA };
|
||||
var b = { x: moduleA };
|
||||
|
||||
@@ -25,6 +25,7 @@ var e: { x: IHasVisualizationModel } = <{ x: IHasVisualizationModel }>null || {
|
||||
var f: { x: IHasVisualizationModel } = <{ x: IHasVisualizationModel }>null ? { x: moduleA } : null;
|
||||
|
||||
//// [aliasUsageInOrExpression_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -32,6 +33,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInOrExpression_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -47,6 +49,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInOrExpression_main.js]
|
||||
"use strict";
|
||||
var moduleA = require("./aliasUsageInOrExpression_moduleA");
|
||||
var i;
|
||||
var d1 = i || moduleA;
|
||||
|
||||
@@ -25,6 +25,7 @@ class D extends C<IHasVisualizationModel> {
|
||||
}
|
||||
|
||||
//// [aliasUsageInTypeArgumentOfExtendsClause_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -32,6 +33,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInTypeArgumentOfExtendsClause_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -47,6 +49,7 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInTypeArgumentOfExtendsClause_main.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
|
||||
@@ -21,6 +21,7 @@ var i: IHasVisualizationModel;
|
||||
var m: typeof moduleA = i;
|
||||
|
||||
//// [aliasUsageInVarAssignment_backbone.js]
|
||||
"use strict";
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -28,6 +29,7 @@ var Model = (function () {
|
||||
})();
|
||||
exports.Model = Model;
|
||||
//// [aliasUsageInVarAssignment_moduleA.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
@@ -43,5 +45,6 @@ var VisualizationModel = (function (_super) {
|
||||
})(Backbone.Model);
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInVarAssignment_main.js]
|
||||
"use strict";
|
||||
var i;
|
||||
var m = i;
|
||||
|
||||
@@ -19,10 +19,13 @@ export var a = function () {
|
||||
|
||||
|
||||
//// [aliasUsedAsNameValue_0.js]
|
||||
"use strict";
|
||||
//// [aliasUsedAsNameValue_1.js]
|
||||
"use strict";
|
||||
function b(a) { return null; }
|
||||
exports.b = b;
|
||||
//// [aliasUsedAsNameValue_2.js]
|
||||
"use strict";
|
||||
///<reference path='aliasUsedAsNameValue_0.ts' />
|
||||
///<reference path='aliasUsedAsNameValue_1.ts' />
|
||||
var mod = require("./aliasUsedAsNameValue_0");
|
||||
|
||||
@@ -11,5 +11,7 @@ import moduleA = require("./aliasWithInterfaceExportAssignmentUsedInVarInitializ
|
||||
var d = b.q3;
|
||||
|
||||
//// [aliasWithInterfaceExportAssignmentUsedInVarInitializer_0.js]
|
||||
"use strict";
|
||||
//// [aliasWithInterfaceExportAssignmentUsedInVarInitializer_1.js]
|
||||
"use strict";
|
||||
var d = b.q3;
|
||||
|
||||
@@ -18,6 +18,7 @@ module M {
|
||||
|
||||
//// [aliasesInSystemModule1.js]
|
||||
System.register(['foo'], function(exports_1) {
|
||||
"use strict";
|
||||
var alias;
|
||||
var cls, cls2, x, y, z, M;
|
||||
return {
|
||||
|
||||
@@ -17,6 +17,7 @@ module M {
|
||||
|
||||
//// [aliasesInSystemModule2.js]
|
||||
System.register(["foo"], function(exports_1) {
|
||||
"use strict";
|
||||
var foo_1;
|
||||
var cls, cls2, x, y, z, M;
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//// [tests/cases/compiler/allowSyntheticDefaultImports1.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
import Namespace from "./b";
|
||||
export var x = new Namespace.Foo();
|
||||
|
||||
//// [b.ts]
|
||||
export class Foo {
|
||||
member: string;
|
||||
}
|
||||
|
||||
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
var Foo = (function () {
|
||||
function Foo() {
|
||||
}
|
||||
return Foo;
|
||||
})();
|
||||
exports.Foo = Foo;
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
var b_1 = require("./b");
|
||||
exports.x = new b_1["default"].Foo();
|
||||
@@ -0,0 +1,18 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Namespace from "./b";
|
||||
>Namespace : Symbol(Namespace, Decl(a.ts, 0, 6))
|
||||
|
||||
export var x = new Namespace.Foo();
|
||||
>x : Symbol(x, Decl(a.ts, 1, 10))
|
||||
>Namespace.Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0))
|
||||
>Namespace : Symbol(Namespace, Decl(a.ts, 0, 6))
|
||||
>Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export class Foo {
|
||||
>Foo : Symbol(Foo, Decl(b.ts, 0, 0))
|
||||
|
||||
member: string;
|
||||
>member : Symbol(member, Decl(b.ts, 0, 18))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Namespace from "./b";
|
||||
>Namespace : typeof Namespace
|
||||
|
||||
export var x = new Namespace.Foo();
|
||||
>x : Namespace.Foo
|
||||
>new Namespace.Foo() : Namespace.Foo
|
||||
>Namespace.Foo : typeof Namespace.Foo
|
||||
>Namespace : typeof Namespace
|
||||
>Foo : typeof Namespace.Foo
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
member: string;
|
||||
>member : string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/compiler/allowSyntheticDefaultImports2.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
import Namespace from "./b";
|
||||
export var x = new Namespace.Foo();
|
||||
|
||||
//// [b.ts]
|
||||
export class Foo {
|
||||
member: string;
|
||||
}
|
||||
|
||||
//// [b.js]
|
||||
System.register([], function(exports_1) {
|
||||
"use strict";
|
||||
var Foo;
|
||||
return {
|
||||
setters:[],
|
||||
execute: function() {
|
||||
Foo = (function () {
|
||||
function Foo() {
|
||||
}
|
||||
return Foo;
|
||||
})();
|
||||
exports_1("Foo", Foo);
|
||||
}
|
||||
}
|
||||
});
|
||||
//// [a.js]
|
||||
System.register(["./b"], function(exports_1) {
|
||||
"use strict";
|
||||
var b_1;
|
||||
var x;
|
||||
return {
|
||||
setters:[
|
||||
function (b_1_1) {
|
||||
b_1 = b_1_1;
|
||||
}],
|
||||
execute: function() {
|
||||
exports_1("x", x = new b_1["default"].Foo());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Namespace from "./b";
|
||||
>Namespace : Symbol(Namespace, Decl(a.ts, 0, 6))
|
||||
|
||||
export var x = new Namespace.Foo();
|
||||
>x : Symbol(x, Decl(a.ts, 1, 10))
|
||||
>Namespace.Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0))
|
||||
>Namespace : Symbol(Namespace, Decl(a.ts, 0, 6))
|
||||
>Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export class Foo {
|
||||
>Foo : Symbol(Foo, Decl(b.ts, 0, 0))
|
||||
|
||||
member: string;
|
||||
>member : Symbol(member, Decl(b.ts, 0, 18))
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Namespace from "./b";
|
||||
>Namespace : typeof Namespace
|
||||
|
||||
export var x = new Namespace.Foo();
|
||||
>x : Namespace.Foo
|
||||
>new Namespace.Foo() : Namespace.Foo
|
||||
>Namespace.Foo : typeof Namespace.Foo
|
||||
>Namespace : typeof Namespace
|
||||
>Foo : typeof Namespace.Foo
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
export class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
member: string;
|
||||
>member : string
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
tests/cases/compiler/a.ts(1,8): error TS1192: Module '"tests/cases/compiler/b"' has no default export.
|
||||
|
||||
|
||||
==== tests/cases/compiler/a.ts (1 errors) ====
|
||||
import Namespace from "./b";
|
||||
~~~~~~~~~
|
||||
!!! error TS1192: Module '"tests/cases/compiler/b"' has no default export.
|
||||
export var x = new Namespace.Foo();
|
||||
|
||||
==== tests/cases/compiler/b.ts (0 errors) ====
|
||||
export class Foo {
|
||||
member: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//// [tests/cases/compiler/allowSyntheticDefaultImports3.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
import Namespace from "./b";
|
||||
export var x = new Namespace.Foo();
|
||||
|
||||
//// [b.ts]
|
||||
export class Foo {
|
||||
member: string;
|
||||
}
|
||||
|
||||
|
||||
//// [b.js]
|
||||
System.register([], function(exports_1) {
|
||||
"use strict";
|
||||
var Foo;
|
||||
return {
|
||||
setters:[],
|
||||
execute: function() {
|
||||
Foo = (function () {
|
||||
function Foo() {
|
||||
}
|
||||
return Foo;
|
||||
})();
|
||||
exports_1("Foo", Foo);
|
||||
}
|
||||
}
|
||||
});
|
||||
//// [a.js]
|
||||
System.register(["./b"], function(exports_1) {
|
||||
"use strict";
|
||||
var b_1;
|
||||
var x;
|
||||
return {
|
||||
setters:[
|
||||
function (b_1_1) {
|
||||
b_1 = b_1_1;
|
||||
}],
|
||||
execute: function() {
|
||||
exports_1("x", x = new b_1["default"].Foo());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [tests/cases/compiler/allowSyntheticDefaultImports4.ts] ////
|
||||
|
||||
//// [b.d.ts]
|
||||
declare class Foo {
|
||||
member: string;
|
||||
}
|
||||
export = Foo;
|
||||
|
||||
//// [a.ts]
|
||||
import Foo from "./b";
|
||||
export var x = new Foo();
|
||||
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
var b_1 = require("./b");
|
||||
exports.x = new b_1["default"]();
|
||||
@@ -0,0 +1,18 @@
|
||||
=== tests/cases/compiler/b.d.ts ===
|
||||
declare class Foo {
|
||||
>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0))
|
||||
|
||||
member: string;
|
||||
>member : Symbol(member, Decl(b.d.ts, 0, 19))
|
||||
}
|
||||
export = Foo;
|
||||
>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Foo from "./b";
|
||||
>Foo : Symbol(Foo, Decl(a.ts, 0, 6))
|
||||
|
||||
export var x = new Foo();
|
||||
>x : Symbol(x, Decl(a.ts, 1, 10))
|
||||
>Foo : Symbol(Foo, Decl(a.ts, 0, 6))
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/b.d.ts ===
|
||||
declare class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
member: string;
|
||||
>member : string
|
||||
}
|
||||
export = Foo;
|
||||
>Foo : Foo
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Foo from "./b";
|
||||
>Foo : typeof Foo
|
||||
|
||||
export var x = new Foo();
|
||||
>x : Foo
|
||||
>new Foo() : Foo
|
||||
>Foo : typeof Foo
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//// [tests/cases/compiler/allowSyntheticDefaultImports5.ts] ////
|
||||
|
||||
//// [b.d.ts]
|
||||
declare class Foo {
|
||||
member: string;
|
||||
}
|
||||
export = Foo;
|
||||
|
||||
//// [a.ts]
|
||||
import Foo from "./b";
|
||||
export var x = new Foo();
|
||||
|
||||
|
||||
//// [a.js]
|
||||
System.register(["./b"], function(exports_1) {
|
||||
"use strict";
|
||||
var b_1;
|
||||
var x;
|
||||
return {
|
||||
setters:[
|
||||
function (b_1_1) {
|
||||
b_1 = b_1_1;
|
||||
}],
|
||||
execute: function() {
|
||||
exports_1("x", x = new b_1["default"]());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
=== tests/cases/compiler/b.d.ts ===
|
||||
declare class Foo {
|
||||
>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0))
|
||||
|
||||
member: string;
|
||||
>member : Symbol(member, Decl(b.d.ts, 0, 19))
|
||||
}
|
||||
export = Foo;
|
||||
>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Foo from "./b";
|
||||
>Foo : Symbol(Foo, Decl(a.ts, 0, 6))
|
||||
|
||||
export var x = new Foo();
|
||||
>x : Symbol(x, Decl(a.ts, 1, 10))
|
||||
>Foo : Symbol(Foo, Decl(a.ts, 0, 6))
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/b.d.ts ===
|
||||
declare class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
member: string;
|
||||
>member : string
|
||||
}
|
||||
export = Foo;
|
||||
>Foo : Foo
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
import Foo from "./b";
|
||||
>Foo : typeof Foo
|
||||
|
||||
export var x = new Foo();
|
||||
>x : Foo
|
||||
>new Foo() : Foo
|
||||
>Foo : typeof Foo
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
tests/cases/compiler/a.ts(1,8): error TS1192: Module '"tests/cases/compiler/b"' has no default export.
|
||||
|
||||
|
||||
==== tests/cases/compiler/b.d.ts (0 errors) ====
|
||||
declare class Foo {
|
||||
member: string;
|
||||
}
|
||||
export = Foo;
|
||||
|
||||
==== tests/cases/compiler/a.ts (1 errors) ====
|
||||
import Foo from "./b";
|
||||
~~~
|
||||
!!! error TS1192: Module '"tests/cases/compiler/b"' has no default export.
|
||||
export var x = new Foo();
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//// [tests/cases/compiler/allowSyntheticDefaultImports6.ts] ////
|
||||
|
||||
//// [b.d.ts]
|
||||
declare class Foo {
|
||||
member: string;
|
||||
}
|
||||
export = Foo;
|
||||
|
||||
//// [a.ts]
|
||||
import Foo from "./b";
|
||||
export var x = new Foo();
|
||||
|
||||
|
||||
//// [a.js]
|
||||
System.register(["./b"], function(exports_1) {
|
||||
"use strict";
|
||||
var b_1;
|
||||
var x;
|
||||
return {
|
||||
setters:[
|
||||
function (b_1_1) {
|
||||
b_1 = b_1_1;
|
||||
}],
|
||||
execute: function() {
|
||||
exports_1("x", x = new b_1["default"]());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,6 +1,40 @@
|
||||
//// [ambientClassDeclarationWithExtends.ts]
|
||||
//// [tests/cases/compiler/ambientClassDeclarationWithExtends.ts] ////
|
||||
|
||||
//// [ambientClassDeclarationExtends_singleFile.ts]
|
||||
declare class A { }
|
||||
declare class B extends A { }
|
||||
|
||||
declare class C {
|
||||
public foo;
|
||||
}
|
||||
namespace D { var x; }
|
||||
declare class D extends C { }
|
||||
|
||||
var d: C = new D();
|
||||
|
||||
//// [ambientClassDeclarationExtends_file1.ts]
|
||||
|
||||
declare class E {
|
||||
public bar;
|
||||
}
|
||||
namespace F { var y; }
|
||||
|
||||
//// [ambientClassDeclarationExtends_file2.ts]
|
||||
|
||||
declare class F extends E { }
|
||||
var f: E = new F();
|
||||
|
||||
|
||||
//// [ambientClassDeclarationWithExtends.js]
|
||||
//// [ambientClassDeclarationExtends_singleFile.js]
|
||||
var D;
|
||||
(function (D) {
|
||||
var x;
|
||||
})(D || (D = {}));
|
||||
var d = new D();
|
||||
//// [ambientClassDeclarationExtends_file1.js]
|
||||
var F;
|
||||
(function (F) {
|
||||
var y;
|
||||
})(F || (F = {}));
|
||||
//// [ambientClassDeclarationExtends_file2.js]
|
||||
var f = new F();
|
||||
|
||||
@@ -1,8 +1,50 @@
|
||||
=== tests/cases/compiler/ambientClassDeclarationWithExtends.ts ===
|
||||
=== tests/cases/compiler/ambientClassDeclarationExtends_singleFile.ts ===
|
||||
declare class A { }
|
||||
>A : Symbol(A, Decl(ambientClassDeclarationWithExtends.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(ambientClassDeclarationExtends_singleFile.ts, 0, 0))
|
||||
|
||||
declare class B extends A { }
|
||||
>B : Symbol(B, Decl(ambientClassDeclarationWithExtends.ts, 0, 19))
|
||||
>A : Symbol(A, Decl(ambientClassDeclarationWithExtends.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(ambientClassDeclarationExtends_singleFile.ts, 0, 19))
|
||||
>A : Symbol(A, Decl(ambientClassDeclarationExtends_singleFile.ts, 0, 0))
|
||||
|
||||
declare class C {
|
||||
>C : Symbol(C, Decl(ambientClassDeclarationExtends_singleFile.ts, 1, 29))
|
||||
|
||||
public foo;
|
||||
>foo : Symbol(foo, Decl(ambientClassDeclarationExtends_singleFile.ts, 3, 17))
|
||||
}
|
||||
namespace D { var x; }
|
||||
>D : Symbol(D, Decl(ambientClassDeclarationExtends_singleFile.ts, 5, 1), Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 22))
|
||||
>x : Symbol(x, Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 17))
|
||||
|
||||
declare class D extends C { }
|
||||
>D : Symbol(D, Decl(ambientClassDeclarationExtends_singleFile.ts, 5, 1), Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 22))
|
||||
>C : Symbol(C, Decl(ambientClassDeclarationExtends_singleFile.ts, 1, 29))
|
||||
|
||||
var d: C = new D();
|
||||
>d : Symbol(d, Decl(ambientClassDeclarationExtends_singleFile.ts, 9, 3))
|
||||
>C : Symbol(C, Decl(ambientClassDeclarationExtends_singleFile.ts, 1, 29))
|
||||
>D : Symbol(D, Decl(ambientClassDeclarationExtends_singleFile.ts, 5, 1), Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 22))
|
||||
|
||||
=== tests/cases/compiler/ambientClassDeclarationExtends_file1.ts ===
|
||||
|
||||
declare class E {
|
||||
>E : Symbol(E, Decl(ambientClassDeclarationExtends_file1.ts, 0, 0))
|
||||
|
||||
public bar;
|
||||
>bar : Symbol(bar, Decl(ambientClassDeclarationExtends_file1.ts, 1, 17))
|
||||
}
|
||||
namespace F { var y; }
|
||||
>F : Symbol(F, Decl(ambientClassDeclarationExtends_file1.ts, 3, 1), Decl(ambientClassDeclarationExtends_file2.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(ambientClassDeclarationExtends_file1.ts, 4, 17))
|
||||
|
||||
=== tests/cases/compiler/ambientClassDeclarationExtends_file2.ts ===
|
||||
|
||||
declare class F extends E { }
|
||||
>F : Symbol(F, Decl(ambientClassDeclarationExtends_file1.ts, 3, 1), Decl(ambientClassDeclarationExtends_file2.ts, 0, 0))
|
||||
>E : Symbol(E, Decl(ambientClassDeclarationExtends_file1.ts, 0, 0))
|
||||
|
||||
var f: E = new F();
|
||||
>f : Symbol(f, Decl(ambientClassDeclarationExtends_file2.ts, 2, 3))
|
||||
>E : Symbol(E, Decl(ambientClassDeclarationExtends_file1.ts, 0, 0))
|
||||
>F : Symbol(F, Decl(ambientClassDeclarationExtends_file1.ts, 3, 1), Decl(ambientClassDeclarationExtends_file2.ts, 0, 0))
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
=== tests/cases/compiler/ambientClassDeclarationWithExtends.ts ===
|
||||
=== tests/cases/compiler/ambientClassDeclarationExtends_singleFile.ts ===
|
||||
declare class A { }
|
||||
>A : A
|
||||
|
||||
@@ -6,3 +6,47 @@ declare class B extends A { }
|
||||
>B : B
|
||||
>A : A
|
||||
|
||||
declare class C {
|
||||
>C : C
|
||||
|
||||
public foo;
|
||||
>foo : any
|
||||
}
|
||||
namespace D { var x; }
|
||||
>D : typeof D
|
||||
>x : any
|
||||
|
||||
declare class D extends C { }
|
||||
>D : D
|
||||
>C : C
|
||||
|
||||
var d: C = new D();
|
||||
>d : C
|
||||
>C : C
|
||||
>new D() : D
|
||||
>D : typeof D
|
||||
|
||||
=== tests/cases/compiler/ambientClassDeclarationExtends_file1.ts ===
|
||||
|
||||
declare class E {
|
||||
>E : E
|
||||
|
||||
public bar;
|
||||
>bar : any
|
||||
}
|
||||
namespace F { var y; }
|
||||
>F : typeof F
|
||||
>y : any
|
||||
|
||||
=== tests/cases/compiler/ambientClassDeclarationExtends_file2.ts ===
|
||||
|
||||
declare class F extends E { }
|
||||
>F : F
|
||||
>E : E
|
||||
|
||||
var f: E = new F();
|
||||
>f : E
|
||||
>E : E
|
||||
>new F() : F
|
||||
>F : typeof F
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user