Merge branch 'master' into fixDecoratedClassName

This commit is contained in:
Ron Buckton
2016-01-28 17:59:04 -08:00
59 changed files with 918 additions and 81 deletions

View File

@@ -1462,7 +1462,7 @@ namespace ts {
function bindCallExpression(node: CallExpression) {
// We're only inspecting call expressions to detect CommonJS modules, so we can skip
// this check if we've already seen the module indicator
if (!file.commonJsModuleIndicator && isRequireCall(node)) {
if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteral*/false)) {
setCommonJsModuleIndicator(node);
}
}

View File

@@ -7288,6 +7288,14 @@ namespace ts {
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;
if (container.kind === SyntaxKind.Constructor) {
const baseTypeNode = getClassExtendsHeritageClauseElement(<ClassLikeDeclaration>container.parent);
if (baseTypeNode && !(getNodeCheckFlags(container) & NodeCheckFlags.HasSeenSuperCall)) {
// In ES6, super inside constructor of class-declaration has to precede "this" accessing
error(node, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}
}
// Now skip arrow functions to get the "real" owner of 'this'.
if (container.kind === SyntaxKind.ArrowFunction) {
container = getThisContainer(container, /* includeArrowFunctions */ false);
@@ -10234,6 +10242,11 @@ namespace ts {
const signature = getResolvedSignature(node);
if (node.expression.kind === SyntaxKind.SuperKeyword) {
const containgFunction = getContainingFunction(node.expression);
if (containgFunction && containgFunction.kind === SyntaxKind.Constructor) {
getNodeLinks(containgFunction).flags |= NodeCheckFlags.HasSeenSuperCall;
}
return voidType;
}
if (node.kind === SyntaxKind.NewExpression) {
@@ -10260,7 +10273,7 @@ namespace ts {
}
// In JavaScript files, calls to any identifier 'require' are treated as external module imports
if (isInJavaScriptFile(node) && isRequireCall(node)) {
if (isInJavaScriptFile(node) && isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) {
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
}
@@ -11851,10 +11864,6 @@ namespace ts {
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(superCallStatement.expression);
}
}
}
else if (baseConstructorType !== nullType) {

View File

@@ -2771,5 +2771,9 @@
"JSX element '{0}' has no corresponding closing tag.": {
"category": "Error",
"code": 17008
},
"'super' must be called before accessing 'this' in the constructor of a derived class.": {
"category": "Error",
"code": 17009
}
}

View File

@@ -1328,7 +1328,7 @@ namespace ts {
}
function collectRequireCalls(node: Node): void {
if (isRequireCall(node)) {
if (isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) {
(imports || (imports = [])).push(<StringLiteral>(<CallExpression>node).arguments[0]);
}
else {

View File

@@ -2054,24 +2054,23 @@ namespace ts {
/* @internal */
export const enum NodeCheckFlags {
TypeChecked = 0x00000001, // Node has been type checked
LexicalThis = 0x00000002, // Lexical 'this' reference
CaptureThis = 0x00000004, // Lexical 'this' used in body
SuperInstance = 0x00000100, // Instance 'super' reference
SuperStatic = 0x00000200, // Static 'super' reference
ContextChecked = 0x00000400, // Contextual types have been assigned
AsyncMethodWithSuper = 0x00000800, // An async method that reads a value from a member of 'super'.
AsyncMethodWithSuperBinding = 0x00001000, // An async method that assigns a value to a member of 'super'.
CaptureArguments = 0x00002000, // Lexical 'arguments' used in body (for async functions)
// Values for enum members have been computed, and any errors have been reported for them.
EnumValuesComputed = 0x00004000,
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body.
BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body.
TypeChecked = 0x00000001, // Node has been type checked
LexicalThis = 0x00000002, // Lexical 'this' reference
CaptureThis = 0x00000004, // Lexical 'this' used in body
SuperInstance = 0x00000100, // Instance 'super' reference
SuperStatic = 0x00000200, // Static 'super' reference
ContextChecked = 0x00000400, // Contextual types have been assigned
AsyncMethodWithSuper = 0x00000800, // An async method that reads a value from a member of 'super'.
AsyncMethodWithSuperBinding = 0x00001000, // An async method that assigns a value to a member of 'super'.
CaptureArguments = 0x00002000, // Lexical 'arguments' used in body (for async functions)
EnumValuesComputed = 0x00004000, // Values for enum members have been computed, and any errors have been reported for them.
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
HasSeenSuperCall = 0x00080000, // Set during the binding when encounter 'super'
ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body.
}
/* @internal */

View File

@@ -1086,12 +1086,14 @@ namespace ts {
* exactly one argument.
* This function does not test if the node is in a JavaScript file or not.
*/
export function isRequireCall(expression: Node): expression is CallExpression {
export function isRequireCall(expression: Node, checkArgumentIsStringLiteral: boolean): expression is CallExpression {
// of the form 'require("name")'
return expression.kind === SyntaxKind.CallExpression &&
(<CallExpression>expression).expression.kind === SyntaxKind.Identifier &&
(<Identifier>(<CallExpression>expression).expression).text === "require" &&
(<CallExpression>expression).arguments.length === 1;
const isRequire = expression.kind === SyntaxKind.CallExpression &&
(<CallExpression>expression).expression.kind === SyntaxKind.Identifier &&
(<Identifier>(<CallExpression>expression).expression).text === "require" &&
(<CallExpression>expression).arguments.length === 1;
return isRequire && (!checkArgumentIsStringLiteral || (<CallExpression>expression).arguments[0].kind === SyntaxKind.StringLiteral);
}
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property