@@ -8,6 +8,7 @@ import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
88import  'package:analyzer/dart/ast/ast.dart' ;
99import  'package:analyzer/dart/element/type.dart' ;
1010import  'package:analyzer/src/dart/ast/extensions.dart' ;
11+ import  'package:analyzer/src/utilities/dot_shorthands.dart' ;
1112import  'package:analyzer_plugin/utilities/assist/assist.dart' ;
1213import  'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart' ;
1314import  'package:analyzer_plugin/utilities/fixes/fixes.dart' ;
@@ -56,36 +57,42 @@ class ReplaceWithVar extends ResolvedCorrectionProducer {
5657        return ;
5758      }
5859      var  initializer =  variables[0 ].initializer;
59-       String ?  typeArgumentsText;
60-       int ?  typeArgumentsOffset;
61-       if  (type is  NamedType ) {
60+       String ?  insertionText;
61+       int ?  insertionOffset;
62+       if  (initializer !=  null  &&  isDotShorthand (initializer)) {
63+         // Inserts the type before the dot shorthand (e.g. `E.a` where type is 
64+         // `E`) because we erase the required context type when we replace the 
65+         // declared type with `var`. 
66+         insertionText =  utils.getNodeText (type);
67+         insertionOffset =  initializer.beginToken.offset;
68+       } else  if  (type is  NamedType ) {
6269        var  typeArguments =  type.typeArguments;
6370        if  (typeArguments !=  null ) {
6471          if  (initializer is  CascadeExpression ) {
6572            initializer =  initializer.target;
6673          }
6774          if  (initializer is  TypedLiteral ) {
6875            if  (initializer.typeArguments ==  null ) {
69-               typeArgumentsText  =  utils.getNodeText (typeArguments);
76+               insertionText  =  utils.getNodeText (typeArguments);
7077              if  (initializer is  ListLiteral ) {
71-                 typeArgumentsOffset  =  initializer.leftBracket.offset;
78+                 insertionOffset  =  initializer.leftBracket.offset;
7279              } else  if  (initializer is  SetOrMapLiteral ) {
73-                 typeArgumentsOffset  =  initializer.leftBracket.offset;
80+                 insertionOffset  =  initializer.leftBracket.offset;
7481              } else  {
7582                throw  StateError ('Unhandled subclass of TypedLiteral' );
7683              }
7784            }
7885          } else  if  (initializer is  InstanceCreationExpression ) {
7986            if  (initializer.constructorName.type.typeArguments ==  null ) {
80-               typeArgumentsText  =  utils.getNodeText (typeArguments);
81-               typeArgumentsOffset  =  initializer.constructorName.type.end;
87+               insertionText  =  utils.getNodeText (typeArguments);
88+               insertionOffset  =  initializer.constructorName.type.end;
8289            }
8390          }
8491        }
8592      }
8693      if  (initializer is  SetOrMapLiteral  && 
8794          initializer.typeArguments ==  null  && 
88-           typeArgumentsText  ==  null ) {
95+           insertionText  ==  null ) {
8996        // This is to prevent the fix from converting a valid map or set literal 
9097        // into an ambiguous literal. We could apply this in more places 
9198        // by examining the elements of the collection. 
@@ -94,8 +101,8 @@ class ReplaceWithVar extends ResolvedCorrectionProducer {
94101      await  builder.addDartFileEdit (file, (builder) {
95102        builder.addSimpleReplacement (range.node (type), 'var' );
96103
97-         if  (typeArgumentsText  !=  null  &&  typeArgumentsOffset  !=  null ) {
98-           builder.addSimpleInsertion (typeArgumentsOffset, typeArgumentsText );
104+         if  (insertionText  !=  null  &&  insertionOffset  !=  null ) {
105+           builder.addSimpleInsertion (insertionOffset, insertionText );
99106        }
100107      });
101108    } else  if  (parent is  DeclaredIdentifier  && 
@@ -105,15 +112,21 @@ class ReplaceWithVar extends ResolvedCorrectionProducer {
105112        return ;
106113      }
107114
108-       String ?  typeArgumentsText;
109-       int ?  typeArgumentsOffset;
110-       if  (type is  NamedType ) {
115+       String ?  insertionText;
116+       int ?  insertionOffset;
117+       var  iterable =  grandparent.iterable;
118+       if  (hasDependentDotShorthand (iterable) &&  iterable is  TypedLiteral ) {
119+         // If there's a dependent shorthand in the literal, we need to 
120+         // insert explicit type arguments to ensure we have an appropriate 
121+         // context type to resolve the dot shorthand. 
122+         insertionText =  '<${utils .getNodeText (type )}>' ;
123+         insertionOffset =  iterable.beginToken.offset;
124+       } else  if  (type is  NamedType ) {
111125        var  typeArguments =  type.typeArguments;
112126        if  (typeArguments !=  null ) {
113-           var  iterable =  grandparent.iterable;
114127          if  (iterable is  TypedLiteral  &&  iterable.typeArguments ==  null ) {
115-             typeArgumentsText  =  utils.getNodeText (typeArguments);
116-             typeArgumentsOffset  =  iterable.offset;
128+             insertionText  =  utils.getNodeText (typeArguments);
129+             insertionOffset  =  iterable.offset;
117130          }
118131        }
119132      }
@@ -123,8 +136,8 @@ class ReplaceWithVar extends ResolvedCorrectionProducer {
123136        } else  {
124137          builder.addSimpleReplacement (range.node (type), 'var' );
125138        }
126-         if  (typeArgumentsText  !=  null  &&  typeArgumentsOffset  !=  null ) {
127-           builder.addSimpleInsertion (typeArgumentsOffset, typeArgumentsText );
139+         if  (insertionText  !=  null  &&  insertionOffset  !=  null ) {
140+           builder.addSimpleInsertion (insertionOffset, insertionText );
128141        }
129142      });
130143    }
0 commit comments