OLD | NEW |
---|---|
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:convert'; | 6 import 'dart:convert'; |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/visitor.dart'; | 10 import 'package:analyzer/dart/ast/visitor.dart'; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 return null; | 147 return null; |
148 } else { | 148 } else { |
149 return validation.problemsAsString; | 149 return validation.problemsAsString; |
150 } | 150 } |
151 } else { | 151 } else { |
152 return null; | 152 return null; |
153 } | 153 } |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 /// Instance of [InstrumentationValue] describing a [MethodElement]. | 157 /// Instance of [InstrumentationValue] describing an [ExecutableElement]. |
158 class _InstrumentationValueForMethodElement extends fasta.InstrumentationValue { | 158 class _InstrumentationValueForExecutableElement |
159 final MethodElement element; | 159 extends fasta.InstrumentationValue { |
160 final ExecutableElement element; | |
160 final _ElementNamer elementNamer; | 161 final _ElementNamer elementNamer; |
161 | 162 |
162 _InstrumentationValueForMethodElement(this.element, this.elementNamer); | 163 _InstrumentationValueForExecutableElement(this.element, this.elementNamer); |
163 | 164 |
164 @override | 165 @override |
165 String toString() { | 166 String toString() { |
166 StringBuffer buffer = new StringBuffer(); | 167 StringBuffer buffer = new StringBuffer(); |
167 elementNamer.appendElementName(buffer, element); | 168 elementNamer.appendElementName(buffer, element); |
168 return buffer.toString(); | 169 return buffer.toString(); |
169 } | 170 } |
170 } | 171 } |
171 | 172 |
172 /** | 173 /** |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 // } | 288 // } |
288 // } | 289 // } |
289 // So to match kernel behavior, we have to arrange for this renaming to | 290 // So to match kernel behavior, we have to arrange for this renaming to |
290 // happen during output. | 291 // happen during output. |
291 elementNamer = new _ElementNamer(node.element); | 292 elementNamer = new _ElementNamer(node.element); |
292 } | 293 } |
293 super.visitConstructorDeclaration(node); | 294 super.visitConstructorDeclaration(node); |
294 elementNamer = oldElementNamer; | 295 elementNamer = oldElementNamer; |
295 } | 296 } |
296 | 297 |
298 @override | |
299 visitDeclaredIdentifier(DeclaredIdentifier node) { | |
300 super.visitDeclaredIdentifier(node); | |
301 if (node.type == null) { | |
302 _recordType(node.identifier.offset, node.element.type); | |
303 } | |
304 } | |
305 | |
297 visitFunctionExpression(FunctionExpression node) { | 306 visitFunctionExpression(FunctionExpression node) { |
298 super.visitFunctionExpression(node); | 307 super.visitFunctionExpression(node); |
299 if (node.parent is! FunctionDeclaration) { | 308 if (node.parent is! FunctionDeclaration) { |
300 DartType type = node.staticType; | 309 DartType type = node.staticType; |
301 if (type is FunctionType) { | 310 if (type is FunctionType) { |
302 _instrumentation.record(uri, node.offset, 'returnType', | 311 _instrumentation.record(uri, node.offset, 'returnType', |
303 new _InstrumentationValueForType(type.returnType, elementNamer)); | 312 new _InstrumentationValueForType(type.returnType, elementNamer)); |
304 List<FormalParameter> parameters = node.parameters.parameters; | 313 List<FormalParameter> parameters = node.parameters.parameters; |
305 for (int i = 0; i < parameters.length; i++) { | 314 for (int i = 0; i < parameters.length; i++) { |
306 FormalParameter parameter = parameters[i]; | 315 FormalParameter parameter = parameters[i]; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 if (node.typeArguments == null) { | 367 if (node.typeArguments == null) { |
359 DartType type = node.staticType; | 368 DartType type = node.staticType; |
360 if (type is InterfaceType) { | 369 if (type is InterfaceType) { |
361 _recordTypeArguments(node.offset, type.typeArguments); | 370 _recordTypeArguments(node.offset, type.typeArguments); |
362 } | 371 } |
363 } | 372 } |
364 } | 373 } |
365 | 374 |
366 visitMethodInvocation(MethodInvocation node) { | 375 visitMethodInvocation(MethodInvocation node) { |
367 super.visitMethodInvocation(node); | 376 super.visitMethodInvocation(node); |
368 _recordMethodTarget(node.methodName.offset, node.methodName.staticElement); | 377 if (node.target != null) { |
378 _recordMethodTarget( | |
379 node.methodName.offset, node.methodName.staticElement); | |
380 } | |
369 if (node.typeArguments == null) { | 381 if (node.typeArguments == null) { |
370 var inferredTypeArguments = _getInferredFunctionTypeArguments( | 382 var inferredTypeArguments = _getInferredFunctionTypeArguments( |
371 node.function.staticType, | 383 node.function.staticType, |
372 node.staticInvokeType, | 384 node.staticInvokeType, |
373 node.typeArguments) | 385 node.typeArguments) |
374 .toList(); | 386 .toList(); |
375 if (inferredTypeArguments.isNotEmpty) { | 387 if (inferredTypeArguments.isNotEmpty) { |
376 _recordTypeArguments(node.methodName.offset, inferredTypeArguments); | 388 _recordTypeArguments(node.methodName.offset, inferredTypeArguments); |
377 } | 389 } |
378 } | 390 } |
379 } | 391 } |
380 | 392 |
393 @override | |
394 visitPrefixedIdentifier(PrefixedIdentifier node) { | |
395 super.visitPrefixedIdentifier(node); | |
396 if (node.prefix.staticElement is! PrefixElement && | |
397 node.prefix.staticElement is! ClassElement) { | |
398 if (node.identifier.inGetterContext()) { | |
399 _recordMethodTarget( | |
400 node.identifier.offset, node.identifier.staticElement); | |
401 } | |
402 } | |
403 } | |
404 | |
381 visitPrefixExpression(PrefixExpression node) { | 405 visitPrefixExpression(PrefixExpression node) { |
382 super.visitPrefixExpression(node); | 406 super.visitPrefixExpression(node); |
383 _recordMethodTarget(node.operator.charOffset, node.staticElement); | 407 _recordMethodTarget(node.operator.charOffset, node.staticElement); |
384 } | 408 } |
385 | 409 |
410 @override | |
411 visitPropertyAccess(PropertyAccess node) { | |
412 super.visitPropertyAccess(node); | |
413 if (node.propertyName.inGetterContext()) { | |
414 _recordMethodTarget( | |
415 node.propertyName.offset, node.propertyName.staticElement); | |
416 } | |
417 } | |
418 | |
386 visitSimpleIdentifier(SimpleIdentifier node) { | 419 visitSimpleIdentifier(SimpleIdentifier node) { |
387 super.visitSimpleIdentifier(node); | 420 super.visitSimpleIdentifier(node); |
388 Element element = node.staticElement; | 421 Element element = node.staticElement; |
389 void recordPromotions(DartType elementType) { | 422 void recordPromotions(DartType elementType) { |
390 if (node.inGetterContext() && !node.inDeclarationContext()) { | 423 if (node.inGetterContext() && !node.inDeclarationContext()) { |
391 int offset = node.offset; | 424 int offset = node.offset; |
392 DartType type = node.staticType; | 425 DartType type = node.staticType; |
393 if (!identical(type, elementType)) { | 426 if (!identical(type, elementType)) { |
394 _instrumentation.record(uri, offset, 'promotedType', | 427 _instrumentation.record(uri, offset, 'promotedType', |
395 new _InstrumentationValueForType(type, elementNamer)); | 428 new _InstrumentationValueForType(type, elementNamer)); |
396 } | 429 } |
397 } | 430 } |
398 } | 431 } |
399 | 432 |
400 if (element is LocalVariableElement) { | 433 if (element is LocalVariableElement) { |
401 recordPromotions(element.type); | 434 recordPromotions(element.type); |
402 } else if (element is ParameterElement) { | 435 } else if (element is ParameterElement) { |
403 recordPromotions(element.type); | 436 recordPromotions(element.type); |
404 } | 437 } |
405 } | 438 } |
406 | 439 |
407 @override | |
408 visitDeclaredIdentifier(DeclaredIdentifier node) { | |
409 super.visitDeclaredIdentifier(node); | |
410 if (node.type == null) { | |
411 _recordType(node.identifier.offset, node.element.type); | |
412 } | |
413 } | |
414 | |
415 visitVariableDeclarationList(VariableDeclarationList node) { | 440 visitVariableDeclarationList(VariableDeclarationList node) { |
416 super.visitVariableDeclarationList(node); | 441 super.visitVariableDeclarationList(node); |
417 if (node.type == null) { | 442 if (node.type == null) { |
418 for (VariableDeclaration variable in node.variables) { | 443 for (VariableDeclaration variable in node.variables) { |
419 VariableElement element = variable.element; | 444 VariableElement element = variable.element; |
420 if (element is LocalVariableElement) { | 445 if (element is LocalVariableElement) { |
421 _recordType(variable.name.offset, element.type); | 446 _recordType(variable.name.offset, element.type); |
422 } else { | 447 } else { |
423 _recordTopType(variable.name.offset, element.type); | 448 _recordTopType(variable.name.offset, element.type); |
424 } | 449 } |
425 } | 450 } |
426 } | 451 } |
427 } | 452 } |
428 | 453 |
429 /// Based on DDC code generator's `_emitFunctionTypeArguments` | 454 /// Based on DDC code generator's `_emitFunctionTypeArguments` |
430 Iterable<DartType> _getInferredFunctionTypeArguments( | 455 Iterable<DartType> _getInferredFunctionTypeArguments( |
431 DartType g, DartType f, TypeArgumentList typeArgs) { | 456 DartType g, DartType f, TypeArgumentList typeArgs) { |
432 if (g is FunctionType && | 457 if (g is FunctionType && |
433 g.typeFormals.isNotEmpty && | 458 g.typeFormals.isNotEmpty && |
434 f is FunctionType && | 459 f is FunctionType && |
435 f.typeFormals.isEmpty) { | 460 f.typeFormals.isEmpty) { |
436 return _recoverTypeArguments(g, f); | 461 return _recoverTypeArguments(g, f); |
437 } else { | 462 } else { |
438 return const []; | 463 return const []; |
439 } | 464 } |
440 } | 465 } |
441 | 466 |
442 void _recordMethodTarget(int offset, Element element) { | 467 void _recordMethodTarget(int offset, Element element) { |
scheglov
2017/05/31 18:40:13
Maybe this method should also be renamed.
Paul Berry
2017/05/31 19:08:33
Good point. Renamed to "_recordTarget".
| |
443 if (element is MethodElement) { | 468 if (element is ExecutableElement) { |
444 _instrumentation.record(uri, offset, 'target', | 469 _instrumentation.record(uri, offset, 'target', |
445 new _InstrumentationValueForMethodElement(element, elementNamer)); | 470 new _InstrumentationValueForExecutableElement(element, elementNamer)); |
446 } | 471 } |
447 } | 472 } |
448 | 473 |
449 void _recordTopType(int offset, DartType type) { | 474 void _recordTopType(int offset, DartType type) { |
450 _instrumentation.record(uri, offset, 'topType', | 475 _instrumentation.record(uri, offset, 'topType', |
451 new _InstrumentationValueForType(type, elementNamer)); | 476 new _InstrumentationValueForType(type, elementNamer)); |
452 } | 477 } |
453 | 478 |
454 void _recordType(int offset, DartType type) { | 479 void _recordType(int offset, DartType type) { |
455 _instrumentation.record(uri, offset, 'type', | 480 _instrumentation.record(uri, offset, 'type', |
456 new _InstrumentationValueForType(type, elementNamer)); | 481 new _InstrumentationValueForType(type, elementNamer)); |
457 } | 482 } |
458 | 483 |
459 void _recordTypeArguments(int offset, List<DartType> typeArguments) { | 484 void _recordTypeArguments(int offset, List<DartType> typeArguments) { |
460 _instrumentation.record(uri, offset, 'typeArgs', | 485 _instrumentation.record(uri, offset, 'typeArgs', |
461 new _InstrumentationValueForTypeArgs(typeArguments, elementNamer)); | 486 new _InstrumentationValueForTypeArgs(typeArguments, elementNamer)); |
462 } | 487 } |
463 | 488 |
464 /// Based on DDC code generator's `_recoverTypeArguments` | 489 /// Based on DDC code generator's `_recoverTypeArguments` |
465 Iterable<DartType> _recoverTypeArguments(FunctionType g, FunctionType f) { | 490 Iterable<DartType> _recoverTypeArguments(FunctionType g, FunctionType f) { |
466 assert(identical(g.element, f.element)); | 491 assert(identical(g.element, f.element)); |
467 assert(g.typeFormals.isNotEmpty && f.typeFormals.isEmpty); | 492 assert(g.typeFormals.isNotEmpty && f.typeFormals.isEmpty); |
468 assert(g.typeFormals.length + g.typeArguments.length == | 493 assert(g.typeFormals.length + g.typeArguments.length == |
469 f.typeArguments.length); | 494 f.typeArguments.length); |
470 return f.typeArguments.skip(g.typeArguments.length); | 495 return f.typeArguments.skip(g.typeArguments.length); |
471 } | 496 } |
472 } | 497 } |
OLD | NEW |