forked from angular/angular
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(transpiler): split the monolithic dart transformer
fixes angular#24 The new architecture conforms with the Traceur architecture.
- Loading branch information
Showing
7 changed files
with
215 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import {ParseTreeTransformer} from 'traceur/src/codegeneration/ParseTreeTransformer'; | ||
|
||
import { | ||
PROPERTY_METHOD_ASSIGNMENT, | ||
MEMBER_EXPRESSION, | ||
THIS_EXPRESSION, | ||
BINARY_EXPRESSION | ||
} from 'traceur/src/syntax/trees/ParseTreeType'; | ||
|
||
import {CONSTRUCTOR} from 'traceur/src/syntax/PredefinedName'; | ||
|
||
import {propName} from 'traceur/src/staticsemantics/PropName'; | ||
|
||
import {ClassFieldParseTree} from '../ast/class_field'; | ||
|
||
/** | ||
* Transforms class declaration: | ||
* - rename constructor (name of the class - default Dart constructor) | ||
* | ||
*/ | ||
|
||
export class ClassTransformer extends ParseTreeTransformer { | ||
/** | ||
* @param {ClassDeclaration} tree | ||
* @returns {ParseTree} | ||
*/ | ||
transformClassDeclaration(tree) { | ||
var className = tree.name.identifierToken.toString(); | ||
var argumentTypesMap = {}; | ||
var fields = []; | ||
|
||
tree.elements.forEach(function(elementTree) { | ||
if (elementTree.type === PROPERTY_METHOD_ASSIGNMENT && | ||
!elementTree.isStatic && | ||
propName(elementTree) === CONSTRUCTOR) { | ||
|
||
// Store constructor argument types, | ||
// so that we can use them to set the types of simple-assigned fields. | ||
elementTree.parameterList.parameters.forEach(function(p) { | ||
var binding = p.parameter.binding; | ||
if (binding.identifierToken) { | ||
argumentTypesMap[binding.identifierToken.value] = p.typeAnnotation; | ||
} | ||
}); | ||
|
||
// Rename "constructor" to the class name. | ||
elementTree.name.literalToken.value = className; | ||
|
||
// Collect all fields, defined in the constructor. | ||
elementTree.body.statements.forEach(function(statement) { | ||
if (statement.expression.type === BINARY_EXPRESSION && | ||
statement.expression.operator.type === '=' && | ||
statement.expression.left.type === MEMBER_EXPRESSION && | ||
statement.expression.left.operand.type === THIS_EXPRESSION) { | ||
|
||
var typeAnnotation = argumentTypesMap[statement.expression.left.memberName.value] || null; | ||
fields.push(new ClassFieldParseTree(tree.location, statement.expression.left.memberName, typeAnnotation)); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
// Add the field definitions to the beginning of the class. | ||
tree.elements = fields.concat(tree.elements); | ||
|
||
return super(tree); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import {MultiTransformer} from 'traceur/src/codegeneration/MultiTransformer'; | ||
import {UniqueIdentifierGenerator} from 'traceur/src/codegeneration/UniqueIdentifierGenerator'; | ||
import {options} from 'traceur/src/Options'; | ||
|
||
import {ClassTransformer} from './ClassTransformer'; | ||
import {InstanceOfTransformer} from './InstanceOfTransformer'; | ||
import {MultiVarTransformer} from './MultiVarTransformer'; | ||
import {StrictEqualityTransformer} from './StrictEqualityTransformer'; | ||
|
||
/** | ||
* Transforms ES6 + annotations to Dart code. | ||
*/ | ||
export class DartTransformer extends MultiTransformer { | ||
constructor(reporter, idGenerator = new UniqueIdentifierGenerator()) { | ||
super(reporter, options.validate); | ||
|
||
var append = (transformer) => { | ||
this.append((tree) => { | ||
return new transformer(idGenerator, reporter).transformAny(tree); | ||
}); | ||
}; | ||
|
||
append(MultiVarTransformer); | ||
append(InstanceOfTransformer); | ||
append(StrictEqualityTransformer); | ||
append(ClassTransformer); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
tools/transpiler/src/codegeneration/InstanceOfTransformer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {INSTANCEOF} from 'traceur/src/syntax/TokenType'; | ||
|
||
import {ParseTreeTransformer} from 'traceur/src/codegeneration/ParseTreeTransformer'; | ||
|
||
/** | ||
* Transforms `a instanceof b` to `a is b`, | ||
*/ | ||
export class InstanceOfTransformer extends ParseTreeTransformer { | ||
/** | ||
* @param {BinaryExpression} tree | ||
* @return {ParseTree} | ||
*/ | ||
transformBinaryExpression(tree) { | ||
tree.left = this.transformAny(tree.left); | ||
tree.right = this.transformAny(tree.right); | ||
|
||
if (tree.operator.type === 'instanceof') { | ||
// TODO(vojta): do this in a cleaner way. | ||
tree.operator.type = 'is'; | ||
return tree; | ||
} | ||
|
||
return tree; | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
tools/transpiler/src/codegeneration/MultiVarTransformer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import {VariableStatement, VariableDeclarationList} from 'traceur/src/syntax/trees/ParseTrees'; | ||
|
||
import {ParseTreeTransformer} from 'traceur/src/codegeneration/ParseTreeTransformer'; | ||
|
||
/** | ||
* Transforms `var a, b;` to `var a; var b;` | ||
*/ | ||
export class MultiVarTransformer extends ParseTreeTransformer { | ||
// Individual item transformer can return an array of items. | ||
// This is used in `transformVariableStatement`. | ||
// Otherwise this is copy/pasted from `ParseTreeTransformer`. | ||
transformList(list) { | ||
var transformedList = []; | ||
var transformedItem = null; | ||
|
||
for (var i = 0, ii = list.length; i < ii; i++) { | ||
transformedItem = this.transformAny(list[i]); | ||
if (Array.isArray(transformedItem)) { | ||
transformedList = transformedList.concat(transformedItem); | ||
} else { | ||
transformedList.push(transformedItem); | ||
} | ||
} | ||
|
||
return transformedList; | ||
} | ||
|
||
/** | ||
* @param {VariableStatement} tree | ||
* @returns {ParseTree} | ||
*/ | ||
transformVariableStatement(tree) { | ||
var declarations = tree.declarations.declarations; | ||
|
||
if (declarations.length === 1 || declarations.length === 0) { | ||
return tree; | ||
} | ||
|
||
// Multiple var declaration, we will split it into multiple statements. | ||
// TODO(vojta): We can leave the multi-definition as long as they are all the same type/untyped. | ||
return declarations.map(function(declaration) { | ||
return new VariableStatement(tree.location, new VariableDeclarationList(tree.location, | ||
tree.declarations.declarationType, [declaration])); | ||
}); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
tools/transpiler/src/codegeneration/StrictEqualityTransformer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { | ||
createCallExpression, | ||
createIdentifierExpression, | ||
createArgumentList} from 'traceur/src/codegeneration/ParseTreeFactory'; | ||
|
||
import { | ||
EQUAL_EQUAL_EQUAL, | ||
NOT_EQUAL_EQUAL | ||
} from 'traceur/src/syntax/TokenType'; | ||
|
||
import {ParseTreeTransformer} from 'traceur/src/codegeneration/ParseTreeTransformer'; | ||
|
||
/** | ||
* Transforms: | ||
* - `a === b` to `indentical(a, b)`, | ||
* - `a !== b` to `!identical(a, b)` | ||
*/ | ||
export class StrictEqualityTransformer extends ParseTreeTransformer { | ||
/** | ||
* @param {BinaryExpression} tree | ||
* @return {ParseTree} | ||
*/ | ||
transformBinaryExpression(tree) { | ||
tree.left = this.transformAny(tree.left); | ||
tree.right = this.transformAny(tree.right); | ||
|
||
if (tree.operator.type === EQUAL_EQUAL_EQUAL) { | ||
// `a === b` -> `identical(a, b)` | ||
return createCallExpression(createIdentifierExpression('identical'), | ||
createArgumentList([tree.left, tree.right])); | ||
} | ||
|
||
if (tree.operator.type === NOT_EQUAL_EQUAL) { | ||
// `a !== b` -> `!identical(a, b)` | ||
// TODO(vojta): do this in a cleaner way. | ||
return createCallExpression(createIdentifierExpression('!identical'), | ||
createArgumentList([tree.left, tree.right])); | ||
} | ||
|
||
return tree; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.