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 22 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
2 changes: 2 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11866,6 +11866,8 @@ module ts {
var identifier = <Identifier>name;
if (contextNode && (contextNode.parserContextFlags & ParserContextFlags.StrictMode) && isEvalOrArgumentsIdentifier(identifier)) {
var nameText = declarationNameToString(identifier);

// Always report 'eval' and 'arguments' invalid usage in strict mode code regardless of parser diagnostics
Copy link
Contributor

Choose a reason for hiding this comment

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

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for catching this!. This is from my previous implementation in which I report a parsing error for using reserve keyword so I still want to report an error in this case. @CyrusNajmabadi corrects me about reserve word. So this change is no longer necessary

return grammarErrorOnNode(identifier, Diagnostics.Invalid_use_of_0_in_strict_mode, nameText);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ module ts {
Catch_clause_variable_cannot_have_an_initializer: { code: 1197, category: DiagnosticCategory.Error, key: "Catch clause variable cannot have an initializer." },
An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: { code: 1198, category: DiagnosticCategory.Error, key: "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive." },
Unterminated_Unicode_escape_sequence: { code: 1199, category: DiagnosticCategory.Error, key: "Unterminated Unicode escape sequence." },
A_computed_property_name_cannot_reference_a_static_property: { code: 1200, category: DiagnosticCategory.Error, key: "A computed property name cannot reference a static property" },
Copy link
Contributor

Choose a reason for hiding this comment

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

you do not need this any more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep. It will be removed in the upcoming commit

Copy link
Contributor

Choose a reason for hiding this comment

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

also the tests.

Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,10 @@
"category": "Error",
"code": 1199
},
"A computed property name cannot reference a static property": {
"category": "Error",
"code": 1200
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300
Expand Down
303 changes: 207 additions & 96 deletions src/compiler/emitter.ts

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4517,6 +4517,12 @@ module ts {
}

function parseClassDeclaration(fullStart: number, modifiers: ModifiersArray): ClassDeclaration {
// 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);
Expand All @@ -4537,7 +4543,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
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