Skip to content
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

New with spread #3066

Merged
merged 11 commits into from
May 18, 2015
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ tests/services/baselines/local/*
tests/baselines/prototyping/local/*
tests/baselines/rwc/*
tests/baselines/test262/*
tests/baselines/reference/projectOutput/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was this added to the .gitignore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got multiple files outputted there every time I run jake runtests:

screen shot 2015-05-07 at 9 49 45 pm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CyrusNajmabadi i think this is a fair one to add, ppl have made this mistake multiple times already. mainly because of a mocha issue on node 0.10.*

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I don't think there's any real harm in having it

tests/baselines/local/projectOutput/*
tests/services/baselines/prototyping/local/*
tests/services/browser/typescriptServices.js
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6599,7 +6599,7 @@ module ts {
result.splice(spliceIndex, 0, signature);
}
}

function getSpreadArgumentIndex(args: Expression[]): number {
for (let i = 0; i < args.length; i++) {
if (args[i].kind === SyntaxKind.SpreadElementExpression) {
Expand Down Expand Up @@ -7121,10 +7121,10 @@ module ts {
}

function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature {
if (node.arguments && languageVersion < ScriptTarget.ES6) {
if (node.arguments && languageVersion < ScriptTarget.ES5) {
let spreadIndex = getSpreadArgumentIndex(node.arguments);
if (spreadIndex >= 0) {
error(node.arguments[spreadIndex], Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher);
error(node.arguments[spreadIndex], Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher);
}
}

Expand All @@ -7142,7 +7142,7 @@ module ts {
// If ConstructExpr's apparent type(section 3.8.1) is an object type with one or
// more construct signatures, the expression is processed in the same manner as a
// function call, but using the construct signatures as the initial set of candidate
// signatures for overload resolution.The result type of the function call becomes
// signatures for overload resolution. The result type of the function call becomes
// the result type of the operation.
expressionType = getApparentType(expressionType);
if (expressionType === unknownType) {
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ module ts {
The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to type 'symbol'." },
Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: DiagnosticCategory.Error, key: "'Symbol' reference does not refer to the global Symbol constructor object." },
A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: DiagnosticCategory.Error, key: "A computed property name of the form '{0}' must be of type 'symbol'." },
Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2472, category: DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." },
Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: { code: 2472, category: DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher." },
Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." },
In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." },
const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." },
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@
"category": "Error",
"code": 2471
},
"Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher.": {
"Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher.": {
"category": "Error",
"code": 2472
},
Expand Down
41 changes: 37 additions & 4 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1886,11 +1886,44 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {

function emitNewExpression(node: NewExpression) {
write("new ");
emit(node.expression);
if (node.arguments) {

// Spread operator logic can be supported in new expressions in ES5 using a combination
// of Function.prototype.bind() and Function.prototype.apply().
//
// Example:
//
// var arguments = [1, 2, 3, 4, 5];
// new Array(...arguments);
//
// Could be transpiled into ES5:
//
// var arguments = [1, 2, 3, 4, 5];
// new (Array.bind.apply(Array, [void 0].concat(arguments)));
//
// `[void 0]` is the first argument which represents `thisArg` to the bind method above.
// And `thisArg` will be set to the return value of the constructor when instantiated
// with the new operator — regardless of any value we set `thisArg` to. Thus, we set it
// to an undefined, `void 0`.
if (languageVersion === ScriptTarget.ES5 &&
node.arguments &&
hasSpreadElement(node.arguments)) {

write("(");
emitCommaList(node.arguments);
write(")");
let target = emitCallTarget(node.expression);
write(".bind.apply(");
emit(target);
write(", [void 0].concat(");
emitListWithSpread(node.arguments, /*alwaysCopy*/true, /*multiline*/false, /*trailingComma*/false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you actually rename alwaysCopy to needsUniqueCopy and replace the relevant comments elsewhere? I realized that we don't actually always copy if the initial element is an array literal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I can rename it.

write(")))");
write("()");
}
else {
emit(node.expression);
if (node.arguments) {
write("(");
emitCommaList(node.arguments);
write(")");
}
}
}

Expand Down
59 changes: 0 additions & 59 deletions tests/baselines/reference/callWithSpread.errors.txt

This file was deleted.

5 changes: 0 additions & 5 deletions tests/baselines/reference/callWithSpread.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ class D extends C {
super.foo(1, 2, ...a);
}
}

// Only supported in when target is ES6
var c = new C(1, 2, ...a);


