| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart_tree; | 5 library dart_tree; |
| 6 | 6 |
| 7 import '../dart2jslib.dart' as dart2js; | 7 import '../dart2jslib.dart' as dart2js; |
| 8 import '../dart_types.dart'; | 8 import '../dart_types.dart'; |
| 9 import '../util/util.dart'; | 9 import '../util/util.dart'; |
| 10 import '../elements/elements.dart' | 10 import '../elements/elements.dart' |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 // Uses of IR definitions are replaced with Tree variables. This is the | 210 // Uses of IR definitions are replaced with Tree variables. This is the |
| 211 // mapping from definitions to variables. | 211 // mapping from definitions to variables. |
| 212 final Map<ir.Definition, Variable> variables = {}; | 212 final Map<ir.Definition, Variable> variables = {}; |
| 213 | 213 |
| 214 FunctionDefinition function; | 214 FunctionDefinition function; |
| 215 ir.Continuation returnContinuation; | 215 ir.Continuation returnContinuation; |
| 216 | 216 |
| 217 Builder(this.compiler); | 217 Builder(this.compiler); |
| 218 | 218 |
| 219 FunctionDefinition build(ir.FunctionDefinition node) { | 219 FunctionDefinition build(ir.FunctionDefinition node) { |
| 220 node.accept(this); | 220 visit(node); |
| 221 return function; | 221 return function; |
| 222 } | 222 } |
| 223 | 223 |
| 224 List<Expression> translateArguments(List<ir.Reference> args) { | 224 List<Expression> translateArguments(List<ir.Reference> args) { |
| 225 return new List.generate(args.length, | 225 return new List.generate(args.length, |
| 226 (int index) => variables[args[index].definition]); | 226 (int index) => variables[args[index].definition]); |
| 227 } | 227 } |
| 228 | 228 |
| 229 Expression visitFunctionDefinition(ir.FunctionDefinition node) { | 229 Expression visitFunctionDefinition(ir.FunctionDefinition node) { |
| 230 returnContinuation = node.returnContinuation; | 230 returnContinuation = node.returnContinuation; |
| 231 List<Variable> parameters = <Variable>[]; | 231 List<Variable> parameters = <Variable>[]; |
| 232 for (ir.Parameter p in node.parameters) { | 232 for (ir.Parameter p in node.parameters) { |
| 233 Variable parameter = new Variable(p.element); | 233 Variable parameter = new Variable(p.element); |
| 234 parameters.add(parameter); | 234 parameters.add(parameter); |
| 235 variables[p] = parameter; | 235 variables[p] = parameter; |
| 236 } | 236 } |
| 237 function = new FunctionDefinition(parameters, node.body.accept(this)); | 237 function = new FunctionDefinition(parameters, visit(node.body)); |
| 238 return null; | 238 return null; |
| 239 } | 239 } |
| 240 | 240 |
| 241 Expression visitLetPrim(ir.LetPrim node) { | 241 Expression visitLetPrim(ir.LetPrim node) { |
| 242 // LetPrim is translated to LetVal. | 242 // LetPrim is translated to LetVal. |
| 243 Expression definition = node.primitive.accept(this); | 243 Expression definition = visit(node.primitive); |
| 244 if (node.primitive.hasAtLeastOneUse) { | 244 if (node.primitive.hasAtLeastOneUse) { |
| 245 Variable variable = new Variable(null); | 245 Variable variable = new Variable(null); |
| 246 variables[node.primitive] = variable; | 246 variables[node.primitive] = variable; |
| 247 return new LetVal(node.primitive.hasExactlyOneUse, variable, | 247 return new LetVal(node.primitive.hasExactlyOneUse, variable, |
| 248 definition, node.body.accept(this)); | 248 definition, visit(node.body)); |
| 249 } else if (node.primitive is ir.Constant) { |
| 250 // TODO(kmillikin): Implement more systematic treatment of pure CPS |
| 251 // values (e.g., as part of a shrinking reductions pass). |
| 252 return visit(node.body); |
| 249 } else { | 253 } else { |
| 250 return new Sequence([definition, node.body.accept(this)]); | 254 return new Sequence([definition, visit(node.body)]); |
| 251 } | 255 } |
| 252 } | 256 } |
| 253 | 257 |
| 254 Expression visitLetCont(ir.LetCont node) { | 258 Expression visitLetCont(ir.LetCont node) { |
| 255 // TODO(kmillikin): Allow continuations to have multiple uses. This could | 259 // TODO(kmillikin): Allow continuations to have multiple uses. This could |
| 256 // arise due to the representation of local control flow or due to | 260 // arise due to the representation of local control flow or due to |
| 257 // optimization. | 261 // optimization. |
| 258 assert(node.continuation.hasAtMostOneUse); | 262 assert(node.continuation.hasAtMostOneUse); |
| 259 return node.body.accept(this); | 263 return visit(node.body); |
| 260 } | 264 } |
| 261 | 265 |
| 262 Expression visitInvokeStatic(ir.InvokeStatic node) { | 266 Expression visitInvokeStatic(ir.InvokeStatic node) { |
| 263 // Calls are translated to direct style. | 267 // Calls are translated to direct style. |
| 264 List<Expression> arguments = translateArguments(node.arguments); | 268 List<Expression> arguments = translateArguments(node.arguments); |
| 265 Expression invoke = new InvokeStatic(node.target, arguments); | 269 Expression invoke = new InvokeStatic(node.target, arguments); |
| 266 ir.Continuation cont = node.continuation.definition; | 270 ir.Continuation cont = node.continuation.definition; |
| 267 if (cont == returnContinuation) { | 271 if (cont == returnContinuation) { |
| 268 return new Return(invoke); | 272 return new Return(invoke); |
| 269 } else { | 273 } else { |
| 270 assert(cont.hasExactlyOneUse); | 274 assert(cont.hasExactlyOneUse); |
| 271 if (cont.parameter.hasAtLeastOneUse) { | 275 if (cont.parameter.hasAtLeastOneUse) { |
| 272 Variable variable = new Variable(null); | 276 Variable variable = new Variable(null); |
| 273 variables[cont.parameter] = variable; | 277 variables[cont.parameter] = variable; |
| 274 return new LetVal(cont.parameter.hasExactlyOneUse, variable, | 278 return new LetVal(cont.parameter.hasExactlyOneUse, variable, |
| 275 invoke, cont.body.accept(this)); | 279 invoke, visit(cont.body)); |
| 276 } else { | 280 } else { |
| 277 return new Sequence([invoke, cont.body.accept(this)]); | 281 return new Sequence([invoke, visit(cont.body)]); |
| 278 } | 282 } |
| 279 } | 283 } |
| 280 } | 284 } |
| 281 | 285 |
| 282 Expression visitInvokeContinuation(ir.InvokeContinuation node) { | 286 Expression visitInvokeContinuation(ir.InvokeContinuation node) { |
| 283 // TODO(kmillikin): Support non-return continuations. These could arise | 287 // TODO(kmillikin): Support non-return continuations. These could arise |
| 284 // due to local control flow or due to inlining or other optimization. | 288 // due to local control flow or due to inlining or other optimization. |
| 285 assert(node.continuation.definition == returnContinuation); | 289 assert(node.continuation.definition == returnContinuation); |
| 286 return new Return(variables[node.argument.definition]); | 290 return new Return(variables[node.argument.definition]); |
| 287 } | 291 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 * See [visitVariable] for the implementation of the heuristic for propagating | 328 * See [visitVariable] for the implementation of the heuristic for propagating |
| 325 * a definition. | 329 * a definition. |
| 326 */ | 330 */ |
| 327 class Unnamer extends Visitor<Expression> { | 331 class Unnamer extends Visitor<Expression> { |
| 328 // The binding environment. The rightmost element of the list is the nearest | 332 // The binding environment. The rightmost element of the list is the nearest |
| 329 // enclosing binding. | 333 // enclosing binding. |
| 330 List<LetVal> environment; | 334 List<LetVal> environment; |
| 331 | 335 |
| 332 void unname(FunctionDefinition definition) { | 336 void unname(FunctionDefinition definition) { |
| 333 environment = <LetVal>[]; | 337 environment = <LetVal>[]; |
| 334 definition.body = definition.body.accept(this); | 338 definition.body = visit(definition.body); |
| 335 | 339 |
| 336 // TODO(kmillikin): Allow definitions that are not propagated. Here, | 340 // TODO(kmillikin): Allow definitions that are not propagated. Here, |
| 337 // this means rebuilding the binding with a recursively unnamed definition, | 341 // this means rebuilding the binding with a recursively unnamed definition, |
| 338 // or else introducing a variable definition and an assignment. | 342 // or else introducing a variable definition and an assignment. |
| 339 assert(environment.isEmpty); | 343 assert(environment.isEmpty); |
| 340 } | 344 } |
| 341 | 345 |
| 342 Expression visitVariable(Variable node) { | 346 Expression visitVariable(Variable node) { |
| 343 // Propagate a variable's definition to its use site if: | 347 // Propagate a variable's definition to its use site if: |
| 344 // 1. It has a single use, to avoid code growth and potential duplication | 348 // 1. It has a single use, to avoid code growth and potential duplication |
| 345 // of side effects, AND | 349 // of side effects, AND |
| 346 // 2a. It is pure (i.e., does not have side effects that prevent it from | 350 // 2a. It is pure (i.e., does not have side effects that prevent it from |
| 347 // being moved), OR | 351 // being moved), OR |
| 348 // 2b. There are only pure expressions between the definition and use. | 352 // 2b. There are only pure expressions between the definition and use. |
| 349 | 353 |
| 350 // TODO(kmillikin): It's not always beneficial to propagate pure | 354 // TODO(kmillikin): It's not always beneficial to propagate pure |
| 351 // definitions---it can prevent propagation of their inputs. Implement | 355 // definitions---it can prevent propagation of their inputs. Implement |
| 352 // a heuristic to avoid this. | 356 // a heuristic to avoid this. |
| 353 | 357 |
| 354 // TODO(kmillikin): Replace linear search with something faster in | 358 // TODO(kmillikin): Replace linear search with something faster in |
| 355 // practice. | 359 // practice. |
| 356 bool seenImpure = false; | 360 bool seenImpure = false; |
| 357 for (int i = environment.length - 1; i >= 0; --i) { | 361 for (int i = environment.length - 1; i >= 0; --i) { |
| 358 if (environment[i].variable == node) { | 362 if (environment[i].variable == node) { |
| 359 if ((!seenImpure || environment[i].definition.isPure) | 363 if ((!seenImpure || environment[i].definition.isPure) |
| 360 && environment[i].hasExactlyOneUse) { | 364 && environment[i].hasExactlyOneUse) { |
| 361 // Use the definition if it is pure or if it is the first impure | 365 // Use the definition if it is pure or if it is the first impure |
| 362 // definition (i.e., propagating past only pure expressions). | 366 // definition (i.e., propagating past only pure expressions). |
| 363 return environment.removeAt(i).definition.accept(this); | 367 return visit(environment.removeAt(i).definition); |
| 364 } | 368 } |
| 365 break; | 369 break; |
| 366 } else if (!environment[i].definition.isPure) { | 370 } else if (!environment[i].definition.isPure) { |
| 367 // Once the first impure definition is seen, impure definitions should | 371 // Once the first impure definition is seen, impure definitions should |
| 368 // no longer be propagated. Continue searching for a pure definition. | 372 // no longer be propagated. Continue searching for a pure definition. |
| 369 seenImpure = true; | 373 seenImpure = true; |
| 370 } | 374 } |
| 371 } | 375 } |
| 372 // If the definition could not be propagated, leave the variable use. | 376 // If the definition could not be propagated, leave the variable use. |
| 373 return node; | 377 return node; |
| 374 } | 378 } |
| 375 | 379 |
| 376 Expression visitSequence(Sequence node) { | 380 Expression visitSequence(Sequence node) { |
| 377 for (int i = 0; i < node.expressions.length; ++i) { | 381 for (int i = 0; i < node.expressions.length; ++i) { |
| 378 node.expressions[i] = node.expressions[i].accept(this); | 382 node.expressions[i] = visit(node.expressions[i]); |
| 379 } | 383 } |
| 380 return node; | 384 return node; |
| 381 } | 385 } |
| 382 | 386 |
| 383 Expression visitLetVal(LetVal node) { | 387 Expression visitLetVal(LetVal node) { |
| 384 environment.add(node); | 388 environment.add(node); |
| 385 Expression body = node.body.accept(this); | 389 Expression body = visit(node.body); |
| 386 | 390 |
| 387 if (!environment.isEmpty && environment.last == node) { | 391 if (!environment.isEmpty && environment.last == node) { |
| 388 // The definition could not be propagated. Residualize the let binding. | 392 // The definition could not be propagated. Residualize the let binding. |
| 389 node.body = body; | 393 node.body = body; |
| 390 environment.removeLast(); | 394 environment.removeLast(); |
| 391 node.definition = node.definition.accept(this); | 395 node.definition = visit(node.definition); |
| 392 return node; | 396 return node; |
| 393 } | 397 } |
| 394 assert(!environment.contains(node)); | 398 assert(!environment.contains(node)); |
| 395 return body; | 399 return body; |
| 396 } | 400 } |
| 397 | 401 |
| 398 Expression visitInvokeStatic(InvokeStatic node) { | 402 Expression visitInvokeStatic(InvokeStatic node) { |
| 399 // Process arguments right-to-left, the opposite of evaluation order. | 403 // Process arguments right-to-left, the opposite of evaluation order. |
| 400 for (int i = node.arguments.length - 1; i >= 0; --i) { | 404 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 401 node.arguments[i] = node.arguments[i].accept(this); | 405 node.arguments[i] = visit(node.arguments[i]); |
| 402 } | 406 } |
| 403 return node; | 407 return node; |
| 404 } | 408 } |
| 405 | 409 |
| 406 Expression visitReturn(Return node) { | 410 Expression visitReturn(Return node) { |
| 407 node.value = node.value.accept(this); | 411 node.value = visit(node.value); |
| 408 return node; | 412 return node; |
| 409 } | 413 } |
| 410 | 414 |
| 411 visitConstant(Constant node) { | 415 visitConstant(Constant node) { |
| 412 return node; | 416 return node; |
| 413 } | 417 } |
| 414 } | 418 } |
| 415 | 419 |
| 416 /** | 420 /** |
| 417 * [Emitter] translates Tree to a Dart AST. | 421 * [Emitter] translates Tree to a Dart AST. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 // Reset the variable index. This function is not reentrant. | 487 // Reset the variable index. This function is not reentrant. |
| 484 Variable.counter = 0; | 488 Variable.counter = 0; |
| 485 this.treeElements = treeElements; | 489 this.treeElements = treeElements; |
| 486 ast.Identifier name = makeIdentifier(element.name); | 490 ast.Identifier name = makeIdentifier(element.name); |
| 487 | 491 |
| 488 TypeEmitter typeEmitter = new TypeEmitter(); | 492 TypeEmitter typeEmitter = new TypeEmitter(); |
| 489 FunctionSignature signature = element.functionSignature; | 493 FunctionSignature signature = element.functionSignature; |
| 490 ast.TypeAnnotation returnType; | 494 ast.TypeAnnotation returnType; |
| 491 if (!signature.type.returnType.isDynamic) { | 495 if (!signature.type.returnType.isDynamic) { |
| 492 returnType = | 496 returnType = |
| 493 signature.type.returnType.accept(typeEmitter, treeElements); | 497 typeEmitter.visitType(signature.type.returnType, treeElements); |
| 494 } | 498 } |
| 495 | 499 |
| 496 List<ast.VariableDefinitions> parameterList = <ast.VariableDefinitions>[]; | 500 List<ast.VariableDefinitions> parameterList = <ast.VariableDefinitions>[]; |
| 497 for (Variable parameter in definition.parameters) { | 501 for (Variable parameter in definition.parameters) { |
| 498 ParameterElement element = parameter.element; | 502 ParameterElement element = parameter.element; |
| 499 parameter.assignIdentifier(); | 503 parameter.assignIdentifier(); |
| 500 ast.TypeAnnotation type; | 504 ast.TypeAnnotation type; |
| 501 if (!element.type.isDynamic) { | 505 if (!element.type.isDynamic) { |
| 502 type = element.type.accept(typeEmitter, treeElements); | 506 type = typeEmitter.visitType(element.type, treeElements); |
| 503 } | 507 } |
| 504 parameterList.add(new ast.VariableDefinitions( | 508 parameterList.add(new ast.VariableDefinitions( |
| 505 type, | 509 type, |
| 506 ast.Modifiers.EMPTY, | 510 ast.Modifiers.EMPTY, |
| 507 new ast.NodeList.singleton(parameter.identifier))); | 511 new ast.NodeList.singleton(parameter.identifier))); |
| 508 } | 512 } |
| 509 ast.NodeList parameters = | 513 ast.NodeList parameters = |
| 510 new ast.NodeList(openParen, | 514 new ast.NodeList(openParen, |
| 511 new Link<ast.Node>.fromList(parameterList), | 515 new Link<ast.Node>.fromList(parameterList), |
| 512 closeParen, | 516 closeParen, |
| 513 ','); | 517 ','); |
| 514 | 518 |
| 515 ast.Node body = definition.body.accept(this); | 519 ast.Node body = visit(definition.body); |
| 516 | 520 |
| 517 if (!variables.isEmpty) { | 521 if (!variables.isEmpty) { |
| 518 // Introduce hoisted definitions for all variables. | 522 // Introduce hoisted definitions for all variables. |
| 519 ast.Identifier modifier = | 523 ast.Identifier modifier = |
| 520 new ast.Identifier(new KeywordToken(Keyword.keywords['var'], -1)); | 524 new ast.Identifier(new KeywordToken(Keyword.keywords['var'], -1)); |
| 521 ast.VariableDefinitions definitions = new ast.VariableDefinitions( | 525 ast.VariableDefinitions definitions = new ast.VariableDefinitions( |
| 522 null, | 526 null, |
| 523 new ast.Modifiers(new ast.NodeList( | 527 new ast.Modifiers(new ast.NodeList( |
| 524 null, | 528 null, |
| 525 new Link<ast.Node>.fromList([modifier]), | 529 new Link<ast.Node>.fromList([modifier]), |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } | 566 } |
| 563 | 567 |
| 564 return new ast.FunctionExpression(name, parameters, body, returnType, | 568 return new ast.FunctionExpression(name, parameters, body, returnType, |
| 565 ast.Modifiers.EMPTY, null, null); | 569 ast.Modifiers.EMPTY, null, null); |
| 566 } | 570 } |
| 567 | 571 |
| 568 /** | 572 /** |
| 569 * Translate a list of arguments to an AST NodeList. | 573 * Translate a list of arguments to an AST NodeList. |
| 570 */ | 574 */ |
| 571 ast.NodeList translateArguments(List<Expression> args) { | 575 ast.NodeList translateArguments(List<Expression> args) { |
| 572 List<ast.Expression> arguments = | 576 List<ast.Expression> arguments = args.map(visit).toList(growable: false); |
| 573 args.map((e) => e.accept(this)).toList(growable: false); | |
| 574 return makeArgumentList(arguments); | 577 return makeArgumentList(arguments); |
| 575 } | 578 } |
| 576 | 579 |
| 577 /** | 580 /** |
| 578 * Concatenate a pair of AST expressions or statements into a single Block | 581 * Concatenate a pair of AST expressions or statements into a single Block |
| 579 * statement. | 582 * statement. |
| 580 */ | 583 */ |
| 581 ast.Node concatenate(ast.Node first, ast.Node second) { | 584 ast.Node concatenate(ast.Node first, ast.Node second) { |
| 582 // This is a convenient but very inefficient way to accumulate statements. | 585 // This is a convenient but very inefficient way to accumulate statements. |
| 583 // The Block and NodeList nodes are not mutable so we can't simply use a | 586 // The Block and NodeList nodes are not mutable so we can't simply use a |
| (...skipping 24 matching lines...) Expand all Loading... |
| 608 } | 611 } |
| 609 | 612 |
| 610 ast.Node visitVariable(Variable node) { | 613 ast.Node visitVariable(Variable node) { |
| 611 // The scope of variables is the body of their binding, so a name has | 614 // The scope of variables is the body of their binding, so a name has |
| 612 // already been generated when we visit a variable. | 615 // already been generated when we visit a variable. |
| 613 assert(node.identifier != null); | 616 assert(node.identifier != null); |
| 614 return new ast.Send(null, node.identifier); | 617 return new ast.Send(null, node.identifier); |
| 615 } | 618 } |
| 616 | 619 |
| 617 ast.Node visitSequence(Sequence node) { | 620 ast.Node visitSequence(Sequence node) { |
| 618 return node.expressions.map((e) => e.accept(this)).reduce(concatenate); | 621 return node.expressions.map(visit).reduce(concatenate); |
| 619 } | 622 } |
| 620 | 623 |
| 621 ast.Node visitLetVal(LetVal node) { | 624 ast.Node visitLetVal(LetVal node) { |
| 622 // Let bindings translate into assignments. | 625 // Let bindings translate into assignments. |
| 623 ast.Identifier identifier = node.variable.assignIdentifier(); | 626 ast.Identifier identifier = node.variable.assignIdentifier(); |
| 624 variables.add(identifier); | 627 variables.add(identifier); |
| 625 | 628 |
| 626 ast.Expression expression = node.definition.accept(this); | 629 ast.Expression expression = visit(node.definition); |
| 627 ast.Expression assignment = makeAssignment(identifier, expression); | 630 ast.Expression assignment = makeAssignment(identifier, expression); |
| 628 | 631 |
| 629 ast.Node rest = node.body.accept(this); | 632 ast.Node rest = visit(node.body); |
| 630 return concatenate(assignment, rest); | 633 return concatenate(assignment, rest); |
| 631 } | 634 } |
| 632 | 635 |
| 633 ast.Node visitInvokeStatic(InvokeStatic node) { | 636 ast.Node visitInvokeStatic(InvokeStatic node) { |
| 634 ast.Identifier name = makeIdentifier(node.target.name); | 637 ast.Identifier name = makeIdentifier(node.target.name); |
| 635 ast.Send send = | 638 ast.Send send = |
| 636 new ast.Send(null, name, translateArguments(node.arguments)); | 639 new ast.Send(null, name, translateArguments(node.arguments)); |
| 637 treeElements[send] = node.target; | 640 treeElements[send] = node.target; |
| 638 return send; | 641 return send; |
| 639 } | 642 } |
| 640 | 643 |
| 641 ast.Node visitReturn(Return node) { | 644 ast.Node visitReturn(Return node) { |
| 642 ast.Expression expression = node.value.accept(this); | 645 ast.Expression expression = visit(node.value); |
| 643 return new ast.Return( | 646 return new ast.Return( |
| 644 new KeywordToken(Keyword.keywords['return'], -1), | 647 new KeywordToken(Keyword.keywords['return'], -1), |
| 645 semicolon, | 648 semicolon, |
| 646 expression); | 649 expression); |
| 647 } | 650 } |
| 648 | 651 |
| 649 ast.Node visitConstant(Constant node) { | 652 ast.Node visitConstant(Constant node) { |
| 650 return node.value.accept(constantEmitter); | 653 return node.value.accept(constantEmitter); |
| 651 } | 654 } |
| 652 } | 655 } |
| 653 | 656 |
| 654 class TypeEmitter extends | 657 class TypeEmitter extends |
| 655 DartTypeVisitor<ast.TypeAnnotation, dart2js.TreeElementMapping> { | 658 DartTypeVisitor<ast.TypeAnnotation, dart2js.TreeElementMapping> { |
| 656 | 659 |
| 657 // Supported types are verified at IR construction time. The unimplemented | 660 // Supported types are verified at IR construction time. The unimplemented |
| 658 // emit methods should be unreachable. | 661 // emit methods should be unreachable. |
| 659 ast.TypeAnnotation unimplemented() => throw new UnimplementedError(); | 662 ast.TypeAnnotation unimplemented() => throw new UnimplementedError(); |
| 660 | 663 |
| 661 ast.TypeAnnotation makeSimpleAnnotation( | 664 ast.TypeAnnotation makeSimpleAnnotation( |
| 662 DartType type, | 665 DartType type, |
| 663 dart2js.TreeElementMapping treeElements) { | 666 dart2js.TreeElementMapping treeElements) { |
| 664 ast.TypeAnnotation annotation = | 667 ast.TypeAnnotation annotation = |
| 665 new ast.TypeAnnotation(Emitter.makeIdentifier(type.toString()), null); | 668 new ast.TypeAnnotation(Emitter.makeIdentifier(type.toString()), null); |
| 666 treeElements.setType(annotation, type); | 669 treeElements.setType(annotation, type); |
| 667 return annotation; | 670 return annotation; |
| 668 } | 671 } |
| 669 | 672 |
| 670 ast.TypeAnnotation visitType(DartType type, | 673 ast.TypeAnnotation visitType(DartType type, |
| 671 dart2js.TreeElementMapping treeElements) { | 674 dart2js.TreeElementMapping treeElements) { |
| 672 return unimplemented(); | 675 return type.accept(this, treeElements); |
| 673 } | 676 } |
| 674 | 677 |
| 675 ast.TypeAnnotation visitVoidType(VoidType type, | 678 ast.TypeAnnotation visitVoidType(VoidType type, |
| 676 dart2js.TreeElementMapping treeElements) { | 679 dart2js.TreeElementMapping treeElements) { |
| 677 return makeSimpleAnnotation(type, treeElements); | 680 return makeSimpleAnnotation(type, treeElements); |
| 678 } | 681 } |
| 679 | 682 |
| 680 ast.TypeAnnotation visitInterfaceType( | 683 ast.TypeAnnotation visitInterfaceType( |
| 681 InterfaceType type, | 684 InterfaceType type, |
| 682 dart2js.TreeElementMapping treeElements) { | 685 dart2js.TreeElementMapping treeElements) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 } | 756 } |
| 754 | 757 |
| 755 ast.Expression visitInterceptor(dart2js.InterceptorConstant constant) { | 758 ast.Expression visitInterceptor(dart2js.InterceptorConstant constant) { |
| 756 return unimplemented(); | 759 return unimplemented(); |
| 757 } | 760 } |
| 758 | 761 |
| 759 ast.Expression visitDummy(dart2js.DummyConstant constant) { | 762 ast.Expression visitDummy(dart2js.DummyConstant constant) { |
| 760 return unimplemented(); | 763 return unimplemented(); |
| 761 } | 764 } |
| 762 } | 765 } |
| OLD | NEW |