@@ -332,6 +332,7 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType> {
332332 @override
333333 DecoratedType visitConstructorDeclaration (ConstructorDeclaration node) {
334334 _handleExecutableDeclaration (
335+ node,
335336 node.declaredElement,
336337 node.metadata,
337338 null ,
@@ -552,7 +553,7 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType> {
552553 if (node.typeParameters != null ) {
553554 _unimplemented (node, 'Generic method' );
554555 }
555- _handleExecutableDeclaration (node.declaredElement, node.metadata,
556+ _handleExecutableDeclaration (node, node .declaredElement, node.metadata,
556557 node.returnType, node.parameters, null , node.body, null );
557558 return null ;
558559 }
@@ -861,16 +862,17 @@ $stackTrace''');
861862 }
862863
863864 /// Creates the necessary constraint(s) for an assignment from [source] to
864- /// [destination] . [expressionChecks] tracks checks that might have to be
865- /// done on the type of an expression. [hard] indicates whether a hard edge
866- /// should be created.
867- void _checkAssignment (ExpressionChecks expressionChecks,
865+ /// [destination] . [origin] should be used as the origin for any edges
866+ /// created. [hard] indicates whether a hard edge should be created.
867+ void _checkAssignment (EdgeOrigin origin,
868868 {@required DecoratedType source,
869869 @required DecoratedType destination,
870870 @required bool hard}) {
871- var edge = _graph.connect (source.node, destination.node, expressionChecks ,
871+ var edge = _graph.connect (source.node, destination.node, origin ,
872872 guards: _guards, hard: hard);
873- expressionChecks? .edges? .add (edge);
873+ if (origin is ExpressionChecks ) {
874+ origin.edges.add (edge);
875+ }
874876 // TODO(paulberry): generalize this.
875877 if ((_isSimple (source) || destination.type.isObject) &&
876878 _isSimple (destination)) {
@@ -880,14 +882,14 @@ $stackTrace''');
880882 source.type.element == destination.type.element) {
881883 assert (source.typeArguments.length == destination.typeArguments.length);
882884 for (int i = 0 ; i < source.typeArguments.length; i++ ) {
883- _checkAssignment (expressionChecks ,
885+ _checkAssignment (origin ,
884886 source: source.typeArguments[i],
885887 destination: destination.typeArguments[i],
886888 hard: false );
887889 }
888890 } else if (source.type is FunctionType &&
889891 destination.type is FunctionType ) {
890- _checkAssignment (expressionChecks ,
892+ _checkAssignment (origin ,
891893 source: source.returnType,
892894 destination: destination.returnType,
893895 hard: hard);
@@ -900,14 +902,14 @@ $stackTrace''');
900902 i < destination.positionalParameters.length;
901903 i++ ) {
902904 // Note: source and destination are swapped due to contravariance.
903- _checkAssignment (expressionChecks ,
905+ _checkAssignment (origin ,
904906 source: destination.positionalParameters[i],
905907 destination: source.positionalParameters[i],
906908 hard: hard);
907909 }
908910 for (var entry in destination.namedParameters.entries) {
909911 // Note: source and destination are swapped due to contravariance.
910- _checkAssignment (expressionChecks ,
912+ _checkAssignment (origin ,
911913 source: entry.value,
912914 destination: source.namedParameters[entry.key],
913915 hard: hard);
@@ -971,6 +973,7 @@ $stackTrace''');
971973 }
972974
973975 void _handleExecutableDeclaration (
976+ AstNode node,
974977 ExecutableElement declaredElement,
975978 NodeList <Annotation > metadata,
976979 TypeAnnotation returnType,
@@ -992,6 +995,7 @@ $stackTrace''');
992995 }
993996 if (declaredElement is ! ConstructorElement ) {
994997 var classElement = declaredElement.enclosingElement as ClassElement ;
998+ var origin = InheritanceOrigin (_source, node.offset);
995999 for (var overridden in _inheritanceManager.getOverridden (
9961000 classElement.type,
9971001 Name (classElement.library.source.uri, declaredElement.name)) ??
@@ -1005,11 +1009,61 @@ $stackTrace''');
10051009 var decoratedSupertype = _decoratedClassHierarchy
10061010 .getDecoratedSupertype (classElement, overriddenClass);
10071011 var substitution = decoratedSupertype.asSubstitution;
1008- _checkAssignment (null ,
1009- source: _currentFunctionType,
1010- destination:
1011- decoratedOverriddenFunctionType.substitute (substitution),
1012- hard: true );
1012+ var overriddenFunctionType =
1013+ decoratedOverriddenFunctionType.substitute (substitution);
1014+ if (returnType == null ) {
1015+ _unionDecoratedTypes (_currentFunctionType.returnType,
1016+ overriddenFunctionType.returnType, origin);
1017+ } else {
1018+ _checkAssignment (origin,
1019+ source: _currentFunctionType.returnType,
1020+ destination: overriddenFunctionType.returnType,
1021+ hard: true );
1022+ }
1023+ if (parameters != null ) {
1024+ int positionalParameterCount = 0 ;
1025+ for (var parameter in parameters.parameters) {
1026+ NormalFormalParameter normalParameter;
1027+ if (parameter is NormalFormalParameter ) {
1028+ normalParameter = parameter;
1029+ } else {
1030+ normalParameter =
1031+ (parameter as DefaultFormalParameter ).parameter;
1032+ }
1033+ DecoratedType currentParameterType;
1034+ DecoratedType overriddenParameterType;
1035+ if (parameter.isNamed) {
1036+ var name = normalParameter.identifier.name;
1037+ currentParameterType =
1038+ _currentFunctionType.namedParameters[name];
1039+ overriddenParameterType =
1040+ overriddenFunctionType.namedParameters[name];
1041+ } else {
1042+ if (positionalParameterCount <
1043+ _currentFunctionType.positionalParameters.length) {
1044+ currentParameterType = _currentFunctionType
1045+ .positionalParameters[positionalParameterCount];
1046+ }
1047+ if (positionalParameterCount <
1048+ overriddenFunctionType.positionalParameters.length) {
1049+ overriddenParameterType = overriddenFunctionType
1050+ .positionalParameters[positionalParameterCount];
1051+ }
1052+ positionalParameterCount++ ;
1053+ }
1054+ if (overriddenParameterType != null ) {
1055+ if (_isUntypedParameter (normalParameter)) {
1056+ _unionDecoratedTypes (
1057+ overriddenParameterType, currentParameterType, origin);
1058+ } else {
1059+ _checkAssignment (origin,
1060+ source: overriddenParameterType,
1061+ destination: currentParameterType,
1062+ hard: true );
1063+ }
1064+ }
1065+ }
1066+ }
10131067 }
10141068 }
10151069 } finally {
@@ -1157,6 +1211,16 @@ $stackTrace''');
11571211 return true ;
11581212 }
11591213
1214+ bool _isUntypedParameter (NormalFormalParameter parameter) {
1215+ if (parameter is SimpleFormalParameter ) {
1216+ return parameter.type == null ;
1217+ } else if (parameter is FieldFormalParameter ) {
1218+ return parameter.type == null ;
1219+ } else {
1220+ return false ;
1221+ }
1222+ }
1223+
11601224 bool _isVariableOrParameterReference (Expression expression) {
11611225 expression = expression.unParenthesized;
11621226 if (expression is SimpleIdentifier ) {
0 commit comments