Merge branch 'master' into forwardRefsInEnumInitializers

This commit is contained in:
Vladimir Matveev 2015-07-27 17:51:20 -07:00
commit e1708e7e2f
40 changed files with 1223 additions and 185 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@ tests/baselines/reference/projectOutput/*
tests/baselines/local/projectOutput/*
tests/services/baselines/prototyping/local/*
tests/services/browser/typescriptServices.js
scripts/configureNightly.js
scripts/processDiagnosticMessages.d.ts
scripts/processDiagnosticMessages.js
scripts/importDefinitelyTypedTests.js

70
AUTHORS.md Normal file
View File

@ -0,0 +1,70 @@
TypeScript is authored by:
* Adam Freidin
* Ahmad Farid
* Anders Hejlsberg
* Arnav Singh
* Arthur Ozga
* Basarat Ali Syed
* Ben Duffield
* Bill Ticehurst
* Bryan Forbes
* Caitlin Potter
* Chris Bubernak
* Colby Russell
* Colin Snover
* Cyrus Najmabadi
* Dan Quirk
* Daniel Rosenwasser
* David Li
* Dick van den Brink
* Dirk Bäumer
* Frank Wallis
* Gabriel Isenberg
* Gilad Peleg
* Guillaume Salles
* Harald Niesche
* Ingvar Stepanyan
* Ivo Gabe de Wolff
* James Whitney
* Jason Freeman
* Jason Ramsay
* Jed Mao
* Johannes Rieken
* Jonathan Bond-Caron
* Jonathan Park
* Jonathan Turner
* Josh Kalderimis
* Kagami Sascha Rosylight
* Keith Mashinter
* Kenji Imamula
* Lorant Pinter
* Masahiro Wakame
* Max Deepfield
* Micah Zoltu
* Mohamed Hegazy
* Oleg Mihailik
* Oleksandr Chekhovskyi
* Paul van Brenk
* Pedro Maltez
* Philip Bulley
* piloopin
* Ron Buckton
* Ryan Cavanaugh
* Sheetal Nandi
* Shengping Zhong
* Shyyko Serhiy
* Simon Hürlimann
* Solal Pirelli
* Stan Thomas
* Steve Lucco
* Tien Hoanhtien
* Tingan Ho
* togru
* Tomas Grubliauskas
* TruongSinh Tran-Nguyen
* Vladimir Matveev
* Wesley Wigham
* Yui Tanglertsampan
* Zev Spitz
* Zhengbo Li

View File

@ -138,6 +138,7 @@ var harnessSources = harnessCoreSources.concat([
"services/documentRegistry.ts",
"services/preProcessFile.ts",
"services/patternMatcher.ts",
"session.ts",
"versionCache.ts",
"convertToBase64.ts",
"transpile.ts"
@ -313,7 +314,7 @@ var processDiagnosticMessagesTs = path.join(scriptsDirectory, "processDiagnostic
var diagnosticMessagesJson = path.join(compilerDirectory, "diagnosticMessages.json");
var diagnosticInfoMapTs = path.join(compilerDirectory, "diagnosticInformationMap.generated.ts");
file(processDiagnosticMessagesTs)
file(processDiagnosticMessagesTs);
// processDiagnosticMessages script
compileFile(processDiagnosticMessagesJs,
@ -338,12 +339,50 @@ file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson],
complete();
});
ex.run();
}, {async: true})
}, {async: true});
desc("Generates a diagnostic file in TypeScript based on an input JSON file");
task("generate-diagnostics", [diagnosticInfoMapTs])
task("generate-diagnostics", [diagnosticInfoMapTs]);
// Publish nightly
var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
var packageJson = "package.json";
var programTs = path.join(compilerDirectory, "program.ts");
file(configureNightlyTs);
compileFile(/*outfile*/configureNightlyJs,
/*sources*/ [configureNightlyTs],
/*prereqs*/ [configureNightlyTs],
/*prefixes*/ [],
/*useBuiltCompiler*/ false,
/*noOutFile*/ false,
/*generateDeclarations*/ false,
/*outDir*/ undefined,
/*preserveConstEnums*/ undefined,
/*keepComments*/ false,
/*noResolve*/ false,
/*stripInternal*/ false);
task("setDebugMode", function() {
useDebugMode = true;
});
task("configure-nightly", [configureNightlyJs], function() {
var cmd = "node " + configureNightlyJs + " " + packageJson + " " + programTs;
console.log(cmd);
exec(cmd);
}, { async: true });
desc("Configure, build, test, and publish the nightly release.");
task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "runtests"], function () {
var cmd = "npm publish --tag next";
console.log(cmd);
exec(cmd);
});
// Local target to build the compiler and services
var tscFile = path.join(builtLocalDirectory, compilerFilename);
compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false);
@ -440,11 +479,11 @@ file(specMd, [word2mdJs, specWord], function () {
child_process.exec(cmd, function () {
complete();
});
}, {async: true})
}, {async: true});
desc("Generates a Markdown version of the Language Specification");
task("generate-spec", [specMd])
task("generate-spec", [specMd]);
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
@ -576,7 +615,7 @@ task("runtests", ["tests", builtLocalDirectory], function() {
exec(cmd, deleteTemporaryProjectOutput);
}, {async: true});
desc("Generates code coverage data via instanbul")
desc("Generates code coverage data via instanbul");
task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run;
console.log(cmd);
@ -619,7 +658,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function(
function getDiffTool() {
var program = process.env['DIFF']
if (!program) {
fail("Add the 'DIFF' environment variable to the path of the program you want to use.")
fail("Add the 'DIFF' environment variable to the path of the program you want to use.");
}
return program;
}
@ -628,14 +667,14 @@ function getDiffTool() {
desc("Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable");
task('diff', function () {
var cmd = '"' + getDiffTool() + '" ' + refBaseline + ' ' + localBaseline;
console.log(cmd)
console.log(cmd);
exec(cmd);
}, {async: true});
desc("Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable");
task('diff-rwc', function () {
var cmd = '"' + getDiffTool() + '" ' + refRwcBaseline + ' ' + localRwcBaseline;
console.log(cmd)
console.log(cmd);
exec(cmd);
}, {async: true});
@ -736,9 +775,9 @@ task("lint", [], function() {
function failure(f) { return function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n') }};
var lintTargets = compilerSources.concat(harnessCoreSources);
for(var i in lintTargets) {
for (var i in lintTargets) {
var f = lintTargets[i];
var cmd = 'tslint -f ' + f;
var cmd = 'tslint -c tslint.json ' + f;
exec(cmd, success(f), failure(f));
}
}, { async: true });

View File

@ -8,6 +8,19 @@
[TypeScript](http://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](http://www.typescriptlang.org/Playground), and stay up to date via [our blog](http://blogs.msdn.com/typescript) and [twitter account](https://twitter.com/typescriptlang).
## Installing
For the latest stable version:
```
npm install -g typescript
```
For our nightly builds:
```
npm install -g typescript@next
```
## Contribute
@ -63,7 +76,8 @@ jake runtests # Run tests using the built compiler and test infrastructu
# Use host=<hostName> or tests=<testPath>.
jake runtests-browser # Runs the tests using the built run.js file. Syntax is jake runtests. Optional
parameters 'host=', 'tests=[regex], reporter=[list|spec|json|<more>]'.
jake baseline-accept # This replaces the baseline test results with the results obtained from jake runtests.
jake baseline-accept # This replaces the baseline test results with the results obtained from jake runtests.
jake lint # Runs tslint on the TypeScript source.
jake -T # List the above commands.
```

View File

@ -2,7 +2,7 @@
"name": "typescript",
"author": "Microsoft Corp.",
"homepage": "http://typescriptlang.org/",
"version": "1.5.3",
"version": "1.6.0",
"license": "Apache-2.0",
"description": "TypeScript is a language for application scale JavaScript development",
"keywords": [

View File

@ -0,0 +1,73 @@
/// <reference path="../src/compiler/sys.ts" />
/**
* A minimal description for a parsed package.json object.
*/
interface PackageJson {
name: string;
version: string;
keywords: string[];
}
function main(): void {
const sys = ts.sys;
if (sys.args.length < 2) {
sys.write("Usage:" + sys.newLine)
sys.write("\tnode configureNightly.js <package.json location> <file containing version>" + sys.newLine);
return;
}
// Acquire the version from the package.json file and modify it appropriately.
const packageJsonFilePath = ts.normalizePath(sys.args[0]);
const packageJsonContents = sys.readFile(packageJsonFilePath);
const packageJsonValue: PackageJson = JSON.parse(packageJsonContents);
const nightlyVersion = getNightlyVersionString(packageJsonValue.version);
// Modify the package.json structure
packageJsonValue.version = nightlyVersion;
// Acquire and modify the source file that exposes the version string.
const tsFilePath = ts.normalizePath(sys.args[1]);
const tsFileContents = sys.readFile(tsFilePath);
const versionAssignmentRegExp = /export\s+const\s+version\s+=\s+".*";/;
const modifiedTsFileContents = tsFileContents.replace(versionAssignmentRegExp, `export const version = "${nightlyVersion}";`);
// Ensure we are actually changing something - the user probably wants to know that the update failed.
if (tsFileContents === modifiedTsFileContents) {
let err = `\n '${tsFilePath}' was not updated while configuring for a nightly publish.\n `;
if (tsFileContents.match(versionAssignmentRegExp)) {
err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`;
}
else {
err += `The file seems to no longer have a string matching '${versionAssignmentRegExp}'.`;
}
throw err + "\n";
}
// Finally write the changes to disk.
sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
sys.writeFile(tsFilePath, modifiedTsFileContents);
}
function getNightlyVersionString(versionString: string): string {
// If the version string already contains "-nightly",
// then get the base string and update based on that.
const dashNightlyPos = versionString.indexOf("-dev");
if (dashNightlyPos >= 0) {
versionString = versionString.slice(0, dashNightlyPos);
}
// We're going to append a representation of the current time at the end of the current version.
// String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ',
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
// UTC time will always be implicit here.
const now = new Date();
const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8);
return `${versionString}-dev.${timeStr}`;
}
main();

View File

@ -68,6 +68,7 @@ namespace ts {
getPropertyOfType,
getSignaturesOfType,
getIndexTypeOfType,
getBaseTypes,
getReturnTypeOfSignature,
getSymbolsInScope,
getSymbolAtLocation,
@ -10439,7 +10440,8 @@ namespace ts {
if (getClassExtendsHeritageClauseElement(<ClassDeclaration>node.parent)) {
if (containsSuperCall(node.body)) {
// The first statement in the body of a constructor must be a super call if both of the following are true:
// The first statement in the body of a constructor (excluding prologue directives) must be a super call
// if both of the following are true:
// - The containing class is a derived class.
// - The constructor declares parameter properties
// or the containing class declares instance member variables with initializers.
@ -10447,14 +10449,26 @@ namespace ts {
forEach((<ClassDeclaration>node.parent).members, isInstancePropertyWithInitializer) ||
forEach(node.parameters, p => p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected));
// Skip past any prologue directives to find the first statement
// to ensure that it was a super call.
if (superCallShouldBeFirst) {
let statements = (<Block>node.body).statements;
if (!statements.length || statements[0].kind !== SyntaxKind.ExpressionStatement || !isSuperCallExpression((<ExpressionStatement>statements[0]).expression)) {
error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
let superCallStatement: ExpressionStatement;
for (let statement of statements) {
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((<ExpressionStatement>statement).expression)) {
superCallStatement = <ExpressionStatement>statement;
break;
}
if (!isPrologueDirective(statement)) {
break;
}
}
if (!superCallStatement) {
error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
}
else {
// In such a required super call, it is a compile-time error for argument expressions to reference this.
markThisReferencesAsErrors((<ExpressionStatement>statements[0]).expression);
markThisReferencesAsErrors(superCallStatement.expression);
}
}
}

View File

@ -510,7 +510,6 @@ namespace ts {
Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." },
Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." },
Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." },
Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." },
Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." },
Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." },
Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." },

View File

@ -2029,10 +2029,6 @@
"category": "Error",
"code": 5042
},
"Option 'sourceMap' cannot be specified with option 'isolatedModules'.": {
"category": "Error",
"code": 5043
},
"Option 'declaration' cannot be specified with option 'isolatedModules'.": {
"category": "Error",
"code": 5044

View File

@ -1425,6 +1425,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
case SyntaxKind.IfStatement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxExpression:
case SyntaxKind.NewExpression:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.PostfixUnaryExpression:
@ -5429,17 +5430,43 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
(!isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
emitLeadingComments(node);
emitStart(node);
if (isES6ExportedDeclaration(node)) {
write("export ");
write("var ");
// variable declaration for import-equals declaration can be hoisted in system modules
// in this case 'var' should be omitted and emit should contain only initialization
let variableDeclarationIsHoisted = shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/ true);
// is it top level export import v = a.b.c in system module?
// if yes - it needs to be rewritten as exporter('v', v = a.b.c)
let isExported = isSourceFileLevelDeclarationInSystemJsModule(node, /*isExported*/ true);
if (!variableDeclarationIsHoisted) {
Debug.assert(!isExported);
if (isES6ExportedDeclaration(node)) {
write("export ");
write("var ");
}
else if (!(node.flags & NodeFlags.Export)) {
write("var ");
}
}
else if (!(node.flags & NodeFlags.Export)) {
write("var ");
if (isExported) {
write(`${exportFunctionForFile}("`);
emitNodeWithoutSourceMap(node.name);
write(`", `);
}
emitModuleMemberName(node);
write(" = ");
emit(node.moduleReference);
write(";");
if (isExported) {
write(")");
}
write(";");
emitEnd(node);
emitExportImportAssignments(node);
emitTrailingComments(node);
@ -5965,6 +5992,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
return;
}
if (isInternalModuleImportEqualsDeclaration(node)) {
if (!hoistedVars) {
hoistedVars = [];
}
hoistedVars.push(node.name);
return;
}
if (isBindingPattern(node)) {
forEach((<BindingPattern>node).elements, visit);
@ -6169,14 +6205,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
writeLine();
for (let i = startIndex; i < node.statements.length; ++i) {
let statement = node.statements[i];
// - imports/exports are not emitted for system modules
// - external module related imports/exports are not emitted for system modules
// - function declarations are not emitted because they were already hoisted
switch (statement.kind) {
case SyntaxKind.ExportDeclaration:
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.FunctionDeclaration:
continue;
case SyntaxKind.ImportEqualsDeclaration:
if (!isInternalModuleImportEqualsDeclaration(statement)) {
continue;
}
}
writeLine();
emit(statement);

View File

@ -8,7 +8,7 @@ namespace ts {
/* @internal */ export let ioWriteTime = 0;
/** The version of the TypeScript compiler release */
export const version = "1.5.3";
export const version = "1.6.0";
export function findConfigFile(searchPath: string): string {
let fileName = "tsconfig.json";
@ -341,7 +341,7 @@ namespace ts {
});
}
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
return runWithCancellationToken(() => {
if (!isDeclarationFile(sourceFile)) {
let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
@ -350,7 +350,7 @@ namespace ts {
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
}
});
}
}
function getOptionsDiagnostics(): Diagnostic[] {
let allDiagnostics: Diagnostic[] = [];
@ -602,10 +602,6 @@ namespace ts {
function verifyCompilerOptions() {
if (options.isolatedModules) {
if (options.sourceMap) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules));
}
if (options.declaration) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules));
}

View File

@ -3,7 +3,7 @@
namespace ts {
export interface SourceFile {
fileWatcher: FileWatcher;
fileWatcher?: FileWatcher;
}
/**

View File

@ -1404,6 +1404,7 @@ namespace ts {
getPropertyOfType(type: Type, propertyName: string): Symbol;
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
getBaseTypes(type: InterfaceType): ObjectType[];
getReturnTypeOfSignature(signature: Signature): Type;
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
@ -1808,7 +1809,9 @@ namespace ts {
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none)
/* @internal */
resolvedBaseConstructorType?: Type; // Resolved base constructor type of class
/* @internal */
resolvedBaseTypes: ObjectType[]; // Resolved base types
}

View File

@ -965,7 +965,7 @@ namespace ts {
return (<ExternalModuleReference>(<ImportEqualsDeclaration>node).moduleReference).expression;
}
export function isInternalModuleImportEqualsDeclaration(node: Node) {
export function isInternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
}

View File

@ -1875,7 +1875,7 @@ module FourSlash {
}
}
private verifyProjectInfo(expected: string[]) {
public verifyProjectInfo(expected: string[]) {
if (this.testType === FourSlashTestType.Server) {
let actual = (<ts.server.SessionClient>this.languageService).getProjectInfo(
this.activeFile.fileName,
@ -2057,11 +2057,8 @@ module FourSlash {
return result;
}
public verifGetScriptLexicalStructureListContains(
name: string,
kind: string,
markerPosition?: number) {
this.taoInvalidReason = 'verifGetScriptLexicalStructureListContains impossible';
public verifyGetScriptLexicalStructureListContains(name: string, kind: string) {
this.taoInvalidReason = 'verifyGetScriptLexicalStructureListContains impossible';
let items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
@ -2263,7 +2260,7 @@ module FourSlash {
return 'line ' + (pos.line + 1) + ', col ' + pos.character;
}
private getMarkerByName(markerName: string) {
public getMarkerByName(markerName: string) {
let markerPos = this.testData.markerPositions[markerName];
if (markerPos === undefined) {
let markerNames: string[] = [];
@ -2738,4 +2735,4 @@ module FourSlash {
fileName: fileName
};
}
}
}

View File

@ -29,6 +29,7 @@ var Buffer: BufferConstructor = require('buffer').Buffer;
// this will work in the browser via browserify
var _chai: typeof chai = require('chai');
var assert: typeof _chai.assert = _chai.assert;
var expect: typeof _chai.expect = _chai.expect;
declare var __dirname: string; // Node-specific
var global = <any>Function("return this").call(null);

View File

@ -109,13 +109,13 @@ namespace ts.server {
}
export class Session {
projectService: ProjectService;
pendingOperation = false;
fileHash: ts.Map<number> = {};
nextFileId = 1;
errorTimer: any; /*NodeJS.Timer | number*/
immediateId: any;
changeSeq = 0;
protected projectService: ProjectService;
private pendingOperation = false;
private fileHash: ts.Map<number> = {};
private nextFileId = 1;
private errorTimer: any; /*NodeJS.Timer | number*/
private immediateId: any;
private changeSeq = 0;
constructor(
private host: ServerHost,
@ -129,7 +129,7 @@ namespace ts.server {
});
}
handleEvent(eventName: string, project: Project, fileName: string) {
private handleEvent(eventName: string, project: Project, fileName: string) {
if (eventName == "context") {
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
@ -137,7 +137,7 @@ namespace ts.server {
}
}
logError(err: Error, cmd: string) {
public logError(err: Error, cmd: string) {
var typedErr = <StackTraceError>err;
var msg = "Exception on executing command " + cmd;
if (typedErr.message) {
@ -149,11 +149,11 @@ namespace ts.server {
this.projectService.log(msg);
}
sendLineToClient(line: string) {
private sendLineToClient(line: string) {
this.host.write(line + this.host.newLine);
}
send(msg: protocol.Message) {
public send(msg: protocol.Message) {
var json = JSON.stringify(msg);
if (this.logger.isVerbose()) {
this.logger.info(msg.type + ": " + json);
@ -162,7 +162,7 @@ namespace ts.server {
'\r\n\r\n' + json);
}
event(info: any, eventName: string) {
public event(info: any, eventName: string) {
var ev: protocol.Event = {
seq: 0,
type: "event",
@ -172,7 +172,7 @@ namespace ts.server {
this.send(ev);
}
response(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) {
private response(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) {
var res: protocol.Response = {
seq: 0,
type: "response",
@ -189,11 +189,11 @@ namespace ts.server {
this.send(res);
}
output(body: any, commandName: string, requestSequence = 0, errorMessage?: string) {
public output(body: any, commandName: string, requestSequence = 0, errorMessage?: string) {
this.response(body, commandName, requestSequence, errorMessage);
}
semanticCheck(file: string, project: Project) {
private semanticCheck(file: string, project: Project) {
try {
var diags = project.compilerService.languageService.getSemanticDiagnostics(file);
@ -207,7 +207,7 @@ namespace ts.server {
}
}
syntacticCheck(file: string, project: Project) {
private syntacticCheck(file: string, project: Project) {
try {
var diags = project.compilerService.languageService.getSyntacticDiagnostics(file);
if (diags) {
@ -220,12 +220,12 @@ namespace ts.server {
}
}
errorCheck(file: string, project: Project) {
private errorCheck(file: string, project: Project) {
this.syntacticCheck(file, project);
this.semanticCheck(file, project);
}
updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
private updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
setTimeout(() => {
if (matchSeq(seq)) {
this.projectService.updateProjectStructure();
@ -233,7 +233,7 @@ namespace ts.server {
}, ms);
}
updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
private updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
if (followMs > ms) {
followMs = ms;
@ -269,7 +269,7 @@ namespace ts.server {
}
}
getDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
private getDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -291,7 +291,7 @@ namespace ts.server {
}));
}
getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
private getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -313,7 +313,7 @@ namespace ts.server {
}));
}
getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{
fileName = ts.normalizePath(fileName);
let project = this.projectService.getProjectForFile(fileName);
@ -343,7 +343,7 @@ namespace ts.server {
});
}
getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
fileName = ts.normalizePath(fileName)
let project = this.projectService.getProjectForFile(fileName)
@ -358,7 +358,7 @@ namespace ts.server {
return projectInfo;
}
getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody {
private getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -426,7 +426,7 @@ namespace ts.server {
return { info: renameInfo, locs: bakedRenameLocs };
}
getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody {
private getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody {
// TODO: get all projects for this file; report refs for all projects deleting duplicates
// can avoid duplicates by eliminating same ref file from subsequent projects
var file = ts.normalizePath(fileName);
@ -473,12 +473,12 @@ namespace ts.server {
};
}
openClientFile(fileName: string) {
private openClientFile(fileName: string) {
var file = ts.normalizePath(fileName);
this.projectService.openClientFile(file);
}
getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody {
private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -504,7 +504,7 @@ namespace ts.server {
};
}
getFormattingEditsForRange(line: number, offset: number, endLine: number, endOffset: number, fileName: string): protocol.CodeEdit[] {
private getFormattingEditsForRange(line: number, offset: number, endLine: number, endOffset: number, fileName: string): protocol.CodeEdit[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -531,7 +531,7 @@ namespace ts.server {
});
}
getFormattingEditsAfterKeystroke(line: number, offset: number, key: string, fileName: string): protocol.CodeEdit[] {
private getFormattingEditsAfterKeystroke(line: number, offset: number, key: string, fileName: string): protocol.CodeEdit[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
@ -607,7 +607,7 @@ namespace ts.server {
});
}
getCompletions(line: number, offset: number, prefix: string, fileName: string): protocol.CompletionEntry[] {
private getCompletions(line: number, offset: number, prefix: string, fileName: string): protocol.CompletionEntry[] {
if (!prefix) {
prefix = "";
}
@ -633,7 +633,7 @@ namespace ts.server {
}, []).sort((a, b) => a.name.localeCompare(b.name));
}
getCompletionEntryDetails(line: number, offset: number,
private getCompletionEntryDetails(line: number, offset: number,
entryNames: string[], fileName: string): protocol.CompletionEntryDetails[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
@ -653,7 +653,7 @@ namespace ts.server {
}, []);
}
getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems {
private getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -682,7 +682,7 @@ namespace ts.server {
return result;
}
getDiagnostics(delay: number, fileNames: string[]) {
private getDiagnostics(delay: number, fileNames: string[]) {
var checkList = fileNames.reduce((accum: PendingErrorCheck[], fileName: string) => {
fileName = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(fileName);
@ -697,7 +697,7 @@ namespace ts.server {
}
}
change(line: number, offset: number, endLine: number, endOffset: number, insertString: string, fileName: string) {
private change(line: number, offset: number, endLine: number, endOffset: number, insertString: string, fileName: string) {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (project) {
@ -712,7 +712,7 @@ namespace ts.server {
}
}
reload(fileName: string, tempFileName: string, reqSeq = 0) {
private reload(fileName: string, tempFileName: string, reqSeq = 0) {
var file = ts.normalizePath(fileName);
var tmpfile = ts.normalizePath(tempFileName);
var project = this.projectService.getProjectForFile(file);
@ -725,7 +725,7 @@ namespace ts.server {
}
}
saveToTmp(fileName: string, tempFileName: string) {
private saveToTmp(fileName: string, tempFileName: string) {
var file = ts.normalizePath(fileName);
var tmpfile = ts.normalizePath(tempFileName);
@ -735,12 +735,12 @@ namespace ts.server {
}
}
closeClientFile(fileName: string) {
private closeClientFile(fileName: string) {
var file = ts.normalizePath(fileName);
this.projectService.closeClientFile(file);
}
decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] {
private decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] {
if (!items) {
return undefined;
}
@ -759,7 +759,7 @@ namespace ts.server {
}));
}
getNavigationBarItems(fileName: string): protocol.NavigationBarItem[] {
private getNavigationBarItems(fileName: string): protocol.NavigationBarItem[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -775,7 +775,7 @@ namespace ts.server {
return this.decorateNavigationBarItem(project, fileName, items);
}
getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
private getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
@ -814,7 +814,7 @@ namespace ts.server {
});
}
getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] {
private getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
@ -836,7 +836,7 @@ namespace ts.server {
}));
}
exit() {
public exit() {
}
private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = {
@ -942,14 +942,14 @@ namespace ts.server {
return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true};
},
};
addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) {
public addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) {
if (this.handlers[command]) {
throw new Error(`Protocol handler already exists for command "${command}"`);
}
this.handlers[command] = handler;
}
executeCommand(request: protocol.Request) : {response?: any, responseRequired?: boolean} {
public executeCommand(request: protocol.Request) : {response?: any, responseRequired?: boolean} {
var handler = this.handlers[request.command];
if (handler) {
return handler(request);
@ -960,7 +960,7 @@ namespace ts.server {
}
}
onMessage(message: string) {
public onMessage(message: string) {
if (this.logger.isVerbose()) {
this.logger.info("request: " + message);
var start = this.hrtime();

View File

@ -48,6 +48,7 @@ namespace ts {
getConstructSignatures(): Signature[];
getStringIndexType(): Type;
getNumberIndexType(): Type;
getBaseTypes(): ObjectType[]
}
export interface Signature {
@ -682,6 +683,11 @@ namespace ts {
getNumberIndexType(): Type {
return this.checker.getIndexTypeOfType(this, IndexKind.Number);
}
getBaseTypes(): ObjectType[] {
return this.flags & (TypeFlags.Class | TypeFlags.Interface)
? this.checker.getBaseTypes(<TypeObject & InterfaceType>this)
: undefined;
}
}
class SignatureObject implements Signature {
@ -1754,18 +1760,31 @@ namespace ts {
sourceFile.version = version;
sourceFile.scriptSnapshot = scriptSnapshot;
}
export interface TranspileOptions {
compilerOptions?: CompilerOptions;
fileName?: string;
reportDiagnostics?: boolean;
moduleName?: string;
}
export interface TranspileOutput {
outputText: string;
diagnostics?: Diagnostic[];
sourceMapText?: string;
}
/*
* This function will compile source text from 'input' argument using specified compiler options.
* If not options are provided - it will use a set of default compiler options.
* Extra compiler options that will unconditionally be used bu this function are:
* Extra compiler options that will unconditionally be used by this function are:
* - isolatedModules = true
* - allowNonTsExtensions = true
* - noLib = true
* - noResolve = true
*/
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions();
*/
export function transpileModule(input: string, transpileOptions?: TranspileOptions): TranspileOutput {
let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions();
options.isolatedModules = true;
@ -1781,23 +1800,30 @@ namespace ts {
options.noResolve = true;
// Parse
let inputFileName = fileName || "module.ts";
let inputFileName = transpileOptions.fileName || "module.ts";
let sourceFile = createSourceFile(inputFileName, input, options.target);
if (moduleName) {
sourceFile.moduleName = moduleName;
if (transpileOptions.moduleName) {
sourceFile.moduleName = transpileOptions.moduleName;
}
let newLine = getNewLineCharacter(options);
// Output
let outputText: string;
let sourceMapText: string;
// Create a compilerHost object to allow the compiler to read and write files
let compilerHost: CompilerHost = {
getSourceFile: (fileName, target) => fileName === inputFileName ? sourceFile : undefined,
writeFile: (name, text, writeByteOrderMark) => {
Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
outputText = text;
if (fileExtensionIs(name, ".map")) {
Debug.assert(sourceMapText === undefined, `Unexpected multiple source map outputs for the file '${name}'`);
sourceMapText = text;
}
else {
Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
outputText = text;
}
},
getDefaultLibFileName: () => "lib.d.ts",
useCaseSensitiveFileNames: () => false,
@ -1807,16 +1833,29 @@ namespace ts {
};
let program = createProgram([inputFileName], options, compilerHost);
addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
let diagnostics: Diagnostic[];
if (transpileOptions.reportDiagnostics) {
diagnostics = [];
addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
}
// Emit
program.emit();
Debug.assert(outputText !== undefined, "Output generation failed");
return outputText;
return { outputText, diagnostics, sourceMapText };
}
/*
* This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result.
*/
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName });
// addRange correctly handles cases when wither 'from' or 'to' argument is missing
addRange(diagnostics, output.diagnostics);
return output.outputText;
}
export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile {

View File

@ -0,0 +1,22 @@
tests/cases/compiler/aliasesInSystemModule1.ts(2,24): error TS2307: Cannot find module 'foo'.
==== tests/cases/compiler/aliasesInSystemModule1.ts (1 errors) ====
import alias = require('foo');
~~~~~
!!! error TS2307: Cannot find module 'foo'.
import cls = alias.Class;
export import cls2 = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
module M {
export import cls = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
}

View File

@ -0,0 +1,42 @@
//// [aliasesInSystemModule1.ts]
import alias = require('foo');
import cls = alias.Class;
export import cls2 = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
module M {
export import cls = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
}
//// [aliasesInSystemModule1.js]
System.register(['foo'], function(exports_1) {
var alias;
var cls, cls2, x, y, z, M;
return {
setters:[
function (_alias) {
alias = _alias;
}],
execute: function() {
cls = alias.Class;
exports_1("cls2", cls2 = alias.Class);
x = new alias.Class();
y = new cls();
z = new cls2();
(function (M) {
M.cls = alias.Class;
var x = new alias.Class();
var y = new M.cls();
var z = new cls2();
})(M || (M = {}));
}
}
});

View File

@ -0,0 +1,21 @@
tests/cases/compiler/aliasesInSystemModule2.ts(2,21): error TS2307: Cannot find module 'foo'.
==== tests/cases/compiler/aliasesInSystemModule2.ts (1 errors) ====
import {alias} from "foo";
~~~~~
!!! error TS2307: Cannot find module 'foo'.
import cls = alias.Class;
export import cls2 = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
module M {
export import cls = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
}

View File

@ -0,0 +1,41 @@
//// [aliasesInSystemModule2.ts]
import {alias} from "foo";
import cls = alias.Class;
export import cls2 = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
module M {
export import cls = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
}
//// [aliasesInSystemModule2.js]
System.register(["foo"], function(exports_1) {
var foo_1;
var cls, cls2, x, y, z, M;
return {
setters:[
function (_foo_1) {
foo_1 = _foo_1;
}],
execute: function() {
cls = foo_1.alias.Class;
exports_1("cls2", cls2 = foo_1.alias.Class);
x = new foo_1.alias.Class();
y = new cls();
z = new cls2();
(function (M) {
M.cls = foo_1.alias.Class;
var x = new foo_1.alias.Class();
var y = new M.cls();
var z = new cls2();
})(M || (M = {}));
}
}
});

View File

@ -1,7 +0,0 @@
error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'.
!!! error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'.
==== tests/cases/compiler/isolatedModulesSourceMap.ts (0 errors) ====
export var x;

View File

@ -1,7 +1,7 @@
//// [isolatedModulesSourceMap.ts]
export var x;
export var x = 1;
//// [isolatedModulesSourceMap.js]
export var x;
export var x = 1;
//# sourceMappingURL=isolatedModulesSourceMap.js.map

View File

@ -1,2 +1,2 @@
//// [isolatedModulesSourceMap.js.map]
{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,CAAC"}
{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,GAAG,CAAC,CAAC"}

View File

@ -8,20 +8,26 @@ sources: isolatedModulesSourceMap.ts
emittedFile:tests/cases/compiler/isolatedModulesSourceMap.js
sourceFile:isolatedModulesSourceMap.ts
-------------------------------------------------------------------
>>>export var x;
>>>export var x = 1;
1 >
2 >^^^^^^^^^^^
3 > ^
4 > ^
5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
4 > ^^^
5 > ^
6 > ^
7 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
1 >
>
2 >export var
3 > x
4 > ;
4 > =
5 > 1
6 > ;
1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0)
2 >Emitted(1, 12) Source(2, 12) + SourceIndex(0)
3 >Emitted(1, 13) Source(2, 13) + SourceIndex(0)
4 >Emitted(1, 14) Source(2, 14) + SourceIndex(0)
4 >Emitted(1, 16) Source(2, 16) + SourceIndex(0)
5 >Emitted(1, 17) Source(2, 17) + SourceIndex(0)
6 >Emitted(1, 18) Source(2, 18) + SourceIndex(0)
---
>>>//# sourceMappingURL=isolatedModulesSourceMap.js.map

View File

@ -0,0 +1,5 @@
=== tests/cases/compiler/isolatedModulesSourceMap.ts ===
export var x = 1;
>x : Symbol(x, Decl(isolatedModulesSourceMap.ts, 1, 10))

View File

@ -0,0 +1,6 @@
=== tests/cases/compiler/isolatedModulesSourceMap.ts ===
export var x = 1;
>x : number
>1 : number

View File

@ -0,0 +1,21 @@
//// [tests/cases/compiler/jsxImportInAttribute.tsx] ////
//// [component.d.ts]
declare module "Test" {
export default class Text { }
}
//// [consumer.tsx]
/// <reference path="component.d.ts" />
import Test from 'Test';
let x = Test; // emit test_1.default
<anything attr={Test} />; // ?
//// [consumer.jsx]
/// <reference path="component.d.ts" />
var Test_1 = require('Test');
var x = Test_1["default"]; // emit test_1.default
<anything attr={Test_1["default"]}/>; // ?

View File

@ -0,0 +1,19 @@
=== tests/cases/compiler/consumer.tsx ===
/// <reference path="component.d.ts" />
import Test from 'Test';
>Test : Symbol(Test, Decl(consumer.tsx, 1, 6))
let x = Test; // emit test_1.default
>x : Symbol(x, Decl(consumer.tsx, 3, 3))
>Test : Symbol(Test, Decl(consumer.tsx, 1, 6))
<anything attr={Test} />; // ?
>attr : Symbol(unknown)
=== tests/cases/compiler/component.d.ts ===
declare module "Test" {
export default class Text { }
>Text : Symbol(Text, Decl(component.d.ts, 1, 23))
}

View File

@ -0,0 +1,22 @@
=== tests/cases/compiler/consumer.tsx ===
/// <reference path="component.d.ts" />
import Test from 'Test';
>Test : typeof Test
let x = Test; // emit test_1.default
>x : typeof Test
>Test : typeof Test
<anything attr={Test} />; // ?
><anything attr={Test} /> : any
>anything : any
>attr : any
>Test : any
=== tests/cases/compiler/component.d.ts ===
declare module "Test" {
export default class Text { }
>Text : Text
}

View File

@ -1,8 +1,7 @@
tests/cases/compiler/strictModeInConstructor.ts(9,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.
tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.
==== tests/cases/compiler/strictModeInConstructor.ts (2 errors) ====
==== tests/cases/compiler/strictModeInConstructor.ts (1 errors) ====
class A {
}
@ -12,14 +11,9 @@ tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' c
public s: number = 9;
constructor () {
~~~~~~~~~~~~~~~~
"use strict"; // No error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
super();
~~~~~~~~~~~~~~~~
}
~~~~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.
}
class C extends A {

View File

@ -0,0 +1,18 @@
// @module: system
// @isolatedModules: true
import alias = require('foo');
import cls = alias.Class;
export import cls2 = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
module M {
export import cls = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
}

View File

@ -0,0 +1,17 @@
// @module: system
// @isolatedModules: true
import {alias} from "foo";
import cls = alias.Class;
export import cls2 = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
module M {
export import cls = alias.Class;
let x = new alias.Class();
let y = new cls();
let z = new cls2();
}

View File

@ -3,4 +3,4 @@
// @target: es6
// @filename: file1.ts
export var x;
export var x = 1;

View File

@ -0,0 +1,14 @@
//@jsx: preserve
//@module: commonjs
//@filename: component.d.ts
declare module "Test" {
export default class Text { }
}
//@filename: consumer.tsx
/// <reference path="component.d.ts" />
import Test from 'Test';
let x = Test; // emit test_1.default
<anything attr={Test} />; // ?

View File

@ -1,7 +1,8 @@
/// <reference path="fourslash.ts" />
//// /*1*/function parseInt(s/*2*/:string):number;
goTo.marker('2');
edit.deleteAtCaret(':string'.length);
goTo.marker('1');
edit.insert('declare ');
edit.insert('declare ');

View File

@ -29,7 +29,34 @@
// type 'fs.' as an alternate way of accessing the top-level objects
// (e.g. 'fs.goTo.eof();')
//---------------------------------------
// For API editors:
// When editting this file, and only while editing this file, enable the reference comments
// and comment out the declarations in this section to get proper type information.
// Undo these changes before compiling/committing/editing any other fourslash tests.
// The test suite will likely crash if you try 'jake runtests' with reference comments enabled.
//
// Explanation:
// We want type-completion while we edit this file, but at compile time/while editting fourslash tests,
// we don't want to include the following reference because we are compiling this file in "--out" mode and don't want to rope
// in the entire codebase into the compilation each fourslash test. Additionally, we don't want to expose the
// src/harness/fourslash.ts API's (or the rest of the compiler) because they are unstable and complicate the
// fourslash testing DSL. Finally, in this case, runtime reflection is (much) faster.
//
// TODO: figure out a better solution to the API exposure problem.
// /// <reference path="../../../built/local/typescriptServices.d.ts"/>
// /// <reference path="../../../src/harness/fourslash.ts"/>
declare var FourSlash;
module ts {
export interface SymbolDisplayPart {
text: string;
kind: string;
}
}
//---------------------------------------------
// Return code used by getEmitOutput function to indicate status of the function
// It is a duplicate of the one in types.ts to expose it to testcases in fourslash
@ -42,7 +69,6 @@ enum EmitReturnStatus {
}
module FourSlashInterface {
declare var FourSlash;
export interface Marker {
fileName: string;
@ -201,15 +227,6 @@ module FourSlashInterface {
FourSlash.currentTestState.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess);
}
public implementorsCountIs(count: number) {
FourSlash.currentTestState.verifyImplementorsCountIs(count);
}
// Add tests for this.
public currentParameterIsVariable() {
FourSlash.currentTestState.verifyCurrentParameterIsVariable(!this.negative);
}
public signatureHelpPresent() {
FourSlash.currentTestState.verifySignatureHelpPresent(!this.negative);
}
@ -361,14 +378,11 @@ module FourSlashInterface {
FourSlash.currentTestState.verifyNoMatchingBracePosition(bracePosition);
}
public setVerifyDocComments(val: boolean) {
FourSlash.currentTestState.setVerifyDocComments(val);
}
public getScriptLexicalStructureListCount(count: number) {
FourSlash.currentTestState.verifyGetScriptLexicalStructureListCount(count);
}
// TODO: figure out what to do with the unused arguments.
public getScriptLexicalStructureListContains(
name: string,
kind: string,
@ -376,13 +390,7 @@ module FourSlashInterface {
parentName?: string,
isAdditionalSpan?: boolean,
markerPosition?: number) {
FourSlash.currentTestState.verifGetScriptLexicalStructureListContains(
name,
kind,
fileName,
parentName,
isAdditionalSpan,
markerPosition);
FourSlash.currentTestState.verifyGetScriptLexicalStructureListContains(name, kind);
}
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string) {
@ -698,12 +706,7 @@ module fs {
export var format = new FourSlashInterface.format();
export var cancellation = new FourSlashInterface.cancellation();
}
module ts {
export interface SymbolDisplayPart {
text: string;
kind: string;
}
}
function verifyOperationIsCancelled(f) {
FourSlash.verifyOperationIsCancelled(f);
}

View File

@ -0,0 +1,447 @@
/// <reference path="..\..\..\src\harness\harness.ts" />
namespace ts.server {
let lastWrittenToHost: string;
const mockHost: ServerHost = {
args: [],
newLine: "\n",
useCaseSensitiveFileNames: true,
write(s): void { lastWrittenToHost = s; },
readFile(): string { return void 0; },
writeFile(): void {},
resolvePath(): string { return void 0; },
fileExists: () => false,
directoryExists: () => false,
createDirectory(): void {},
getExecutingFilePath(): string { return void 0; },
getCurrentDirectory(): string { return void 0; },
readDirectory(): string[] { return []; },
exit(): void {}
};
const mockLogger: Logger = {
close(): void {},
isVerbose(): boolean { return false; },
loggingEnabled(): boolean { return false; },
perftrc(s: string): void {},
info(s: string): void {},
startGroup(): void {},
endGroup(): void {},
msg(s: string, type?: string): void {},
};
describe("the Session class", () => {
let session: Session;
let lastSent: protocol.Message;
beforeEach(() => {
session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger);
session.send = (msg: protocol.Message) => {
lastSent = msg;
};
});
describe("executeCommand", () => {
it("should throw when commands are executed with invalid arguments", () => {
const req: protocol.FileRequest = {
command: CommandNames.Open,
seq: 0,
type: "command",
arguments: {
file: undefined
}
};
expect(() => session.executeCommand(req)).to.throw();
});
it("should output an error response when a command does not exist", () => {
const req: protocol.Request = {
command: "foobar",
seq: 0,
type: "command"
};
session.executeCommand(req);
expect(lastSent).to.deep.equal(<protocol.Response>{
command: CommandNames.Unknown,
type: "response",
seq: 0,
message: "Unrecognized JSON command: foobar",
request_seq: 0,
success: false
});
});
it("should return a tuple containing the response and if a response is required on success", () => {
const req: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "command",
arguments: {
hostInfo: "unit test",
formatOptions: {
newLineCharacter: "`n"
}
}
};
expect(session.executeCommand(req)).to.deep.equal({
responseRequired: false
});
expect(lastSent).to.deep.equal({
command: CommandNames.Configure,
type: "response",
success: true,
request_seq: 0,
seq: 0,
body: undefined
});
});
});
describe("onMessage", () => {
it("should not throw when commands are executed with invalid arguments", () => {
let i = 0;
for (name in CommandNames) {
if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) {
continue;
}
const req: protocol.Request = {
command: name,
seq: i++,
type: "command"
};
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.arguments = {};
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.arguments = null;
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.arguments = "";
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.arguments = 0;
session.onMessage(JSON.stringify(req));
req.seq = i++;
req.arguments = [];
session.onMessage(JSON.stringify(req));
}
session.onMessage("GARBAGE NON_JSON DATA");
});
it("should output the response for a correctly handled message", () => {
const req: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "command",
arguments: {
hostInfo: "unit test",
formatOptions: {
newLineCharacter: "`n"
}
}
};
session.onMessage(JSON.stringify(req));
expect(lastSent).to.deep.equal(<protocol.ConfigureResponse>{
command: CommandNames.Configure,
type: "response",
success: true,
request_seq: 0,
seq: 0,
body: undefined
});
});
});
describe("send", () => {
it("is an overrideable handle which sends protocol messages over the wire", () => {
const msg = {seq: 0, type: "none"};
const strmsg = JSON.stringify(msg);
const len = 1 + Buffer.byteLength(strmsg, "utf8");
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
session.send = Session.prototype.send;
assert(session.send);
expect(session.send(msg)).to.not.exist;
expect(lastWrittenToHost).to.equal(resultMsg);
});
});
describe("addProtocolHandler", () => {
it("can add protocol handlers", () => {
const respBody = {
item: false
};
const command = "newhandle";
const result = {
response: respBody,
responseRequired: true
};
session.addProtocolHandler(command, (req) => result);
expect(session.executeCommand({
command,
seq: 0,
type: "command"
})).to.deep.equal(result);
});
it("throws when a duplicate handler is passed", () => {
const respBody = {
item: false
};
const resp = {
response: respBody,
responseRequired: true
};
const command = "newhandle";
session.addProtocolHandler(command, (req) => resp);
expect(() => session.addProtocolHandler(command, (req) => resp))
.to.throw(`Protocol handler already exists for command "${command}"`);
});
});
describe("event", () => {
it("can format event responses and send them", () => {
const evt = "notify-test";
const info = {
test: true
};
session.event(info, evt);
expect(lastSent).to.deep.equal({
type: "event",
seq: 0,
event: evt,
body: info
});
});
});
describe("output", () => {
it("can format command responses and send them", () => {
const body = {
block: {
key: "value"
}
};
const command = "test";
session.output(body, command);
expect(lastSent).to.deep.equal({
seq: 0,
request_seq: 0,
type: "response",
command,
body: body,
success: true
});
});
});
});
describe("how Session is extendable via subclassing", () => {
class TestSession extends Session {
lastSent: protocol.Message;
customHandler = "testhandler";
constructor() {
super(mockHost, Buffer.byteLength, process.hrtime, mockLogger);
this.addProtocolHandler(this.customHandler, () => {
return {response: undefined, responseRequired: true};
});
}
send(msg: protocol.Message) {
this.lastSent = msg;
}
};
it("can override methods such as send", () => {
const session = new TestSession();
const body = {
block: {
key: "value"
}
};
const command = "test";
session.output(body, command);
expect(session.lastSent).to.deep.equal({
seq: 0,
request_seq: 0,
type: "response",
command,
body: body,
success: true
});
});
it("can add and respond to new protocol handlers", () => {
const session = new TestSession();
expect(session.executeCommand({
seq: 0,
type: "command",
command: session.customHandler
})).to.deep.equal({
response: undefined,
responseRequired: true
});
});
it("has access to the project service", () => {
class ServiceSession extends TestSession {
constructor() {
super();
assert(this.projectService);
expect(this.projectService).to.be.instanceOf(ProjectService);
}
};
new ServiceSession();
});
});
describe("an example of using the Session API to create an in-process server", () => {
class InProcSession extends Session {
private queue: protocol.Request[] = [];
constructor(private client: InProcClient) {
super(mockHost, Buffer.byteLength, process.hrtime, mockLogger);
this.addProtocolHandler("echo", (req: protocol.Request) => ({
response: req.arguments,
responseRequired: true
}));
}
send(msg: protocol.Message) {
this.client.handle(msg);
}
enqueue(msg: protocol.Request) {
this.queue.unshift(msg);
}
handleRequest(msg: protocol.Request) {
let response: protocol.Response;
try {
({response} = this.executeCommand(msg));
}
catch (e) {
this.output(undefined, msg.command, msg.seq, e.toString());
return;
}
if (response) {
this.output(response, msg.command, msg.seq);
}
}
consumeQueue() {
while (this.queue.length > 0) {
const elem = this.queue.pop();
this.handleRequest(elem);
}
}
}
class InProcClient {
private server: InProcSession;
private seq = 0;
private callbacks: ts.Map<(resp: protocol.Response) => void> = {};
private eventHandlers: ts.Map<(args: any) => void> = {};
handle(msg: protocol.Message): void {
if (msg.type === "response") {
const response = <protocol.Response>msg;
if (this.callbacks[response.request_seq]) {
this.callbacks[response.request_seq](response);
delete this.callbacks[response.request_seq];
}
}
else if (msg.type === "event") {
const event = <protocol.Event>msg;
this.emit(event.event, event.body);
}
}
emit(name: string, args: any): void {
if (this.eventHandlers[name]) {
this.eventHandlers[name](args);
}
}
on(name: string, handler: (args: any) => void): void {
this.eventHandlers[name] = handler;
}
connect(session: InProcSession): void {
this.server = session;
}
execute(command: string, args: any, callback: (resp: protocol.Response) => void): void {
if (!this.server) {
return;
}
this.seq++;
this.server.enqueue({
seq: this.seq,
type: "command",
command,
arguments: args
});
this.callbacks[this.seq] = callback;
}
};
it("can be constructed and respond to commands", (done) => {
const cli = new InProcClient();
const session = new InProcSession(cli);
const toEcho = {
data: true
};
const toEvent = {
data: false
};
let responses = 0;
// Connect the client
cli.connect(session);
// Add an event handler
cli.on("testevent", (eventinfo) => {
expect(eventinfo).to.equal(toEvent);
responses++;
expect(responses).to.equal(1);
});
// Trigger said event from the server
session.event(toEvent, "testevent");
// Queue an echo command
cli.execute("echo", toEcho, (resp) => {
assert(resp.success, resp.message);
responses++;
expect(responses).to.equal(2);
expect(resp.body).to.deep.equal(toEcho);
});
// Queue a configure command
cli.execute("configure", {
hostInfo: "unit test",
formatOptions: {
newLineCharacter: "`n"
}
}, (resp) => {
assert(resp.success, resp.message);
responses++;
expect(responses).to.equal(3);
done();
});
// Consume the queue and trigger the callbacks
session.consumeQueue();
});
});
}

View File

@ -2,58 +2,120 @@
module ts {
describe("Transpile", () => {
function runTest(input: string, compilerOptions: ts.CompilerOptions = {}, fileName?: string, moduleName?: string, expectedOutput?: string, expectedDiagnosticCodes: number[] = []): void {
let diagnostics: Diagnostic[] = [];
let result = transpile(input, compilerOptions, fileName || "file.ts", diagnostics, moduleName);
interface TranspileTestSettings {
options?: TranspileOptions;
expectedOutput?: string;
expectedDiagnosticCodes?: number[];
}
function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes?: number[]) {
if(!expectedDiagnosticCodes) {
return;
}
for (let i = 0; i < expectedDiagnosticCodes.length; i++) {
assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expeced diagnostic.`);
}
assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
if (expectedOutput !== undefined) {
assert.equal(result, expectedOutput);
}
assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
}
function test(input: string, testSettings: TranspileTestSettings): void {
let diagnostics: Diagnostic[] = [];
let transpileOptions: TranspileOptions = testSettings.options || {};
let transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName);
transpileOptions.reportDiagnostics = true;
let transpileModuleResult = transpileModule(input, transpileOptions);
checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes);
checkDiagnostics(transpileModuleResult.diagnostics, testSettings.expectedDiagnosticCodes);
if (testSettings.expectedOutput !== undefined) {
assert.equal(transpileResult, testSettings.expectedOutput);
assert.equal(transpileModuleResult.outputText, testSettings.expectedOutput);
}
// check source maps
if (!transpileOptions.compilerOptions) {
transpileOptions.compilerOptions = {};
}
if (!transpileOptions.fileName) {
transpileOptions.fileName = "file.ts";
}
transpileOptions.compilerOptions.sourceMap = true;
let transpileModuleResultWithSourceMap = transpileModule(input, transpileOptions);
assert.isTrue(transpileModuleResultWithSourceMap.sourceMapText !== undefined);
let expectedSourceMapFileName = removeFileExtension(transpileOptions.fileName) + ".js.map";
let expectedSourceMappingUrlLine = `//# sourceMappingURL=${expectedSourceMapFileName}`;
if (testSettings.expectedOutput !== undefined) {
assert.equal(transpileModuleResultWithSourceMap.outputText, testSettings.expectedOutput + expectedSourceMappingUrlLine);
}
else {
// expected output is not set, just verify that output text has sourceMappingURL as a last line
let output = transpileModuleResultWithSourceMap.outputText;
assert.isTrue(output.length >= expectedSourceMappingUrlLine.length);
if (output.length === expectedSourceMappingUrlLine.length) {
assert.equal(output, expectedSourceMappingUrlLine);
}
else {
let suffix = getNewLineCharacter(transpileOptions.compilerOptions) + expectedSourceMappingUrlLine
assert.isTrue(output.indexOf(suffix, output.length - suffix.length) !== -1);
}
}
}
it("Generates correct compilerOptions diagnostics", () => {
// Expecting 5047: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher."
runTest(`var x = 0;`, {}, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [5047]);
test(`var x = 0;`, { expectedDiagnosticCodes: [5047] });
});
it("Generates no diagnostics with valid inputs", () => {
// No errors
runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates no diagnostics for missing file references", () => {
runTest(`/// <reference path="file2.ts" />
var x = 0;`,
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
test(`/// <reference path="file2.ts" />
var x = 0;`,
{ options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates no diagnostics for missing module imports", () => {
runTest(`import {a} from "module2";`,
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined,/*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
test(`import {a} from "module2";`,
{ options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates expected syntactic diagnostics", () => {
runTest(`a b`,
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [1005]); /// 1005: ';' Expected
test(`a b`,
{ options: { compilerOptions: { module: ModuleKind.CommonJS } }, expectedDiagnosticCodes: [1005] }); /// 1005: ';' Expected
});
it("Does not generate semantic diagnostics", () => {
runTest(`var x: string = 0;`,
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
test(`var x: string = 0;`,
{ options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates module output", () => {
runTest(`var x = 0;`, { module: ModuleKind.AMD }, /*fileName*/ undefined, /*moduleName*/undefined, `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`);
test(`var x = 0;`,
{
options: { compilerOptions: { module: ModuleKind.AMD } },
expectedOutput: `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`
});
});
it("Uses correct newLine character", () => {
runTest(`var x = 0;`, { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, /*moduleName*/undefined, `var x = 0;\n`, /*expectedDiagnosticCodes*/ []);
test(`var x = 0;`,
{
options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } },
expectedOutput: `var x = 0;\n`
});
});
it("Sets module name", () => {
@ -66,12 +128,15 @@ var x = 0;`,
` }\n` +
` }\n` +
`});\n`;
runTest("var x = 1;", { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, "NamedModule", output)
test("var x = 1;",
{
options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" },
expectedOutput: output
})
});
it("No extra errors for file without extension", () => {
runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, "file", /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/[]);
test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } });
});
});
}