Skip to content

Class emit for ES6 #2333

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

Merged
merged 25 commits into from
Mar 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
033a83d
Basic emit for class constructor without static property assignment
Mar 10, 2015
d3205ef
Remove redundant sourcemap span and comment. Differentiate between em…
Mar 10, 2015
8576282
Emit non-getter/setter member function
Mar 10, 2015
1b84f1d
emit get/set member function
Mar 11, 2015
890aa4a
test cases for constructor overload, non-static property assignment, …
Mar 11, 2015
da12d46
Add tests for extension, type arguments, overload
Mar 11, 2015
a0a506b
Emit class declaration with static property assignment
Mar 11, 2015
7ee587c
Emit class with export and export default
Mar 11, 2015
5683960
Disallow refering to static property in computed property name
Mar 12, 2015
0672923
Parse classDeclaration in strict mode code for ES6
Mar 12, 2015
800c523
Clean up redundant tests
Mar 12, 2015
af05afd
Emit Super as super
Mar 12, 2015
13e55ae
Address code review
Mar 14, 2015
2a07d3f
Address code review: do not emit default constructor
Mar 15, 2015
9bf5a11
Update baselines
Mar 15, 2015
c70385c
Update baselines
Mar 16, 2015
3bb4b50
Update baselines for symbol
Mar 16, 2015
0eeb7ce
Update baselines
Mar 16, 2015
2c7ea7f
Update Baselines
Mar 16, 2015
e573461
Address code review. Use-before-def check will be added to separate w…
Mar 16, 2015
88933d5
Address code review
Mar 16, 2015
91c5bae
Address code review
Mar 16, 2015
c51983d
Address code review
Mar 16, 2015
513b45d
Merge branch 'master' into emitClass
Mar 16, 2015
9b3fccd
Address code review; Use for..of and use if-statement
Mar 16, 2015
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
304 changes: 207 additions & 97 deletions src/compiler/emitter.ts

Large diffs are not rendered by default.

31 changes: 20 additions & 11 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ module ts {
// change the token touching it, we actually need to look back *at least* one token so
// that the prior token sees that change.
let maxLookahead = 1;

let start = changeRange.span.start;

// the first iteration aligns us with the change start. subsequent iteration move us to
Expand Down Expand Up @@ -831,7 +831,7 @@ module ts {
// will immediately bail out of walking any subtrees when we can see that their parents
// are already correct.
let result = parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true)

return result;
}

