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

Unified Diff: pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Issue 610323005: Issue 19670. Extend the 'Create Field' Quick Fix to support getter context. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/correction/util.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/lib/src/services/correction/fix_internal.dart
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index f934e07ef093264aba95f0d97aa8479f24afb411..6257db2097964c635d6bb7633733074648f859c4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -198,10 +198,10 @@ class FixProcessor {
_addFix_undefinedClass_useSimilar();
}
if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) {
+ _addFix_createField();
_addFix_createFunction_forFunctionType();
_addFix_importLibrary_withType();
_addFix_importLibrary_withTopLevelVariable();
- _addFix_undefinedSetter_createField();
}
if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) {
_addFix_useStaticAccess_method();
@@ -220,6 +220,7 @@ class FixProcessor {
_addFix_undefinedFunction_create();
}
if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) {
+ _addFix_createField();
_addFix_createFunction_forFunctionType();
}
if (errorCode == HintCode.UNDEFINED_METHOD ||
@@ -229,7 +230,7 @@ class FixProcessor {
_addFix_undefinedFunction_create();
}
if (errorCode == StaticTypeWarningCode.UNDEFINED_SETTER) {
- _addFix_undefinedSetter_createField();
+ _addFix_createField();
}
// done
return fixes;
@@ -579,6 +580,82 @@ class FixProcessor {
targetElement);
}
+ void _addFix_createField() {
+ SimpleIdentifier nameNode = node;
+ String name = nameNode.name;
+ // prepare target Expression
+ Expression target;
+ {
+ AstNode nameParent = nameNode.parent;
+ if (nameParent is PrefixedIdentifier) {
+ target = nameParent.prefix;
+ }
+ if (nameParent is PropertyAccess) {
+ target = nameParent.realTarget;
+ }
+ }
+ // prepare target ClassElement
+ bool staticModifier = false;
+ ClassElement targetClassElement;
+ if (target != null) {
+ // prepare target interface type
+ DartType targetType = target.bestType;
+ if (targetType is! InterfaceType) {
+ return;
+ }
+ targetClassElement = targetType.element;
+ // maybe static
+ if (target is Identifier) {
+ Identifier targetIdentifier = target;
+ Element targetElement = targetIdentifier.staticElement;
+ staticModifier = targetElement.kind == ElementKind.CLASS;
+ }
+ } else {
+ targetClassElement = getEnclosingClassElement(node);
+ if (targetClassElement == null) {
+ return;
+ }
+ staticModifier = _inStaticContext();
+ }
+ // prepare location
+ ClassDeclaration targetClassNode = targetClassElement.node;
+ _FieldLocation targetLocation = _prepareNewFieldLocation(targetClassNode);
+ // build method source
+ String targetFile = targetClassElement.source.fullName;
+ SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
+ {
+ sb.append(targetLocation.prefix);
+ // maybe "static"
+ if (staticModifier) {
+ sb.append('static ');
+ }
+ // append type
+ Expression fieldTypeNode = climbPropertyAccess(nameNode);
+ DartType fieldType = _inferUndefinedExpressionType(fieldTypeNode);
+ if (fieldType != null) {
+ _appendType(sb, fieldType, 'TYPE');
+ } else {
+ sb.append('var ');
+ }
+ // append name
+ {
+ sb.startPosition('NAME');
+ sb.append(name);
+ sb.endPosition();
+ }
+ sb.append(';');
+ sb.append(targetLocation.suffix);
+ }
+ // insert source
+ _insertBuilder(sb);
+ // add linked positions
+ if (targetFile == file) {
+ _addLinkedPosition3('NAME', sb, rf.rangeNode(node));
+ }
+ // add proposal
+ _addFixToElement(FixKind.CREATE_FIELD, [name], targetClassElement);
+ }
+
void _addFix_createFunction_forFunctionType() {
if (node is SimpleIdentifier) {
SimpleIdentifier nameNode = node as SimpleIdentifier;
@@ -1153,7 +1230,7 @@ class FixProcessor {
sb.append(sourcePrefix);
// append return type
{
- DartType type = _inferReturnType(invocation);
+ DartType type = _inferUndefinedExpressionType(invocation);
_appendType(sb, type, 'RETURN_TYPE');
}
// append name
@@ -1254,7 +1331,10 @@ class FixProcessor {
sb.append("static ");
}
// append return type
- _appendType(sb, _inferReturnType(invocation), 'RETURN_TYPE');
+ _appendType(
+ sb,
+ _inferUndefinedExpressionType(invocation),
+ 'RETURN_TYPE');
// append name
{
sb.startPosition("NAME");
@@ -1345,76 +1425,6 @@ class FixProcessor {
}
}
- void _addFix_undefinedSetter_createField() {
- // prepare enclosing AssignmentExpression
- AssignmentExpression assignment = node.getAncestor((node) {
- return node is AssignmentExpression;
- });
- if (assignment == null) {
- return;
- }
- // prepare name
- SimpleIdentifier nameNode = node;
- String name = nameNode.name;
- // prepare target class
- bool staticModifier = false;
- ClassElement targetClassElement;
- AstNode nameParent = nameNode.parent;
- if (nameParent is PrefixedIdentifier) {
- Expression target = nameParent.prefix;
- // prepare target interface type
- DartType targetType = target.bestType;
- if (targetType is! InterfaceType) {
- return;
- }
- targetClassElement = targetType.element as ClassElement;
- // may be static
- if (target is Identifier) {
- staticModifier = target.bestElement.kind == ElementKind.CLASS;
- }
- } else {
- ClassDeclaration target = node.getAncestor((node) {
- return node is ClassDeclaration;
- });
- if (target == null) {
- return;
- }
- targetClassElement = target.element;
- staticModifier = _inStaticContext();
- }
- // prepare location
- ClassDeclaration targetClassNode = targetClassElement.node;
- _FieldLocation targetLocation = _prepareNewFieldLocation(targetClassNode);
- // build method source
- String targetFile = targetClassElement.source.fullName;
- SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
- {
- sb.append(targetLocation.prefix);
- // maybe "static"
- if (staticModifier) {
- sb.append('static ');
- }
- // append return type
- _appendType(sb, assignment.rightHandSide.bestType, 'TYPE');
- // append name
- {
- sb.startPosition('NAME');
- sb.append(name);
- sb.endPosition();
- }
- sb.append(';');
- sb.append(targetLocation.suffix);
- }
- // insert source
- _insertBuilder(sb);
- // add linked positions
- if (targetFile == file) {
- _addLinkedPosition3('NAME', sb, rf.rangeNode(node));
- }
- // add proposal
- _addFixToElement(FixKind.CREATE_FIELD, [name], targetClassElement);
- }
-
void _addFix_useEffectiveIntegerDivision() {
for (AstNode n = node; n != null; n = n.parent) {
if (n is MethodInvocation &&
@@ -1774,33 +1784,46 @@ class FixProcessor {
}
/**
- * Returns a possible return [Type], may be `null` if cannot be inferred.
+ * Returns an expected [DartType] of [expression], may be `null` if cannot be
+ * inferred.
*/
- DartType _inferReturnType(MethodInvocation invocation) {
- AstNode parent = invocation.parent;
+ DartType _inferUndefinedExpressionType(Expression expression) {
+ AstNode parent = expression.parent;
// myFunction();
if (parent is ExpressionStatement) {
- return VoidTypeImpl.instance;
+ if (expression is MethodInvocation) {
+ return VoidTypeImpl.instance;
+ }
}
// return myFunction();
if (parent is ReturnStatement) {
- ExecutableElement executable = getEnclosingExecutableElement(invocation);
+ ExecutableElement executable = getEnclosingExecutableElement(expression);
return executable != null ? executable.returnType : null;
}
// int v = myFunction();
if (parent is VariableDeclaration) {
VariableDeclaration variableDeclaration = parent;
- if (variableDeclaration.initializer == invocation) {
+ if (variableDeclaration.initializer == expression) {
VariableElement variableElement = variableDeclaration.element;
if (variableElement != null) {
return variableElement.type;
}
}
}
+ // myField = 42;
+ if (parent is AssignmentExpression) {
+ AssignmentExpression assignment = parent;
+ if (assignment.leftHandSide == expression) {
+ Expression rhs = assignment.rightHandSide;
+ if (rhs != null) {
+ return rhs.bestType;
+ }
+ }
+ }
// v = myFunction();
if (parent is AssignmentExpression) {
AssignmentExpression assignment = parent;
- if (assignment.rightHandSide == invocation) {
+ if (assignment.rightHandSide == expression) {
if (assignment.operator.type == TokenType.EQ) {
// v = myFunction();
Expression lhs = assignment.leftHandSide;
@@ -1824,7 +1847,7 @@ class FixProcessor {
BinaryExpression binary = parent;
MethodElement method = binary.bestElement;
if (method != null) {
- if (binary.rightOperand == invocation) {
+ if (binary.rightOperand == expression) {
List<ParameterElement> parameters = method.parameters;
return parameters.length == 1 ? parameters[0].type : null;
}
@@ -1832,7 +1855,7 @@ class FixProcessor {
}
// foo( myFunction() );
if (parent is ArgumentList) {
- ParameterElement parameter = invocation.bestParameterElement;
+ ParameterElement parameter = expression.bestParameterElement;
return parameter != null ? parameter.type : null;
}
// bool
@@ -1840,28 +1863,28 @@ class FixProcessor {
// assert( myFunction() );
if (parent is AssertStatement) {
AssertStatement statement = parent;
- if (statement.condition == invocation) {
+ if (statement.condition == expression) {
return coreTypeBool;
}
}
// if ( myFunction() ) {}
if (parent is IfStatement) {
IfStatement statement = parent;
- if (statement.condition == invocation) {
+ if (statement.condition == expression) {
return coreTypeBool;
}
}
// while ( myFunction() ) {}
if (parent is WhileStatement) {
WhileStatement statement = parent;
- if (statement.condition == invocation) {
+ if (statement.condition == expression) {
return coreTypeBool;
}
}
// do {} while ( myFunction() );
if (parent is DoStatement) {
DoStatement statement = parent;
- if (statement.condition == invocation) {
+ if (statement.condition == expression) {
return coreTypeBool;
}
}
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/correction/util.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698