chore: Make field declarations explicit
This used to be valid code: ``` class Foo { constructor() { this.bar = ‘string’; } } ``` This will now fail since ‘bar’ is not explicitly defined as a field. We now have to write: ``` class Foo { bar:string; // << REQUIRED constructor() { this.bar = ‘string’; } } ```
This commit is contained in:
@ -6,6 +6,8 @@ class Inject {}
|
||||
class Bar {}
|
||||
|
||||
class Provide {
|
||||
token;
|
||||
|
||||
@CONST()
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
@ -13,6 +15,8 @@ class Provide {
|
||||
}
|
||||
|
||||
class AnnotateMe {
|
||||
maybe;
|
||||
|
||||
@CONST()
|
||||
constructor({maybe = 'default'} = {}) {
|
||||
this.maybe = maybe;
|
||||
|
@ -13,6 +13,8 @@ var max = (a, b) => {
|
||||
};
|
||||
|
||||
class LexicalThis {
|
||||
zero;
|
||||
|
||||
constructor() {
|
||||
this.zero = 0;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import {ddescribe, describe, it, expect} from 'test_lib/test_lib';
|
||||
import {CONST} from './fixtures/annotations';
|
||||
|
||||
// Constructor
|
||||
// Define fields
|
||||
class Foo {
|
||||
a;
|
||||
b;
|
||||
|
||||
constructor(a, b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
@ -15,6 +16,8 @@ class Foo {
|
||||
}
|
||||
|
||||
class SubFoo extends Foo {
|
||||
c;
|
||||
|
||||
constructor(a, b) {
|
||||
this.c = 3;
|
||||
super(a, b);
|
||||
@ -25,6 +28,8 @@ class SubFoo extends Foo {
|
||||
class ConstClass {}
|
||||
|
||||
class Const {
|
||||
a;
|
||||
|
||||
@CONST
|
||||
constructor(a:number) {
|
||||
this.a = a;
|
||||
@ -32,6 +37,8 @@ class Const {
|
||||
}
|
||||
|
||||
class SubConst extends Const {
|
||||
b;
|
||||
|
||||
@CONST
|
||||
constructor(a:number, b:number) {
|
||||
super(a);
|
||||
|
@ -5,6 +5,8 @@ function sum(a, b) {
|
||||
}
|
||||
|
||||
class ConstructorWithNamedParams {
|
||||
sum;
|
||||
|
||||
constructor(a, {b=1, c=2}) {
|
||||
this.sum = a + b + c;
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ class Bar {
|
||||
}
|
||||
|
||||
class Foo {
|
||||
a;
|
||||
b;
|
||||
|
||||
constructor(a: number, b: number) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
|
@ -25,7 +25,6 @@ import {
|
||||
} from 'traceur/src/syntax/trees/ParseTrees';
|
||||
|
||||
import {
|
||||
ClassFieldDeclaration,
|
||||
PropertyConstructorAssignment
|
||||
} from '../syntax/trees/ParseTrees';
|
||||
|
||||
@ -73,30 +72,6 @@ export class ClassTransformer extends ParseTreeTransformer {
|
||||
// Rename "constructor" to the class name.
|
||||
elementTree.name.literalToken.value = className;
|
||||
|
||||
// Collect all fields, defined in the constructor.
|
||||
elementTree.body.statements.forEach(function(statement) {
|
||||
var exp = statement.expression;
|
||||
if (exp &&
|
||||
exp.type === BINARY_EXPRESSION &&
|
||||
exp.operator.type === EQUAL &&
|
||||
exp.left.type === MEMBER_EXPRESSION &&
|
||||
exp.left.operand.type === THIS_EXPRESSION) {
|
||||
|
||||
var typeAnnotation;
|
||||
|
||||
if (exp.right.type === IDENTIFIER_EXPRESSION) {
|
||||
// `this.field = variable;`
|
||||
// we can infer the type of the field from the variable when it is a typed arg
|
||||
var varName = exp.right.getStringValue();
|
||||
typeAnnotation = argumentTypesMap[varName] || null;
|
||||
}
|
||||
|
||||
var fieldName = exp.left.memberName.value;
|
||||
var lvalue = new BindingIdentifier(tree.location, fieldName);
|
||||
fields.push(new ClassFieldDeclaration(tree.location, lvalue, typeAnnotation, isConst));
|
||||
}
|
||||
});
|
||||
|
||||
// Compute the initializer list
|
||||
var initializerList = [];
|
||||
var superCall = that._extractSuperCall(elementTree.body);
|
||||
@ -149,6 +124,11 @@ export class ClassTransformer extends ParseTreeTransformer {
|
||||
|
||||
// Add the field definitions to the beginning of the class.
|
||||
tree.elements = fields.concat(tree.elements);
|
||||
if (isConst) {
|
||||
tree.elements.forEach(function(element) {
|
||||
element.isFinal = true;
|
||||
});
|
||||
}
|
||||
|
||||
return super.transformClassDeclaration(tree);
|
||||
}
|
||||
|
@ -45,8 +45,11 @@ export class DartParseTreeWriter extends JavaScriptParseTreeWriter {
|
||||
}
|
||||
|
||||
if (tree.typeAnnotation === null) {
|
||||
this.write_(VAR);
|
||||
this.write_(tree.isFinal ? 'final' : VAR);
|
||||
} else {
|
||||
if (tree.isFinal) {
|
||||
this.write_('final');
|
||||
}
|
||||
this.writeType_(tree.typeAnnotation);
|
||||
}
|
||||
this.writeSpace_();
|
||||
@ -211,6 +214,7 @@ export class DartParseTreeWriter extends JavaScriptParseTreeWriter {
|
||||
case 'number': return 'num';
|
||||
case 'boolean': return 'bool';
|
||||
case 'string': return 'String';
|
||||
case 'any': return 'dynamic';
|
||||
case 'Promise': return 'Future';
|
||||
default: return typeName;
|
||||
}
|
||||
@ -244,25 +248,6 @@ export class DartParseTreeWriter extends JavaScriptParseTreeWriter {
|
||||
}
|
||||
}
|
||||
|
||||
visitClassFieldDeclaration(tree) {
|
||||
if (tree.isFinal) {
|
||||
// `final <type> name;` or `final name;` for untyped variable
|
||||
this.write_('final');
|
||||
this.writeSpace_();
|
||||
this.writeType_(tree.typeAnnotation);
|
||||
} else {
|
||||
// `<type> name;` or `var name;`
|
||||
if (tree.typeAnnotation) {
|
||||
this.writeType_(tree.typeAnnotation);
|
||||
} else {
|
||||
this.write_(VAR);
|
||||
this.writeSpace_();
|
||||
}
|
||||
}
|
||||
|
||||
this.write_(tree.lvalue.getStringValue());
|
||||
this.write_(SEMI_COLON);
|
||||
}
|
||||
|
||||
writeType_(typeAnnotation) {
|
||||
if (!typeAnnotation) {
|
||||
|
@ -4,36 +4,6 @@ import {PropertyMethodAssignment} from 'traceur/src/syntax/trees/ParseTrees';
|
||||
|
||||
import * as ParseTreeType from './ParseTreeType';
|
||||
|
||||
// Class field declaration
|
||||
export class ClassFieldDeclaration extends ParseTree {
|
||||
constructor(location, lvalue, typeAnnotation, isFinal) {
|
||||
this.location = location;
|
||||
this.lvalue = lvalue;
|
||||
this.typeAnnotation = typeAnnotation;
|
||||
this.isFinal = isFinal;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return CLASS_FIELD_DECLARATION;
|
||||
}
|
||||
|
||||
visit(visitor) {
|
||||
if (visitor.visitClassFieldDeclaration) {
|
||||
visitor.visitClassFieldDeclaration(this);
|
||||
}
|
||||
}
|
||||
|
||||
transform(transformer) {
|
||||
if (transformer.transformClassFieldDeclaration) {
|
||||
return transformer.transformClassFieldDeclaration(this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
var CLASS_FIELD_DECLARATION = ParseTreeType.CLASS_FIELD_DECLARATION;
|
||||
|
||||
// Class constructor
|
||||
export class PropertyConstructorAssignment extends PropertyMethodAssignment {
|
||||
/**
|
||||
|
Reference in New Issue
Block a user