| 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 /// 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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 inferrer.findMethodInvocationMember(writeContext, equalsInvocation, | 364 inferrer.findMethodInvocationMember(writeContext, equalsInvocation, |
| 365 silent: true); | 365 silent: true); |
| 366 return inferrer.typeSchemaEnvironment | 366 return inferrer.typeSchemaEnvironment |
| 367 .getLeastUpperBound(inferredType, rhsType); | 367 .getLeastUpperBound(inferredType, rhsType); |
| 368 } else if (combiner != null) { | 368 } else if (combiner != null) { |
| 369 bool isOverloadedArithmeticOperator = false; | 369 bool isOverloadedArithmeticOperator = false; |
| 370 var combinerMember = inferrer | 370 var combinerMember = inferrer |
| 371 .findMethodInvocationMember(writeContext, combiner, silent: true); | 371 .findMethodInvocationMember(writeContext, combiner, silent: true); |
| 372 if (combinerMember is Procedure) { | 372 if (combinerMember is Procedure) { |
| 373 isOverloadedArithmeticOperator = inferrer.typeSchemaEnvironment | 373 isOverloadedArithmeticOperator = inferrer.typeSchemaEnvironment |
| 374 .isOverloadedArithmeticOperator(combinerMember); | 374 .isOverloadedArithmeticOperatorAndType( |
| 375 combinerMember, writeContext); |
| 375 } | 376 } |
| 376 if (isPostIncDec) { | 377 if (isPostIncDec) { |
| 377 return inferredType; | 378 return inferredType; |
| 378 } else { | 379 } else { |
| 379 DartType rhsType; | 380 DartType rhsType; |
| 380 if (isPreIncDec) { | 381 if (isPreIncDec) { |
| 381 rhsType = inferrer.coreTypes.intClass.rawType; | 382 rhsType = inferrer.coreTypes.intClass.rawType; |
| 382 } else { | 383 } else { |
| 383 // Analyzer uses a null context for the RHS here. | 384 // Analyzer uses a null context for the RHS here. |
| 384 // TODO(paulberry): improve on this. | 385 // TODO(paulberry): improve on this. |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 arguments); | 680 arguments); |
| 680 inferrer.listener.constructorInvocationExit(this, inferredType); | 681 inferrer.listener.constructorInvocationExit(this, inferredType); |
| 681 return inferredType; | 682 return inferredType; |
| 682 } | 683 } |
| 683 } | 684 } |
| 684 | 685 |
| 685 /// Concrete shadow object representing a field in kernel form. | 686 /// Concrete shadow object representing a field in kernel form. |
| 686 class KernelField extends Field { | 687 class KernelField extends Field { |
| 687 FieldNode _fieldNode; | 688 FieldNode _fieldNode; |
| 688 | 689 |
| 689 bool _isInferred = false; | |
| 690 | |
| 691 KernelTypeInferrer _typeInferrer; | 690 KernelTypeInferrer _typeInferrer; |
| 692 | 691 |
| 693 KernelField(Name name, {String fileUri}) : super(name, fileUri: fileUri) {} | 692 KernelField(Name name, {String fileUri}) : super(name, fileUri: fileUri) {} |
| 694 | |
| 695 void _setInferredType(DartType inferredType) { | |
| 696 _isInferred = true; | |
| 697 super.type = inferredType; | |
| 698 } | |
| 699 } | 693 } |
| 700 | 694 |
| 701 /// Concrete shadow object representing a for-in loop in kernel form. | 695 /// Concrete shadow object representing a for-in loop in kernel form. |
| 702 class KernelForInStatement extends ForInStatement implements KernelStatement { | 696 class KernelForInStatement extends ForInStatement implements KernelStatement { |
| 703 final bool _declaresVariable; | 697 final bool _declaresVariable; |
| 704 | 698 |
| 705 KernelForInStatement(VariableDeclaration variable, Expression iterable, | 699 KernelForInStatement(VariableDeclaration variable, Expression iterable, |
| 706 Statement body, this._declaresVariable, | 700 Statement body, this._declaresVariable, |
| 707 {bool isAsync: false}) | 701 {bool isAsync: false}) |
| 708 : super(variable, iterable, body, isAsync: isAsync); | 702 : super(variable, iterable, body, isAsync: isAsync); |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 1299 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 1306 typeNeeded = inferrer.listener.methodInvocationEnter(this, typeContext) || | 1300 typeNeeded = inferrer.listener.methodInvocationEnter(this, typeContext) || |
| 1307 typeNeeded; | 1301 typeNeeded; |
| 1308 // First infer the receiver so we can look up the method that was invoked. | 1302 // First infer the receiver so we can look up the method that was invoked. |
| 1309 var receiverType = inferrer.inferExpression(receiver, null, true); | 1303 var receiverType = inferrer.inferExpression(receiver, null, true); |
| 1310 bool isOverloadedArithmeticOperator = false; | 1304 bool isOverloadedArithmeticOperator = false; |
| 1311 Member interfaceMember = | 1305 Member interfaceMember = |
| 1312 inferrer.findMethodInvocationMember(receiverType, this); | 1306 inferrer.findMethodInvocationMember(receiverType, this); |
| 1313 if (interfaceMember is Procedure) { | 1307 if (interfaceMember is Procedure) { |
| 1314 isOverloadedArithmeticOperator = inferrer.typeSchemaEnvironment | 1308 isOverloadedArithmeticOperator = inferrer.typeSchemaEnvironment |
| 1315 .isOverloadedArithmeticOperator(interfaceMember); | 1309 .isOverloadedArithmeticOperatorAndType(interfaceMember, receiverType); |
| 1316 } | 1310 } |
| 1317 var calleeType = inferrer.getCalleeFunctionType( | 1311 var calleeType = inferrer.getCalleeFunctionType( |
| 1318 interfaceMember, receiverType, name, !_isImplicitCall); | 1312 interfaceMember, receiverType, name, !_isImplicitCall); |
| 1319 bool forceArgumentInference = false; | 1313 bool forceArgumentInference = false; |
| 1320 if (inferrer.isDryRun) { | 1314 if (inferrer.isDryRun) { |
| 1321 if (_isUserDefinableOperator(name.name)) { | 1315 if (_isUserDefinableOperator(name.name)) { |
| 1322 // If this is an overloadable arithmetic operator, then type inference | 1316 // If this is an overloadable arithmetic operator, then type inference |
| 1323 // might depend on the RHS, so conservatively assume it does. | 1317 // might depend on the RHS, so conservatively assume it does. |
| 1324 forceArgumentInference = _isOverloadableArithmeticOperator(name.name); | 1318 forceArgumentInference = _isOverloadableArithmeticOperator(name.name); |
| 1325 } else { | 1319 } else { |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1588 DartType _inferExpression( | 1582 DartType _inferExpression( |
| 1589 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 1583 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 1590 typeNeeded = inferrer.listener.staticAssignEnter(desugared, typeContext) || | 1584 typeNeeded = inferrer.listener.staticAssignEnter(desugared, typeContext) || |
| 1591 typeNeeded; | 1585 typeNeeded; |
| 1592 // TODO(paulberry): record the appropriate types on let variables and | 1586 // TODO(paulberry): record the appropriate types on let variables and |
| 1593 // conditional expressions. | 1587 // conditional expressions. |
| 1594 DartType writeContext; | 1588 DartType writeContext; |
| 1595 var write = this.write; | 1589 var write = this.write; |
| 1596 if (write is StaticSet) { | 1590 if (write is StaticSet) { |
| 1597 writeContext = write.target.setterType; | 1591 writeContext = write.target.setterType; |
| 1598 if (inferrer.isDryRun) { | 1592 var target = write.target; |
| 1599 var target = write.target; | 1593 if (target is KernelField && target._fieldNode != null) { |
| 1600 if (target is KernelField && target._fieldNode != null) { | 1594 if (inferrer.isDryRun) { |
| 1601 inferrer.recordDryRunDependency(target._fieldNode); | 1595 inferrer.recordDryRunDependency(target._fieldNode); |
| 1602 } | 1596 } |
| 1597 if (TypeInferenceEngineImpl.fusedTopLevelInference && |
| 1598 inferrer.isTopLevel) { |
| 1599 inferrer.engine |
| 1600 .inferFieldFused(target._fieldNode, inferrer.fieldNode); |
| 1601 } |
| 1603 } | 1602 } |
| 1604 } | 1603 } |
| 1605 var inferredType = _inferRhs(inferrer, writeContext); | 1604 var inferredType = _inferRhs(inferrer, writeContext); |
| 1606 inferrer.listener.staticAssignExit(desugared, inferredType); | 1605 inferrer.listener.staticAssignExit(desugared, inferredType); |
| 1607 return inferredType; | 1606 return inferredType; |
| 1608 } | 1607 } |
| 1609 } | 1608 } |
| 1610 | 1609 |
| 1611 /// Concrete shadow object representing a read of a static variable in kernel | 1610 /// Concrete shadow object representing a read of a static variable in kernel |
| 1612 /// form. | 1611 /// form. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1630 if (target is KernelField && target._fieldNode != null) { | 1629 if (target is KernelField && target._fieldNode != null) { |
| 1631 collector.recordDependency(target._fieldNode); | 1630 collector.recordDependency(target._fieldNode); |
| 1632 } | 1631 } |
| 1633 } | 1632 } |
| 1634 | 1633 |
| 1635 @override | 1634 @override |
| 1636 DartType _inferExpression( | 1635 DartType _inferExpression( |
| 1637 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 1636 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 1638 typeNeeded = | 1637 typeNeeded = |
| 1639 inferrer.listener.staticGetEnter(this, typeContext) || typeNeeded; | 1638 inferrer.listener.staticGetEnter(this, typeContext) || typeNeeded; |
| 1640 if (inferrer.isDryRun) { | 1639 var target = this.target; |
| 1641 var target = this.target; | 1640 if (target is KernelField && target._fieldNode != null) { |
| 1642 if (target is KernelField && target._fieldNode != null) { | 1641 if (inferrer.isDryRun) { |
| 1643 inferrer.recordDryRunDependency(target._fieldNode); | 1642 inferrer.recordDryRunDependency(target._fieldNode); |
| 1644 } | 1643 } |
| 1644 if (TypeInferenceEngineImpl.fusedTopLevelInference && |
| 1645 inferrer.isTopLevel) { |
| 1646 inferrer.engine.inferFieldFused(target._fieldNode, inferrer.fieldNode); |
| 1647 } |
| 1645 } | 1648 } |
| 1646 var inferredType = typeNeeded ? target.getterType : null; | 1649 var inferredType = typeNeeded ? target.getterType : null; |
| 1647 inferrer.listener.staticGetExit(this, inferredType); | 1650 inferrer.listener.staticGetExit(this, inferredType); |
| 1648 return inferredType; | 1651 return inferredType; |
| 1649 } | 1652 } |
| 1650 } | 1653 } |
| 1651 | 1654 |
| 1652 /// Shadow object for [StaticInvocation]. | 1655 /// Shadow object for [StaticInvocation]. |
| 1653 class KernelStaticInvocation extends StaticInvocation | 1656 class KernelStaticInvocation extends StaticInvocation |
| 1654 implements KernelExpression { | 1657 implements KernelExpression { |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 FieldNode createFieldNode(KernelField field) { | 1891 FieldNode createFieldNode(KernelField field) { |
| 1889 FieldNode fieldNode = new FieldNode(this, field); | 1892 FieldNode fieldNode = new FieldNode(this, field); |
| 1890 field._fieldNode = fieldNode; | 1893 field._fieldNode = fieldNode; |
| 1891 return fieldNode; | 1894 return fieldNode; |
| 1892 } | 1895 } |
| 1893 | 1896 |
| 1894 @override | 1897 @override |
| 1895 KernelTypeInferrer createLocalTypeInferrer( | 1898 KernelTypeInferrer createLocalTypeInferrer( |
| 1896 Uri uri, TypeInferenceListener listener, InterfaceType thisType) { | 1899 Uri uri, TypeInferenceListener listener, InterfaceType thisType) { |
| 1897 return new KernelTypeInferrer._( | 1900 return new KernelTypeInferrer._( |
| 1898 this, uri.toString(), listener, false, thisType); | 1901 this, uri.toString(), listener, false, thisType, null); |
| 1899 } | 1902 } |
| 1900 | 1903 |
| 1901 @override | 1904 @override |
| 1902 KernelTypeInferrer createTopLevelTypeInferrer(TypeInferenceListener listener, | 1905 KernelTypeInferrer createTopLevelTypeInferrer(TypeInferenceListener listener, |
| 1903 InterfaceType thisType, KernelField field) { | 1906 InterfaceType thisType, KernelField field) { |
| 1904 return field._typeInferrer = | 1907 return field._typeInferrer = new KernelTypeInferrer._( |
| 1905 new KernelTypeInferrer._(this, field.fileUri, listener, true, thisType); | 1908 this, field.fileUri, listener, true, thisType, field._fieldNode); |
| 1906 } | 1909 } |
| 1907 | 1910 |
| 1908 @override | 1911 @override |
| 1909 int getFieldOffset(KernelField field) { | 1912 int getFieldOffset(KernelField field) { |
| 1910 return field.fileOffset; | 1913 return field.fileOffset; |
| 1911 } | 1914 } |
| 1912 | 1915 |
| 1913 @override | 1916 @override |
| 1914 KernelTypeInferrer getFieldTypeInferrer(KernelField field) { | 1917 KernelTypeInferrer getFieldTypeInferrer(KernelField field) { |
| 1915 return field._typeInferrer; | 1918 return field._typeInferrer; |
| 1916 } | 1919 } |
| 1917 | |
| 1918 @override | |
| 1919 bool isFieldInferred(KernelField field) { | |
| 1920 return field._isInferred; | |
| 1921 } | |
| 1922 | |
| 1923 @override | |
| 1924 void setFieldInferredType(KernelField field, DartType inferredType) { | |
| 1925 field._setInferredType(inferredType); | |
| 1926 } | |
| 1927 } | 1920 } |
| 1928 | 1921 |
| 1929 /// Concrete implementation of [TypeInferrer] specialized to work with kernel | 1922 /// Concrete implementation of [TypeInferrer] specialized to work with kernel |
| 1930 /// objects. | 1923 /// objects. |
| 1931 class KernelTypeInferrer extends TypeInferrerImpl { | 1924 class KernelTypeInferrer extends TypeInferrerImpl { |
| 1932 @override | 1925 @override |
| 1933 final typePromoter = new KernelTypePromoter(); | 1926 final typePromoter = new KernelTypePromoter(); |
| 1934 | 1927 |
| 1935 KernelTypeInferrer._(KernelTypeInferenceEngine engine, String uri, | 1928 KernelTypeInferrer._( |
| 1936 TypeInferenceListener listener, bool topLevel, InterfaceType thisType) | 1929 KernelTypeInferenceEngine engine, |
| 1937 : super(engine, uri, listener, topLevel, thisType); | 1930 String uri, |
| 1931 TypeInferenceListener listener, |
| 1932 bool topLevel, |
| 1933 InterfaceType thisType, |
| 1934 FieldNode fieldNode) |
| 1935 : super(engine, uri, listener, topLevel, thisType, fieldNode); |
| 1938 | 1936 |
| 1939 @override | 1937 @override |
| 1940 Expression getFieldInitializer(KernelField field) { | 1938 Expression getFieldInitializer(KernelField field) { |
| 1941 return field.initializer; | 1939 return field.initializer; |
| 1942 } | 1940 } |
| 1943 | 1941 |
| 1944 @override | 1942 @override |
| 1945 DartType inferExpression( | 1943 DartType inferExpression( |
| 1946 Expression expression, DartType typeContext, bool typeNeeded) { | 1944 Expression expression, DartType typeContext, bool typeNeeded) { |
| 1947 // When doing top level inference, we skip subexpressions whose type isn't | 1945 // When doing top level inference, we skip subexpressions whose type isn't |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2275 } | 2273 } |
| 2276 | 2274 |
| 2277 transformChildren(v) { | 2275 transformChildren(v) { |
| 2278 return internalError("Internal error: Unsupported operation."); | 2276 return internalError("Internal error: Unsupported operation."); |
| 2279 } | 2277 } |
| 2280 | 2278 |
| 2281 visitChildren(v) { | 2279 visitChildren(v) { |
| 2282 return internalError("Internal error: Unsupported operation."); | 2280 return internalError("Internal error: Unsupported operation."); |
| 2283 } | 2281 } |
| 2284 } | 2282 } |
| OLD | NEW |