Expand Down Expand Up @@ -1986,7 +1986,7 @@ module ts {
//
// let v = new List < A, B >()
//
// then we have a problem. "v = new List<A" doesn't intersect the change range, so we
// then we have a problem. "v = new List<A" doesn't intersect the change range, so we
// start reparsing at "B" and we completely fail to handle this properly.
//
// In order to prevent this, we do not allow a variable declarator to be reused if it
Expand Down Expand Up @@ -3008,9 +3008,9 @@ module ts {
Debug.assert(token === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");

let node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction, identifier.pos);

let parameter = <ParameterDeclaration>createNode(SyntaxKind.Parameter, identifier.pos);
parameter.name = identifier;
parameter.name = identifier;
finishNode(parameter);

node.parameters = <NodeArray<ParameterDeclaration>>[parameter];
Expand Down Expand Up @@ -3140,8 +3140,8 @@ module ts {

function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction {
let node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction);
// Arrow functions are never generators.
//
// Arrow functions are never generators.
//
// If we're speculatively parsing a signature for a parenthesized arrow function, then
// we have to have a complete parameter list. Otherwise we might see something like
// a => (b => c)
Expand Down Expand Up @@ -3206,7 +3206,7 @@ module ts {
// Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
// we do not that for the 'whenFalse' part.
let node = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression, leftOperand.pos);
node.condition = leftOperand;
node.condition = leftOperand;
node.questionToken = questionToken;
node.whenTrue = allowInAnd(parseAssignmentExpressionOrHigher);
node.colonToken = parseExpectedToken(SyntaxKind.ColonToken, /*reportAtCurrentPosition:*/ false,
Expand Down Expand Up @@ -4526,7 +4526,13 @@ module ts {
}

function parseClassDeclaration(fullStart: number, modifiers: ModifiersArray): ClassDeclaration {
let node = <ClassDeclaration>createNode(SyntaxKind.ClassDeclaration, fullStart);
// In ES6 specification, All parts of a ClassDeclaration or a ClassExpression are strict mode code
let savedStrictModeContext = inStrictModeContext();
if (languageVersion >= ScriptTarget.ES6) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would always enter strict mode once we're in a class. If that's ES semantics, then that's what we should follow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That will be a breaking change. I have tried running on that mode on RWC and our compiler. Both do have non-strict-mode code in classDeclaration. So, I want to push this version in first. Then, decide if we want to extend this to all classDeclaration later.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am surprised that stuff broke. Do you recall what the particular strict mode errors were?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, can we bring this to the design meeting. Technically those classes are broken, and won't work in the future. Do we want to continue 'pretending' they're ok, or should we be up frong about breaking them. Can you also possibly email us the examples of where this breaks?

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, using arguments as a name of parameters. I will send email of what is broken

setStrictModeContext(true);
}

var node = <ClassDeclaration>createNode(SyntaxKind.ClassDeclaration, fullStart);
setModifiers(node, modifiers);
parseExpected(SyntaxKind.ClassKeyword);
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
Expand All @@ -4546,7 +4552,10 @@ module ts {
else {
node.members = createMissingList<ClassElement>();
}
return finishNode(node);

var finishedNode = finishNode(node);
setStrictModeContext(savedStrictModeContext);
return finishedNode;
}

function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
Expand Down Expand Up @@ -4774,7 +4783,7 @@ module ts {
// walker.
let result = parseExpression();
// Ensure the string being required is in our 'identifier' table. This will ensure
// that features like 'find refs' will look inside this file when search for its name.
// that features like 'find refs' will look inside this file when search for its name.
if (result.kind === SyntaxKind.StringLiteral) {
internIdentifier((<LiteralExpression>result).text);
}
Expand Down
37 changes: 14 additions & 23 deletions tests/baselines/reference/callWithSpreadES6.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ var c = new C(1, 2, ...a);


//// [callWithSpreadES6.js]
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
function foo(x, y, ...z) {
}
var a;
Expand All @@ -84,26 +78,23 @@ xa[1].foo(...[
2,
"abc"
]);
var C = (function () {
function C(x, y, ...z) {
class C {
constructor(x, y, ...z) {
this.foo(x, y);
this.foo(x, y, ...z);
}
C.prototype.foo = function (x, y, ...z) {
};
return C;
})();
var D = (function (_super) {
__extends(D, _super);
function D() {
_super.call(this, 1, 2);
_super.call(this, 1, 2, ...a);
foo(x, y, ...z) {
}
D.prototype.foo = function () {
_super.prototype.foo.call(this, 1, 2);
_super.prototype.foo.call(this, 1, 2, ...a);
};
return D;
})(C);
}
class D extends C {
constructor() {
super(1, 2);
super(1, 2, ...a);
}
foo() {
super.foo(1, 2);
super.foo(1, 2, ...a);
}
}
// Only supported in when target is ES6
var c = new C(1, 2, ...a);
9 changes: 4 additions & 5 deletions tests/baselines/reference/computedPropertyNames12_ES6.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ class C {
var s;
var n;
var a;
var C = (function () {
function C() {
class C {
constructor() {
this[n] = n;
this[s + n] = 2;
this[`hello bye`] = 0;
}
C[`hello ${a} bye`] = 0;
return C;
})();
}
C[`hello ${a} bye`] = 0;
51 changes: 24 additions & 27 deletions tests/baselines/reference/computedPropertyNames13_ES6.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,27 @@ class C {
var s;
var n;
var a;
var C = (function () {
function C() {
}
C.prototype[s] = function () {
};
C.prototype[n] = function () {
};
C[s + s] = function () {
};
C.prototype[s + n] = function () {
};
C.prototype[+s] = function () {
};
C[""] = function () {
};
C.prototype[0] = function () {
};
C.prototype[a] = function () {
};
C[true] = function () {
};
C.prototype[`hello bye`] = function () {
};
C[`hello ${a} bye`] = function () {
};
return C;
})();
class C {
[s]() {
}
[n]() {
}
static [s + s]() {
}
[s + n]() {
}
[+s]() {
}
static [""]() {
}
[0]() {
}
[a]() {
}
static [true]() {
}
[`hello bye`]() {
}
static [`hello ${a} bye`]() {
}
}
29 changes: 13 additions & 16 deletions tests/baselines/reference/computedPropertyNames14_ES6.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,17 @@ class C {

//// [computedPropertyNames14_ES6.js]
var b;
var C = (function () {
function C() {
class C {
[b]() {
}
C.prototype[b] = function () {
};
C[true] = function () {
};
C.prototype[[]] = function () {
};
C[{}] = function () {
};
C.prototype[undefined] = function () {
};
C[null] = function () {
};
return C;
})();
static [true]() {
}
[[]]() {
}
static [{}]() {
}
[undefined]() {
}
static [null]() {
}
}
17 changes: 7 additions & 10 deletions tests/baselines/reference/computedPropertyNames15_ES6.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@ class C {
var p1;
var p2;
var p3;
var C = (function () {
function C() {
class C {
[p1]() {
}
C.prototype[p1] = function () {
};
C.prototype[p2] = function () {
};
C.prototype[p3] = function () {
};
return C;
})();
[p2]() {
}
[p3]() {
}
}
105 changes: 29 additions & 76 deletions tests/baselines/reference/computedPropertyNames16_ES6.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,80 +20,33 @@ class C {
var s;
var n;
var a;
var C = (function () {
function C() {
class C {
get [s]() {
return 0;
}
Object.defineProperty(C.prototype, s, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, n, {
set: function (v) {
},
enumerable: true,
configurable: true
});
Object.defineProperty(C, s + s, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, s + n, {
set: function (v) {
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, +s, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(C, "", {
set: function (v) {
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, 0, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, a, {
set: function (v) {
},
enumerable: true,
configurable: true
});
Object.defineProperty(C, true, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, `hello bye`, {
set: function (v) {
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, `hello ${a} bye`, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
return C;
})();
set [n](v) {
}
static get [s + s]() {
return 0;
}
set [s + n](v) {
}
get [+s]() {
return 0;
}
static set [""](v) {
}
get [0]() {
return 0;
}
set [a](v) {
}
static get [true]() {
return 0;
}
set [`hello bye`](v) {
}
get [`hello ${a} bye`]() {
return 0;
}
}
Loading