New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Capture 'arguments' in arrow functions in pre-ES6 targets #2764
Changes from 15 commits
a8605c5
ace55aa
d3e0f74
7aa8892
3db3578
4b72353
53ccdfc
93a383c
c02dd3e
af06380
a7ea5ae
ca2d932
9b0e6df
a6012bc
037c360
3ef397e
fd0ff34
9e60a4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1419,7 +1419,7 @@ | |
"category": "Error", | ||
"code": 2495 | ||
}, | ||
"The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression.": { | ||
"The 'arguments' object cannot be referenced in an arrow function below ES6. Consider using a standard function expression.": { | ||
"category": "Error", | ||
"code": 2496 | ||
}, | ||
|
@@ -1439,6 +1439,14 @@ | |
"category": "Error", | ||
"code": 2500 | ||
}, | ||
"Duplicate identifier '_arguments'. Compiler uses variable declaration '_arguments' to capture 'arguments' reference.": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we just change these to be templated text, and pass the relevant identifiers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That way you can share the one for this and super |
||
"category": "Error", | ||
"code": 2501 | ||
}, | ||
"Expression resolves to variable declaration '_arguments' that compiler uses to capture 'arguments' reference.": { | ||
"category": "Error", | ||
"code": 2502 | ||
}, | ||
|
||
"Import declaration '{0}' is using private name '{1}'.": { | ||
"category": "Error", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1267,6 +1267,7 @@ module ts { | |
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; | ||
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; | ||
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; | ||
isCapturedArgumentsIdentifier(node: Identifier): void; | ||
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult; | ||
isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult; | ||
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant | ||
|
@@ -1393,18 +1394,19 @@ module 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 | ||
EmitExtends = 0x00000008, // Emit __extends | ||
SuperInstance = 0x00000010, // Instance 'super' reference | ||
SuperStatic = 0x00000020, // Static 'super' reference | ||
ContextChecked = 0x00000040, // Contextual types have been assigned | ||
LexicalThis = 0x00000002, // 'this' refers to a lexically captured '_this'. | ||
CaptureThis = 0x00000004, // 'this' needs to be captured as '_this' | ||
CaptureArguments = 0x00000008, // 'arguments' needs to be captured as '_arguments' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't you need a LexicalArguments flag too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, because unlike with |
||
EmitExtends = 0x00000010, // Emit __extends | ||
SuperInstance = 0x00000020, // Instance 'super' reference | ||
SuperStatic = 0x00000040, // Static 'super' reference | ||
ContextChecked = 0x00000080, // Contextual types have been assigned | ||
|
||
// Values for enum members have been computed, and any errors have been reported for them. | ||
EnumValuesComputed = 0x00000080, | ||
BlockScopedBindingInLoop = 0x00000100, | ||
EmitDecorate = 0x00000200, // Emit __decorate | ||
EmitParam = 0x00000400, // Emit __param helper for decorators | ||
EnumValuesComputed = 0x00000100, | ||
BlockScopedBindingInLoop = 0x00000200, | ||
EmitDecorate = 0x00000400, // Emit __decorate | ||
EmitParam = 0x00000800, // Emit __param helper for decorators | ||
} | ||
|
||
/* @internal */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -331,7 +331,7 @@ module ts { | |
return node.kind === SyntaxKind.EnumDeclaration && isConst(node); | ||
} | ||
|
||
function walkUpBindingElementsAndPatterns(node: Node): Node { | ||
export function walkUpBindingElementsAndPatterns(node: Node): Node { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like this name. But you don't have to change it now. Just saying |
||
while (node && (node.kind === SyntaxKind.BindingElement || isBindingPattern(node))) { | ||
node = node.parent; | ||
} | ||
|
@@ -513,6 +513,16 @@ module ts { | |
} | ||
} | ||
|
||
export function getArgumentsContainer(node: Node, includeArrowFunctions: boolean) { | ||
while (true) { | ||
node = getThisContainer(node, includeArrowFunctions); | ||
|
||
if (!node || isFunctionLike(node) || node.kind === SyntaxKind.SourceFile) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it not the same as the "this" container? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Y'know, in <ES6 mode, it might just be. See #2779. |
||
return <FunctionLikeDeclaration | SourceFile>node; | ||
} | ||
} | ||
} | ||
|
||
export function getThisContainer(node: Node, includeArrowFunctions: boolean): Node { | ||
while (true) { | ||
node = node.parent; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
tests/cases/conformance/es6/arrowFunction/emitArrowFunctionWhenUsingArguments01_ES6.ts(2,15): error TS2304: Cannot find name 'arguments'. | ||
tests/cases/conformance/es6/arrowFunction/emitArrowFunctionWhenUsingArguments01_ES6.ts(19,15): error TS2304: Cannot find name 'arguments'. | ||
|
||
|
||
==== tests/cases/conformance/es6/arrowFunction/emitArrowFunctionWhenUsingArguments01_ES6.ts (2 errors) ==== | ||
var a = () => { | ||
var arg = arguments[0]; // error | ||
~~~~~~~~~ | ||
!!! error TS2304: Cannot find name 'arguments'. | ||
} | ||
|
||
var b = function () { | ||
var a = () => { | ||
var arg = arguments[0]; // error | ||
} | ||
} | ||
|
||
function baz() { | ||
() => { | ||
var arg = arguments[0]; | ||
} | ||
} | ||
|
||
function foo(inputFunc: () => void) { } | ||
foo(() => { | ||
var arg = arguments[0]; // error | ||
~~~~~~~~~ | ||
!!! error TS2304: Cannot find name 'arguments'. | ||
}); | ||
|
||
function bar() { | ||
var arg = arguments[0]; // no error | ||
} | ||
|
||
|
||
() => { | ||
function foo() { | ||
var arg = arguments[0]; // no error | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just say "in ES3 or ES5"