Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: pkg/analyzer/test/src/task/strong/front_end_inference_test.dart

Issue 2921443002: Implement type inference for PropertyGet. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/front_end/lib/src/base/instrumentation.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/front_end/lib/src/base/instrumentation.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698