diff --git a/package.json b/package.json index db39e0e923..2079c41fdd 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,11 @@ "tslint": "latest" }, "scripts": { - "test": "jake runtests" + "pretest": "jake tests", + "test": "jake runtests", + "build": "npm run build:compiler && npm run build:tests", + "build:compiler": "jake local", + "build:tests": "jake tests", + "clean": "jake clean" } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2ff2c8590d..c37189488b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6436,22 +6436,79 @@ namespace ts { let classType = classDeclaration && getDeclaredTypeOfSymbol(getSymbolOfNode(classDeclaration)); let baseClassType = classType && getBaseTypes(classType)[0]; + let container = getSuperContainer(node, /*includeFunctions*/ true); + let needToCaptureLexicalThis = false; + + if (!isCallExpression) { + // adjust the container reference in case if super is used inside arrow functions with arbitrary deep nesting + while (container && container.kind === SyntaxKind.ArrowFunction) { + container = getSuperContainer(container, /*includeFunctions*/ true); + needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6; + } + } + + let canUseSuperExpression = isLegalUsageOfSuperExpression(container); + let nodeCheckFlag: NodeCheckFlags = 0; + + // always set NodeCheckFlags for 'super' expression node + if (canUseSuperExpression) { + if ((container.flags & NodeFlags.Static) || isCallExpression) { + nodeCheckFlag = NodeCheckFlags.SuperStatic; + } + else { + nodeCheckFlag = NodeCheckFlags.SuperInstance; + } + + getNodeLinks(node).flags |= nodeCheckFlag; + + if (needToCaptureLexicalThis) { + // call expressions are allowed only in constructors so they should always capture correct 'this' + // super property access expressions can also appear in arrow functions - + // in this case they should also use correct lexical this + captureLexicalThis(node.parent, container); + } + } + if (!baseClassType) { if (!classDeclaration || !getClassExtendsHeritageClauseElement(classDeclaration)) { error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); } + return unknownType; + } + + if (!canUseSuperExpression) { + if (container && container.kind === SyntaxKind.ComputedPropertyName) { + error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); + } + else if (isCallExpression) { + error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors); + } + else { + error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); + } + return unknownType; } + + if (container.kind === SyntaxKind.Constructor && isInConstructorArgumentInitializer(node, container)) { + // issue custom error message for super property access in constructor arguments (to be aligned with old compiler) + error(node, Diagnostics.super_cannot_be_referenced_in_constructor_arguments); + return unknownType; + } + + return nodeCheckFlag === NodeCheckFlags.SuperStatic + ? getBaseConstructorTypeOfClass(classType) + : baseClassType; + + function isLegalUsageOfSuperExpression(container: Node): boolean { + if (!container) { + return false; + } - let container = getSuperContainer(node, /*includeFunctions*/ true); - - if (container) { - let canUseSuperExpression = false; - let needToCaptureLexicalThis: boolean; if (isCallExpression) { // TS 1.0 SPEC (April 2014): 4.8.1 // Super calls are only permitted in constructors of derived classes - canUseSuperExpression = container.kind === SyntaxKind.Constructor; + return container.kind === SyntaxKind.Constructor; } else { // TS 1.0 SPEC (April 2014) @@ -6459,75 +6516,28 @@ namespace ts { // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance // - In a static member function or static member accessor - // super property access might appear in arrow functions with arbitrary deep nesting - needToCaptureLexicalThis = false; - while (container && container.kind === SyntaxKind.ArrowFunction) { - container = getSuperContainer(container, /*includeFunctions*/ true); - needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6; - } - // topmost container must be something that is directly nested in the class declaration if (container && isClassLike(container.parent)) { if (container.flags & NodeFlags.Static) { - canUseSuperExpression = - container.kind === SyntaxKind.MethodDeclaration || - container.kind === SyntaxKind.MethodSignature || - container.kind === SyntaxKind.GetAccessor || - container.kind === SyntaxKind.SetAccessor; + return container.kind === SyntaxKind.MethodDeclaration || + container.kind === SyntaxKind.MethodSignature || + container.kind === SyntaxKind.GetAccessor || + container.kind === SyntaxKind.SetAccessor; } else { - canUseSuperExpression = - container.kind === SyntaxKind.MethodDeclaration || - container.kind === SyntaxKind.MethodSignature || - container.kind === SyntaxKind.GetAccessor || - container.kind === SyntaxKind.SetAccessor || - container.kind === SyntaxKind.PropertyDeclaration || - container.kind === SyntaxKind.PropertySignature || - container.kind === SyntaxKind.Constructor; + return container.kind === SyntaxKind.MethodDeclaration || + container.kind === SyntaxKind.MethodSignature || + container.kind === SyntaxKind.GetAccessor || + container.kind === SyntaxKind.SetAccessor || + container.kind === SyntaxKind.PropertyDeclaration || + container.kind === SyntaxKind.PropertySignature || + container.kind === SyntaxKind.Constructor; } } } - - if (canUseSuperExpression) { - let returnType: Type; - - if ((container.flags & NodeFlags.Static) || isCallExpression) { - getNodeLinks(node).flags |= NodeCheckFlags.SuperStatic; - returnType = getBaseConstructorTypeOfClass(classType); - } - else { - getNodeLinks(node).flags |= NodeCheckFlags.SuperInstance; - returnType = baseClassType; - } - - if (container.kind === SyntaxKind.Constructor && isInConstructorArgumentInitializer(node, container)) { - // issue custom error message for super property access in constructor arguments (to be aligned with old compiler) - error(node, Diagnostics.super_cannot_be_referenced_in_constructor_arguments); - returnType = unknownType; - } - - if (!isCallExpression && needToCaptureLexicalThis) { - // call expressions are allowed only in constructors so they should always capture correct 'this' - // super property access expressions can also appear in arrow functions - - // in this case they should also use correct lexical this - captureLexicalThis(node.parent, container); - } - - return returnType; - } - } - - if (container && container.kind === SyntaxKind.ComputedPropertyName) { - error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); - } - else if (isCallExpression) { - error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors); - } - else { - error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); - } - - return unknownType; + + return false; + } } // Return contextual type of parameter or undefined if no contextual type is available diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 98c551027f..cb5eb86466 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6259,6 +6259,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi write(`], function(${exportFunctionForFile}) {`); writeLine(); increaseIndent(); + emitEmitHelpers(node); emitCaptureThisForNodeIfNecessary(node); emitSystemModuleBody(node, startIndex); decreaseIndent(); @@ -6330,6 +6331,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitAMDModule(node: SourceFile, startIndex: number) { + emitEmitHelpers(node); collectExternalModuleInfo(node); writeLine(); @@ -6351,6 +6353,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitCommonJSModule(node: SourceFile, startIndex: number) { + emitEmitHelpers(node); collectExternalModuleInfo(node); emitExportStarHelper(); emitCaptureThisForNodeIfNecessary(node); @@ -6360,6 +6363,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitUMDModule(node: SourceFile, startIndex: number) { + emitEmitHelpers(node); collectExternalModuleInfo(node); // Module is detected first to support Browserify users that load into a browser with an AMD loader @@ -6389,6 +6393,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi exportSpecifiers = undefined; exportEquals = undefined; hasExportStars = false; + emitEmitHelpers(node); emitCaptureThisForNodeIfNecessary(node); emitLinesStartingAt(node.statements, startIndex); emitTempDeclarations(/*newLine*/ true); @@ -6527,14 +6532,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } - function emitSourceFileNode(node: SourceFile) { - // Start new file on new line - writeLine(); - emitDetachedComments(node); - - // emit prologue directives prior to __extends - let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false); - + function emitEmitHelpers(node: SourceFile): void { // Only emit helpers if the user did not say otherwise. if (!compilerOptions.noEmitHelpers) { // Only Emit __extends function when target ES5. @@ -6562,6 +6560,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi awaiterEmitted = true; } } + } + + function emitSourceFileNode(node: SourceFile) { + // Start new file on new line + writeLine(); + emitShebang(); + emitDetachedComments(node); + + // emit prologue directives prior to __extends + let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false); if (isExternalModule(node) || compilerOptions.isolatedModules) { if (languageVersion >= ScriptTarget.ES6) { @@ -6585,6 +6593,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi exportSpecifiers = undefined; exportEquals = undefined; hasExportStars = false; + emitEmitHelpers(node); emitCaptureThisForNodeIfNecessary(node); emitLinesStartingAt(node.statements, startIndex); emitTempDeclarations(/*newLine*/ true); @@ -6978,6 +6987,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } } + + function emitShebang() { + let shebang = getShebang(currentSourceFile.text); + if (shebang) { + write(shebang); + } + } function isPinnedOrTripleSlashComment(comment: CommentRange) { if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 8aaed56667..ac4119b385 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -408,6 +408,9 @@ namespace ts { case CharacterCodes.greaterThan: // Starts of conflict marker trivia return true; + case CharacterCodes.hash: + // Only if its the beginning can we have #! trivia + return pos === 0; default: return ch > CharacterCodes.maxAsciiCharacter; } @@ -468,6 +471,13 @@ namespace ts { } break; + case CharacterCodes.hash: + if (isShebangTrivia(text, pos)) { + pos = scanShebangTrivia(text, pos); + continue; + } + break; + default: if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch) || isLineBreak(ch))) { pos++; @@ -535,6 +545,20 @@ namespace ts { return pos; } + const shebangTriviaRegex = /^#!.*/; + + function isShebangTrivia(text: string, pos: number) { + // Shebangs check must only be done at the start of the file + Debug.assert(pos === 0); + return shebangTriviaRegex.test(text); + } + + function scanShebangTrivia(text: string, pos: number) { + let shebang = shebangTriviaRegex.exec(text)[0]; + pos = pos + shebang.length; + return pos; + } + /** * Extract comments from text prefixing the token closest following `pos`. * The return value is an array containing a TextRange for each comment. @@ -628,6 +652,13 @@ namespace ts { export function getTrailingCommentRanges(text: string, pos: number): CommentRange[] { return getCommentRanges(text, pos, /*trailing*/ true); } + + /** Optionally, get the shebang */ + export function getShebang(text: string): string { + return shebangTriviaRegex.test(text) + ? shebangTriviaRegex.exec(text)[0] + : undefined; + } export function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean { return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z || @@ -1098,6 +1129,18 @@ namespace ts { return token = SyntaxKind.EndOfFileToken; } let ch = text.charCodeAt(pos); + + // Special handling for shebang + if (ch === CharacterCodes.hash && pos === 0 && isShebangTrivia(text, pos)) { + pos = scanShebangTrivia(text ,pos); + if (skipTrivia) { + continue; + } + else { + return token = SyntaxKind.ShebangTrivia; + } + } + switch (ch) { case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 6872c4c876..880180b133 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -14,7 +14,7 @@ namespace ts { let matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase()); if (!matchResult) { - errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, 'en', 'ja-jp')); + errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp")); return false; } @@ -49,7 +49,7 @@ namespace ts { } // TODO: Add codePage support for readFile? - let fileContents = ''; + let fileContents = ""; try { fileContents = sys.readFile(filePath); } @@ -355,22 +355,23 @@ namespace ts { return { program, exitStatus }; function compileProgram(): ExitStatus { - // First get any syntactic errors. - let diagnostics = program.getSyntacticDiagnostics(); - reportDiagnostics(diagnostics); + let diagnostics: Diagnostic[]; + + // First get and report any syntactic errors. + diagnostics = program.getSyntacticDiagnostics(); // If we didn't have any syntactic errors, then also try getting the global and // semantic errors. if (diagnostics.length === 0) { - let diagnostics = program.getGlobalDiagnostics(); - reportDiagnostics(diagnostics); + diagnostics = program.getGlobalDiagnostics(); if (diagnostics.length === 0) { - let diagnostics = program.getSemanticDiagnostics(); - reportDiagnostics(diagnostics); + diagnostics = program.getSemanticDiagnostics(); } } + reportDiagnostics(diagnostics); + // If the user doesn't want us to emit, then we're done at this point. if (compilerOptions.noEmit) { return diagnostics.length diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e8f033562e..eb908d07ec 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -17,6 +17,7 @@ namespace ts { } // token > SyntaxKind.Identifer => token is a keyword + // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync export const enum SyntaxKind { Unknown, EndOfFileToken, @@ -24,6 +25,8 @@ namespace ts { MultiLineCommentTrivia, NewLineTrivia, WhitespaceTrivia, + // We detect and preserve #! on the first line + ShebangTrivia, // We detect and provide better error recovery when we encounter a git merge marker. This // allows us to edit files with git-conflict markers in them in a much more pleasant manner. ConflictMarkerTrivia, diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index 30951b90fc..9d44dfdc03 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -75,28 +75,28 @@ function delint(sourceFile) { delintNode(sourceFile); function delintNode(node) { switch (node.kind) { - case 196 /* ForStatement */: - case 197 /* ForInStatement */: - case 195 /* WhileStatement */: - case 194 /* DoStatement */: - if (node.statement.kind !== 189 /* Block */) { + case 197 /* ForStatement */: + case 198 /* ForInStatement */: + case 196 /* WhileStatement */: + case 195 /* DoStatement */: + if (node.statement.kind !== 190 /* Block */) { report(node, "A looping statement's contents should be wrapped in a block body."); } break; - case 193 /* IfStatement */: + case 194 /* IfStatement */: var ifStatement = node; - if (ifStatement.thenStatement.kind !== 189 /* Block */) { + if (ifStatement.thenStatement.kind !== 190 /* Block */) { report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body."); } if (ifStatement.elseStatement && - ifStatement.elseStatement.kind !== 189 /* Block */ && - ifStatement.elseStatement.kind !== 193 /* IfStatement */) { + ifStatement.elseStatement.kind !== 190 /* Block */ && + ifStatement.elseStatement.kind !== 194 /* IfStatement */) { report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body."); } break; - case 178 /* BinaryExpression */: + case 179 /* BinaryExpression */: var op = node.operatorToken.kind; - if (op === 29 /* EqualsEqualsToken */ || op == 30 /* ExclamationEqualsToken */) { + if (op === 30 /* EqualsEqualsToken */ || op == 31 /* ExclamationEqualsToken */) { report(node, "Use '===' and '!=='."); } break; diff --git a/tests/baselines/reference/errorSuperPropertyAccess.js b/tests/baselines/reference/errorSuperPropertyAccess.js index 57a574d8a0..6e35248cd3 100644 --- a/tests/baselines/reference/errorSuperPropertyAccess.js +++ b/tests/baselines/reference/errorSuperPropertyAccess.js @@ -139,14 +139,14 @@ var __extends = (this && this.__extends) || function (d, b) { //super property access in instance member accessor(get and set) of class with no base type var NoBase = (function () { function NoBase() { - this.m = _super.prototype; - this.n = _super.hasOwnProperty.call(this, ''); - var a = _super.prototype; - var b = _super.hasOwnProperty.call(this, ''); + this.m = _super.prototype.prototype; + this.n = _super.prototype.hasOwnProperty.call(this, ''); + var a = _super.prototype.prototype; + var b = _super.prototype.hasOwnProperty.call(this, ''); } NoBase.prototype.fn = function () { - var a = _super.prototype; - var b = _super.hasOwnProperty.call(this, ''); + var a = _super.prototype.prototype; + var b = _super.prototype.hasOwnProperty.call(this, ''); }; //super static property access in static member function of class with no base type //super static property access in static member accessor(get and set) of class with no base type diff --git a/tests/baselines/reference/parserSuperExpression1.js b/tests/baselines/reference/parserSuperExpression1.js index 0d312f7910..0d219afad3 100644 --- a/tests/baselines/reference/parserSuperExpression1.js +++ b/tests/baselines/reference/parserSuperExpression1.js @@ -18,7 +18,7 @@ var C = (function () { function C() { } C.prototype.foo = function () { - _super.foo.call(this); + _super.prototype.foo.call(this); }; return C; })(); @@ -30,7 +30,7 @@ var M1; function C() { } C.prototype.foo = function () { - _super.foo.call(this); + _super.prototype.foo.call(this); }; return C; })(); diff --git a/tests/baselines/reference/parserSuperExpression2.js b/tests/baselines/reference/parserSuperExpression2.js index 7a77c28ef5..eb3c2c697e 100644 --- a/tests/baselines/reference/parserSuperExpression2.js +++ b/tests/baselines/reference/parserSuperExpression2.js @@ -10,7 +10,7 @@ var C = (function () { function C() { } C.prototype.M = function () { - _super..call(this, 0); + _super.prototype..call(this, 0); }; return C; })(); diff --git a/tests/baselines/reference/parserSuperExpression4.js b/tests/baselines/reference/parserSuperExpression4.js index 46ffc65f57..59ba63bb2c 100644 --- a/tests/baselines/reference/parserSuperExpression4.js +++ b/tests/baselines/reference/parserSuperExpression4.js @@ -18,7 +18,7 @@ var C = (function () { function C() { } C.prototype.foo = function () { - _super.foo = 1; + _super.prototype.foo = 1; }; return C; })(); @@ -30,7 +30,7 @@ var M1; function C() { } C.prototype.foo = function () { - _super.foo = 1; + _super.prototype.foo = 1; }; return C; })(); diff --git a/tests/baselines/reference/shebang.js b/tests/baselines/reference/shebang.js new file mode 100644 index 0000000000..d7e3a4d835 --- /dev/null +++ b/tests/baselines/reference/shebang.js @@ -0,0 +1,8 @@ +//// [shebang.ts] +#!/usr/bin/env node +var foo = 'I wish the generated JS to be executed in node'; + + +//// [shebang.js] +#!/usr/bin/env node +var foo = 'I wish the generated JS to be executed in node'; diff --git a/tests/baselines/reference/shebang.symbols b/tests/baselines/reference/shebang.symbols new file mode 100644 index 0000000000..37ad543667 --- /dev/null +++ b/tests/baselines/reference/shebang.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/shebang.ts === +#!/usr/bin/env node +var foo = 'I wish the generated JS to be executed in node'; +>foo : Symbol(foo, Decl(shebang.ts, 1, 3)) + diff --git a/tests/baselines/reference/shebang.types b/tests/baselines/reference/shebang.types new file mode 100644 index 0000000000..5fd6f0533e --- /dev/null +++ b/tests/baselines/reference/shebang.types @@ -0,0 +1,6 @@ +=== tests/cases/compiler/shebang.ts === +#!/usr/bin/env node +var foo = 'I wish the generated JS to be executed in node'; +>foo : string +>'I wish the generated JS to be executed in node' : string + diff --git a/tests/baselines/reference/shebangError.errors.txt b/tests/baselines/reference/shebangError.errors.txt new file mode 100644 index 0000000000..e8197d8bc5 --- /dev/null +++ b/tests/baselines/reference/shebangError.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/shebangError.ts(2,1): error TS1127: Invalid character. +tests/cases/compiler/shebangError.ts(2,2): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/shebangError.ts(2,12): error TS2304: Cannot find name 'env'. +tests/cases/compiler/shebangError.ts(2,16): error TS1005: ';' expected. +tests/cases/compiler/shebangError.ts(2,16): error TS2304: Cannot find name 'node'. + + +==== tests/cases/compiler/shebangError.ts (5 errors) ==== + var foo = 'Shebang is only allowed on the first line'; + #!/usr/bin/env node + +!!! error TS1127: Invalid character. + ~~~~~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~ +!!! error TS2304: Cannot find name 'env'. + ~~~~ +!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2304: Cannot find name 'node'. \ No newline at end of file diff --git a/tests/baselines/reference/shebangError.js b/tests/baselines/reference/shebangError.js new file mode 100644 index 0000000000..a8fb376d8a --- /dev/null +++ b/tests/baselines/reference/shebangError.js @@ -0,0 +1,8 @@ +//// [shebangError.ts] +var foo = 'Shebang is only allowed on the first line'; +#!/usr/bin/env node + +//// [shebangError.js] +var foo = 'Shebang is only allowed on the first line'; +!/usr/bin / env; +node; diff --git a/tests/baselines/reference/super.js b/tests/baselines/reference/super.js index a6b698413e..1d060672ce 100644 --- a/tests/baselines/reference/super.js +++ b/tests/baselines/reference/super.js @@ -79,7 +79,7 @@ var Base2 = (function () { function Base2() { } Base2.prototype.foo = function () { - _super.foo.call(this); + _super.prototype.foo.call(this); }; return Base2; })(); diff --git a/tests/baselines/reference/super1.js b/tests/baselines/reference/super1.js index 6a52cfcd9e..5c2182d8af 100644 --- a/tests/baselines/reference/super1.js +++ b/tests/baselines/reference/super1.js @@ -165,7 +165,7 @@ var Base4; function Sub4E() { } Sub4E.prototype.x = function () { - return _super.x.call(this); + return _super.prototype.x.call(this); }; return Sub4E; })(); diff --git a/tests/baselines/reference/superCallWithMissingBaseClass.errors.txt b/tests/baselines/reference/superCallWithMissingBaseClass.errors.txt new file mode 100644 index 0000000000..0f4e4b7dd1 --- /dev/null +++ b/tests/baselines/reference/superCallWithMissingBaseClass.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/superCallWithMissingBaseClass.ts(1,19): error TS2304: Cannot find name 'Bar'. + + +==== tests/cases/compiler/superCallWithMissingBaseClass.ts (1 errors) ==== + class Foo extends Bar { + ~~~ +!!! error TS2304: Cannot find name 'Bar'. + m1() { + return super.m1(); + } + + static m2() { + return super.m2(); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superCallWithMissingBaseClass.js b/tests/baselines/reference/superCallWithMissingBaseClass.js new file mode 100644 index 0000000000..101e709653 --- /dev/null +++ b/tests/baselines/reference/superCallWithMissingBaseClass.js @@ -0,0 +1,30 @@ +//// [superCallWithMissingBaseClass.ts] +class Foo extends Bar { + m1() { + return super.m1(); + } + + static m2() { + return super.m2(); + } +} + +//// [superCallWithMissingBaseClass.js] +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; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var Foo = (function (_super) { + __extends(Foo, _super); + function Foo() { + _super.apply(this, arguments); + } + Foo.prototype.m1 = function () { + return _super.prototype.m1.call(this); + }; + Foo.m2 = function () { + return _super.m2.call(this); + }; + return Foo; +})(Bar); diff --git a/tests/baselines/reference/systemModuleWithSuperClass.js b/tests/baselines/reference/systemModuleWithSuperClass.js new file mode 100644 index 0000000000..3484606ee0 --- /dev/null +++ b/tests/baselines/reference/systemModuleWithSuperClass.js @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/systemModuleWithSuperClass.ts] //// + +//// [foo.ts] + +export class Foo { + a: string; +} + +//// [bar.ts] +import {Foo} from './foo'; +export class Bar extends Foo { + b: string; +} + +//// [foo.js] +System.register([], function(exports_1) { + var Foo; + return { + setters:[], + execute: function() { + Foo = (function () { + function Foo() { + } + return Foo; + })(); + exports_1("Foo", Foo); + } + } +}); +//// [bar.js] +System.register(['./foo'], function(exports_1) { + 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; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + var foo_1; + var Bar; + return { + setters:[ + function (_foo_1) { + foo_1 = _foo_1; + }], + execute: function() { + Bar = (function (_super) { + __extends(Bar, _super); + function Bar() { + _super.apply(this, arguments); + } + return Bar; + })(foo_1.Foo); + exports_1("Bar", Bar); + } + } +}); diff --git a/tests/baselines/reference/systemModuleWithSuperClass.symbols b/tests/baselines/reference/systemModuleWithSuperClass.symbols new file mode 100644 index 0000000000..4635433347 --- /dev/null +++ b/tests/baselines/reference/systemModuleWithSuperClass.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/foo.ts === + +export class Foo { +>Foo : Symbol(Foo, Decl(foo.ts, 0, 0)) + + a: string; +>a : Symbol(a, Decl(foo.ts, 1, 18)) +} + +=== tests/cases/compiler/bar.ts === +import {Foo} from './foo'; +>Foo : Symbol(Foo, Decl(bar.ts, 0, 8)) + +export class Bar extends Foo { +>Bar : Symbol(Bar, Decl(bar.ts, 0, 26)) +>Foo : Symbol(Foo, Decl(bar.ts, 0, 8)) + + b: string; +>b : Symbol(b, Decl(bar.ts, 1, 30)) +} diff --git a/tests/baselines/reference/systemModuleWithSuperClass.types b/tests/baselines/reference/systemModuleWithSuperClass.types new file mode 100644 index 0000000000..130f53f0ce --- /dev/null +++ b/tests/baselines/reference/systemModuleWithSuperClass.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/foo.ts === + +export class Foo { +>Foo : Foo + + a: string; +>a : string +} + +=== tests/cases/compiler/bar.ts === +import {Foo} from './foo'; +>Foo : typeof Foo + +export class Bar extends Foo { +>Bar : Bar +>Foo : Foo + + b: string; +>b : string +} diff --git a/tests/cases/compiler/shebang.ts b/tests/cases/compiler/shebang.ts new file mode 100644 index 0000000000..3456df0fad --- /dev/null +++ b/tests/cases/compiler/shebang.ts @@ -0,0 +1,2 @@ +#!/usr/bin/env node +var foo = 'I wish the generated JS to be executed in node'; diff --git a/tests/cases/compiler/shebangError.ts b/tests/cases/compiler/shebangError.ts new file mode 100644 index 0000000000..91a27a65aa --- /dev/null +++ b/tests/cases/compiler/shebangError.ts @@ -0,0 +1,2 @@ +var foo = 'Shebang is only allowed on the first line'; +#!/usr/bin/env node \ No newline at end of file diff --git a/tests/cases/compiler/superCallWithMissingBaseClass.ts b/tests/cases/compiler/superCallWithMissingBaseClass.ts new file mode 100644 index 0000000000..6f7ede1019 --- /dev/null +++ b/tests/cases/compiler/superCallWithMissingBaseClass.ts @@ -0,0 +1,9 @@ +class Foo extends Bar { + m1() { + return super.m1(); + } + + static m2() { + return super.m2(); + } +} \ No newline at end of file diff --git a/tests/cases/compiler/systemModuleWithSuperClass.ts b/tests/cases/compiler/systemModuleWithSuperClass.ts new file mode 100644 index 0000000000..2f1c21f4d4 --- /dev/null +++ b/tests/cases/compiler/systemModuleWithSuperClass.ts @@ -0,0 +1,12 @@ +// @module: system + +// @Filename: foo.ts +export class Foo { + a: string; +} + +// @Filename: bar.ts +import {Foo} from './foo'; +export class Bar extends Foo { + b: string; +} \ No newline at end of file diff --git a/tslint.json b/tslint.json index 16a69b81f8..71dc6730de 100644 --- a/tslint.json +++ b/tslint.json @@ -4,20 +4,31 @@ "comment-format": [true, "check-space" ], - "indent": true, + "indent": [true, + "spaces" + ], "one-line": [true, "check-open-brace" ], "no-unreachable": true, "no-use-before-declare": true, "no-var-keyword": true, - "quotemark": true, + "quotemark": [true, + "double" + ], "semicolon": true, "whitespace": [true, "check-branch", "check-operator", "check-separator", "check-type" - ] + ], + "typedef-whitespace": [true, { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }] } }