//// [callWithSpread.js]
Expand Down Expand Up @@ -112,6 +109,4 @@ var D = (function (_super) {
};
return D;
})(C);
// Only supported in when target is ES6
var c = new C(1, 2, ...a);
var _a, _b, _c;
159 changes: 159 additions & 0 deletions tests/baselines/reference/callWithSpread.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
=== tests/cases/conformance/expressions/functionCalls/callWithSpread.ts ===
interface X {
>X : Symbol(X, Decl(callWithSpread.ts, 0, 0))

foo(x: number, y: number, ...z: string[]);
>foo : Symbol(foo, Decl(callWithSpread.ts, 0, 13))
>x : Symbol(x, Decl(callWithSpread.ts, 1, 8))
>y : Symbol(y, Decl(callWithSpread.ts, 1, 18))
>z : Symbol(z, Decl(callWithSpread.ts, 1, 29))
}

function foo(x: number, y: number, ...z: string[]) {
>foo : Symbol(foo, Decl(callWithSpread.ts, 2, 1))
>x : Symbol(x, Decl(callWithSpread.ts, 4, 13))
>y : Symbol(y, Decl(callWithSpread.ts, 4, 23))
>z : Symbol(z, Decl(callWithSpread.ts, 4, 34))
}

var a: string[];
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

var z: number[];
>z : Symbol(z, Decl(callWithSpread.ts, 8, 3))

var obj: X;
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
>X : Symbol(X, Decl(callWithSpread.ts, 0, 0))

var xa: X[];
>xa : Symbol(xa, Decl(callWithSpread.ts, 10, 3))
>X : Symbol(X, Decl(callWithSpread.ts, 0, 0))

foo(1, 2, "abc");
>foo : Symbol(foo, Decl(callWithSpread.ts, 2, 1))

foo(1, 2, ...a);
>foo : Symbol(foo, Decl(callWithSpread.ts, 2, 1))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

foo(1, 2, ...a, "abc");
>foo : Symbol(foo, Decl(callWithSpread.ts, 2, 1))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

obj.foo(1, 2, "abc");
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))

obj.foo(1, 2, ...a);
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

obj.foo(1, 2, ...a, "abc");
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

(obj.foo)(1, 2, "abc");
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))

(obj.foo)(1, 2, ...a);
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

(obj.foo)(1, 2, ...a, "abc");
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

xa[1].foo(1, 2, "abc");
>xa[1].foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>xa : Symbol(xa, Decl(callWithSpread.ts, 10, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))

xa[1].foo(1, 2, ...a);
>xa[1].foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>xa : Symbol(xa, Decl(callWithSpread.ts, 10, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

xa[1].foo(1, 2, ...a, "abc");
>xa[1].foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>xa : Symbol(xa, Decl(callWithSpread.ts, 10, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))

(<Function>xa[1].foo)(...[1, 2, "abc"]);
>Function : Symbol(Function, Decl(lib.d.ts, 223, 38), Decl(lib.d.ts, 269, 11))
>xa[1].foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
>xa : Symbol(xa, Decl(callWithSpread.ts, 10, 3))
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))

class C {
>C : Symbol(C, Decl(callWithSpread.ts, 28, 40))

constructor(x: number, y: number, ...z: string[]) {
>x : Symbol(x, Decl(callWithSpread.ts, 31, 16))
>y : Symbol(y, Decl(callWithSpread.ts, 31, 26))
>z : Symbol(z, Decl(callWithSpread.ts, 31, 37))

this.foo(x, y);
>this.foo : Symbol(foo, Decl(callWithSpread.ts, 34, 5))
>this : Symbol(C, Decl(callWithSpread.ts, 28, 40))
>foo : Symbol(foo, Decl(callWithSpread.ts, 34, 5))
>x : Symbol(x, Decl(callWithSpread.ts, 31, 16))
>y : Symbol(y, Decl(callWithSpread.ts, 31, 26))

this.foo(x, y, ...z);
>this.foo : Symbol(foo, Decl(callWithSpread.ts, 34, 5))
>this : Symbol(C, Decl(callWithSpread.ts, 28, 40))
>foo : Symbol(foo, Decl(callWithSpread.ts, 34, 5))
>x : Symbol(x, Decl(callWithSpread.ts, 31, 16))
>y : Symbol(y, Decl(callWithSpread.ts, 31, 26))
>z : Symbol(z, Decl(callWithSpread.ts, 31, 37))
}
foo(x: number, y: number, ...z: string[]) {
>foo : Symbol(foo, Decl(callWithSpread.ts, 34, 5))
>x : Symbol(x, Decl(callWithSpread.ts, 35, 8))
>y : Symbol(y, Decl(callWithSpread.ts, 35, 18))
>z : Symbol(z, Decl(callWithSpread.ts, 35, 29))
}
}

class D extends C {
>D : Symbol(D, Decl(callWithSpread.ts, 37, 1))
>C : Symbol(C, Decl(callWithSpread.ts, 28, 40))

constructor() {
super(1, 2);
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))

super(1, 2, ...a);
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
}
foo() {
>foo : Symbol(foo, Decl(callWithSpread.ts, 43, 5))

super.foo(1, 2);
>super.foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))

super.foo(1, 2, ...a);
>super.foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
}
}

Loading