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

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart

Issue 2943273002: Implement type inference of getters/setters based on inheritance. (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
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 /// This file declares a "shadow hierarchy" of concrete classes which extend 5 /// This file declares a "shadow hierarchy" of concrete classes which extend
6 /// the kernel class hierarchy, adding methods and fields needed by the 6 /// the kernel class hierarchy, adding methods and fields needed by the
7 /// BodyBuilder. 7 /// BodyBuilder.
8 /// 8 ///
9 /// Instances of these classes may be created using the factory methods in 9 /// Instances of these classes may be created using the factory methods in
10 /// `ast_factory.dart`. 10 /// `ast_factory.dart`.
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 fileOffset, 653 fileOffset,
654 _initialTarget.function.functionType, 654 _initialTarget.function.functionType,
655 computeConstructorReturnType(_initialTarget), 655 computeConstructorReturnType(_initialTarget),
656 arguments); 656 arguments);
657 inferrer.listener.constructorInvocationExit(this, inferredType); 657 inferrer.listener.constructorInvocationExit(this, inferredType);
658 return inferredType; 658 return inferredType;
659 } 659 }
660 } 660 }
661 661
662 /// Concrete shadow object representing a field in kernel form. 662 /// Concrete shadow object representing a field in kernel form.
663 class KernelField extends Field { 663 class KernelField extends Field implements KernelMember {
664 @override
664 FieldNode _fieldNode; 665 FieldNode _fieldNode;
665 666
667 @override
666 KernelTypeInferrer _typeInferrer; 668 KernelTypeInferrer _typeInferrer;
667 669
668 KernelField(Name name, {String fileUri}) : super(name, fileUri: fileUri) {} 670 KernelField(Name name, {String fileUri}) : super(name, fileUri: fileUri) {}
669 671
670 static FieldNode getFieldNode(Field field) { 672 @override
671 if (field is KernelField) return field._fieldNode; 673 void setInferredType(
672 return null; 674 TypeInferenceEngineImpl engine, String uri, DartType inferredType) {
673 } 675 engine.instrumentation?.record(Uri.parse(uri), fileOffset, 'topType',
674 676 new InstrumentationValueForType(inferredType));
675 static void recordOverride( 677 type = inferredType;
676 KernelField field, Member overriddenMember, bool isSetter) {
677 if (field._fieldNode != null) {
678 if (isSetter && overriddenMember is Field) {
679 // When overriding a field, we are called twice; once for the setter and
680 // once for the getter. Ignore the setter.
681 return;
682 }
683 field._fieldNode.overrides.add(overriddenMember);
684 }
685 } 678 }
686 } 679 }
687 680
688 /// Concrete shadow object representing a for-in loop in kernel form. 681 /// Concrete shadow object representing a for-in loop in kernel form.
689 class KernelForInStatement extends ForInStatement implements KernelStatement { 682 class KernelForInStatement extends ForInStatement implements KernelStatement {
690 final bool _declaresVariable; 683 final bool _declaresVariable;
691 684
692 KernelForInStatement(VariableDeclaration variable, Expression iterable, 685 KernelForInStatement(VariableDeclaration variable, Expression iterable,
693 Statement body, this._declaresVariable, 686 Statement body, this._declaresVariable,
694 {bool isAsync: false}) 687 {bool isAsync: false})
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 valueType = inferredValueType; 1251 valueType = inferredValueType;
1259 } 1252 }
1260 var inferredType = typeNeeded 1253 var inferredType = typeNeeded
1261 ? new InterfaceType(mapClass, [inferredKeyType, inferredValueType]) 1254 ? new InterfaceType(mapClass, [inferredKeyType, inferredValueType])
1262 : null; 1255 : null;
1263 inferrer.listener.mapLiteralExit(this, inferredType); 1256 inferrer.listener.mapLiteralExit(this, inferredType);
1264 return inferredType; 1257 return inferredType;
1265 } 1258 }
1266 } 1259 }
1267 1260
1261 /// Abstract shadow object representing a field or procedure in kernel form.
1262 abstract class KernelMember implements Member {
1263 String get fileUri;
1264
1265 FieldNode get _fieldNode;
1266
1267 void set _fieldNode(FieldNode value);
1268
1269 KernelTypeInferrer get _typeInferrer;
1270
1271 void set _typeInferrer(KernelTypeInferrer value);
1272
1273 void setInferredType(
1274 TypeInferenceEngineImpl engine, String uri, DartType inferredType);
1275
1276 static FieldNode getFieldNode(Member member) {
1277 if (member is KernelMember) return member._fieldNode;
1278 return null;
1279 }
1280
1281 static void recordOverride(KernelMember member, Member overriddenMember) {
1282 if (member._fieldNode != null) {
1283 member._fieldNode.overrides.add(overriddenMember);
1284 }
1285 }
1286 }
1287
1268 /// Shadow object for [MethodInvocation]. 1288 /// Shadow object for [MethodInvocation].
1269 class KernelMethodInvocation extends MethodInvocation 1289 class KernelMethodInvocation extends MethodInvocation
1270 implements KernelExpression { 1290 implements KernelExpression {
1271 /// Indicates whether this method invocation is a call to a `call` method 1291 /// Indicates whether this method invocation is a call to a `call` method
1272 /// resulting from the invocation of a function expression. 1292 /// resulting from the invocation of a function expression.
1273 final bool _isImplicitCall; 1293 final bool _isImplicitCall;
1274 1294
1275 KernelMethodInvocation(Expression receiver, Name name, Arguments arguments, 1295 KernelMethodInvocation(Expression receiver, Name name, Arguments arguments,
1276 {bool isImplicitCall: false, Member interfaceTarget}) 1296 {bool isImplicitCall: false, Member interfaceTarget})
1277 : _isImplicitCall = isImplicitCall, 1297 : _isImplicitCall = isImplicitCall,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 DartType _inferExpression( 1379 DartType _inferExpression(
1360 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { 1380 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) {
1361 typeNeeded = 1381 typeNeeded =
1362 inferrer.listener.nullLiteralEnter(this, typeContext) || typeNeeded; 1382 inferrer.listener.nullLiteralEnter(this, typeContext) || typeNeeded;
1363 var inferredType = typeNeeded ? inferrer.coreTypes.nullClass.rawType : null; 1383 var inferredType = typeNeeded ? inferrer.coreTypes.nullClass.rawType : null;
1364 inferrer.listener.nullLiteralExit(this, inferredType); 1384 inferrer.listener.nullLiteralExit(this, inferredType);
1365 return inferredType; 1385 return inferredType;
1366 } 1386 }
1367 } 1387 }
1368 1388
1389 /// Concrete shadow object representing a procedure in kernel form.
1390 class KernelProcedure extends Procedure implements KernelMember {
1391 @override
1392 FieldNode _fieldNode;
1393
1394 @override
1395 KernelTypeInferrer _typeInferrer;
1396
1397 KernelProcedure(Name name, ProcedureKind kind, FunctionNode function,
1398 {String fileUri})
1399 : super(name, kind, function, fileUri: fileUri);
1400
1401 @override
1402 void setInferredType(
1403 TypeInferenceEngineImpl engine, String uri, DartType inferredType) {
1404 if (isSetter) {
1405 if (function.positionalParameters.length > 0) {
1406 var parameter = function.positionalParameters[0];
1407 engine.instrumentation?.record(Uri.parse(uri), parameter.fileOffset,
1408 'topType', new InstrumentationValueForType(inferredType));
1409 parameter.type = inferredType;
1410 }
1411 } else if (isGetter) {
1412 engine.instrumentation?.record(Uri.parse(uri), fileOffset, 'topType',
1413 new InstrumentationValueForType(inferredType));
1414 function.returnType = inferredType;
1415 } else {
1416 internalError(
1417 'setInferredType called on a procedure that is not an accessor');
1418 }
1419 }
1420 }
1421
1369 /// Concrete shadow object representing an assignment to a property. 1422 /// Concrete shadow object representing an assignment to a property.
1370 class KernelPropertyAssign extends KernelComplexAssignmentWithReceiver { 1423 class KernelPropertyAssign extends KernelComplexAssignmentWithReceiver {
1371 /// If this assignment uses null-aware access (`?.`), the conditional 1424 /// If this assignment uses null-aware access (`?.`), the conditional
1372 /// expression that guards the access; otherwise `null`. 1425 /// expression that guards the access; otherwise `null`.
1373 Expression nullAwareGuard; 1426 Expression nullAwareGuard;
1374 1427
1375 KernelPropertyAssign(Expression receiver, Expression rhs, 1428 KernelPropertyAssign(Expression receiver, Expression rhs,
1376 {bool isSuper: false}) 1429 {bool isSuper: false})
1377 : super(receiver, rhs, isSuper); 1430 : super(receiver, rhs, isSuper);
1378 1431
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 } 1859 }
1807 } 1860 }
1808 1861
1809 /// Concrete implementation of [TypeInferenceEngine] specialized to work with 1862 /// Concrete implementation of [TypeInferenceEngine] specialized to work with
1810 /// kernel objects. 1863 /// kernel objects.
1811 class KernelTypeInferenceEngine extends TypeInferenceEngineImpl { 1864 class KernelTypeInferenceEngine extends TypeInferenceEngineImpl {
1812 KernelTypeInferenceEngine(Instrumentation instrumentation, bool strongMode) 1865 KernelTypeInferenceEngine(Instrumentation instrumentation, bool strongMode)
1813 : super(instrumentation, strongMode); 1866 : super(instrumentation, strongMode);
1814 1867
1815 @override 1868 @override
1816 void clearFieldInitializer(KernelField field) { 1869 FieldNode createFieldNode(KernelMember member) {
1817 field.initializer = null; 1870 FieldNode fieldNode = new FieldNode(this, member);
1818 } 1871 member._fieldNode = fieldNode;
1819
1820 @override
1821 FieldNode createFieldNode(KernelField field) {
1822 FieldNode fieldNode = new FieldNode(this, field);
1823 field._fieldNode = fieldNode;
1824 return fieldNode; 1872 return fieldNode;
1825 } 1873 }
1826 1874
1827 @override 1875 @override
1828 KernelTypeInferrer createLocalTypeInferrer( 1876 KernelTypeInferrer createLocalTypeInferrer(
1829 Uri uri, TypeInferenceListener listener, InterfaceType thisType) { 1877 Uri uri, TypeInferenceListener listener, InterfaceType thisType) {
1830 return new KernelTypeInferrer._( 1878 return new KernelTypeInferrer._(
1831 this, uri.toString(), listener, false, thisType, null); 1879 this, uri.toString(), listener, false, thisType, null);
1832 } 1880 }
1833 1881
1834 @override 1882 @override
1835 KernelTypeInferrer createTopLevelTypeInferrer(TypeInferenceListener listener, 1883 KernelTypeInferrer createTopLevelTypeInferrer(TypeInferenceListener listener,
1836 InterfaceType thisType, KernelField field) { 1884 InterfaceType thisType, KernelMember member) {
1837 return field._typeInferrer = new KernelTypeInferrer._( 1885 return member._typeInferrer = new KernelTypeInferrer._(
1838 this, field.fileUri, listener, true, thisType, field._fieldNode); 1886 this, member.fileUri, listener, true, thisType, member._fieldNode);
1839 } 1887 }
1840 1888
1841 @override 1889 @override
1842 int getFieldOffset(KernelField field) { 1890 KernelTypeInferrer getFieldTypeInferrer(KernelMember member) {
1843 return field.fileOffset; 1891 return member._typeInferrer;
1844 }
1845
1846 @override
1847 KernelTypeInferrer getFieldTypeInferrer(KernelField field) {
1848 return field._typeInferrer;
1849 } 1892 }
1850 } 1893 }
1851 1894
1852 /// Concrete implementation of [TypeInferrer] specialized to work with kernel 1895 /// Concrete implementation of [TypeInferrer] specialized to work with kernel
1853 /// objects. 1896 /// objects.
1854 class KernelTypeInferrer extends TypeInferrerImpl { 1897 class KernelTypeInferrer extends TypeInferrerImpl {
1855 @override 1898 @override
1856 final typePromoter = new KernelTypePromoter(); 1899 final typePromoter = new KernelTypePromoter();
1857 1900
1858 KernelTypeInferrer._( 1901 KernelTypeInferrer._(
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
2178 } 2221 }
2179 2222
2180 transformChildren(v) { 2223 transformChildren(v) {
2181 return internalError("Internal error: Unsupported operation."); 2224 return internalError("Internal error: Unsupported operation.");
2182 } 2225 }
2183 2226
2184 visitChildren(v) { 2227 visitChildren(v) {
2185 return internalError("Internal error: Unsupported operation."); 2228 return internalError("Internal error: Unsupported operation.");
2186 } 2229 }
2187 } 2230 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698