| 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 086ed81f5e681f8eb714cb0f101be0a211c3cbde..d5580c04692ee43b96c0fff1e70e7c788d33b7b1 100644
|
| --- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
|
| +++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
|
| @@ -262,13 +262,6 @@ class FixProcessor {
|
| exitPosition = null;
|
| }
|
|
|
| - void _addFixToElement(FixKind kind, List args, Element element) {
|
| - Source source = element.source;
|
| - String file = source.fullName;
|
| - int fileStamp = element.context.getModificationStamp(source);
|
| - _addFix(kind, args, file: file, fileStamp: fileStamp);
|
| - }
|
| -
|
| void _addFix_boolInsteadOfBoolean() {
|
| SourceRange range = rf.rangeError(error);
|
| _addReplaceEdit(range, "bool");
|
| @@ -309,6 +302,140 @@ class FixProcessor {
|
| }
|
| }
|
|
|
| + void _addFix_createConstructor_insteadOfSyntheticDefault() {
|
| + TypeName typeName = null;
|
| + ConstructorName constructorName = null;
|
| + InstanceCreationExpression instanceCreation = null;
|
| + if (node is SimpleIdentifier) {
|
| + if (node.parent is TypeName) {
|
| + typeName = node.parent as TypeName;
|
| + if (typeName.name == node && typeName.parent is ConstructorName) {
|
| + constructorName = typeName.parent as ConstructorName;
|
| + // should be synthetic default constructor
|
| + {
|
| + ConstructorElement constructorElement =
|
| + constructorName.staticElement;
|
| + if (constructorElement == null ||
|
| + !constructorElement.isDefaultConstructor ||
|
| + !constructorElement.isSynthetic) {
|
| + return;
|
| + }
|
| + }
|
| + // prepare InstanceCreationExpression
|
| + if (constructorName.parent is InstanceCreationExpression) {
|
| + instanceCreation =
|
| + constructorName.parent as InstanceCreationExpression;
|
| + if (instanceCreation.constructorName != constructorName) {
|
| + return;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + // do we have enough information?
|
| + if (instanceCreation == null) {
|
| + return;
|
| + }
|
| + // prepare target
|
| + DartType targetType = typeName.type;
|
| + if (targetType is! InterfaceType) {
|
| + return;
|
| + }
|
| + ClassElement targetElement = targetType.element as ClassElement;
|
| + String targetFile = targetElement.source.fullName;
|
| + ClassDeclaration targetClass = targetElement.node;
|
| + _ConstructorLocation targetLocation =
|
| + _prepareNewConstructorLocation(targetClass);
|
| + // build method source
|
| + SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
|
| + {
|
| + String indent = " ";
|
| + sb.append(targetLocation.prefix);
|
| + sb.append(indent);
|
| + sb.append(targetElement.name);
|
| + _addFix_undefinedMethod_create_parameters(
|
| + sb,
|
| + instanceCreation.argumentList);
|
| + sb.append(") {${eol}${indent}}");
|
| + sb.append(targetLocation.suffix);
|
| + }
|
| + // insert source
|
| + _insertBuilder(sb);
|
| + // add proposal
|
| + _addFixToElement(
|
| + FixKind.CREATE_CONSTRUCTOR,
|
| + [constructorName],
|
| + targetElement);
|
| + }
|
| +
|
| + void _addFix_createConstructor_named() {
|
| + SimpleIdentifier name = null;
|
| + ConstructorName constructorName = null;
|
| + InstanceCreationExpression instanceCreation = null;
|
| + if (node is SimpleIdentifier) {
|
| + // name
|
| + name = node as SimpleIdentifier;
|
| + if (name.parent is ConstructorName) {
|
| + constructorName = name.parent as ConstructorName;
|
| + if (constructorName.name == name) {
|
| + // Type.name
|
| + if (constructorName.parent is InstanceCreationExpression) {
|
| + instanceCreation =
|
| + constructorName.parent as InstanceCreationExpression;
|
| + // new Type.name()
|
| + if (instanceCreation.constructorName != constructorName) {
|
| + return;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + // do we have enough information?
|
| + if (instanceCreation == null) {
|
| + return;
|
| + }
|
| + // prepare target interface type
|
| + DartType targetType = constructorName.type.type;
|
| + if (targetType is! InterfaceType) {
|
| + return;
|
| + }
|
| + ClassElement targetElement = targetType.element as ClassElement;
|
| + String targetFile = targetElement.source.fullName;
|
| + ClassDeclaration targetClass = targetElement.node;
|
| + _ConstructorLocation targetLocation =
|
| + _prepareNewConstructorLocation(targetClass);
|
| + // build method source
|
| + SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
|
| + {
|
| + String indent = " ";
|
| + sb.append(targetLocation.prefix);
|
| + sb.append(indent);
|
| + sb.append(targetElement.name);
|
| + sb.append(".");
|
| + // append name
|
| + {
|
| + sb.startPosition("NAME");
|
| + sb.append(name.name);
|
| + sb.endPosition();
|
| + }
|
| + _addFix_undefinedMethod_create_parameters(
|
| + sb,
|
| + instanceCreation.argumentList);
|
| + sb.append(") {${eol}${indent}}");
|
| + sb.append(targetLocation.suffix);
|
| + }
|
| + // insert source
|
| + _insertBuilder(sb);
|
| + if (targetFile == file) {
|
| + _addLinkedPosition("NAME", rf.rangeNode(name));
|
| + }
|
| + // add proposal
|
| + _addFixToElement(
|
| + FixKind.CREATE_CONSTRUCTOR,
|
| + [constructorName],
|
| + targetElement);
|
| + }
|
| +
|
| void _addFix_createConstructorSuperExplicit() {
|
| ConstructorDeclaration targetConstructor =
|
| node.parent as ConstructorDeclaration;
|
| @@ -448,140 +575,6 @@ class FixProcessor {
|
| }
|
| }
|
|
|
| - void _addFix_createConstructor_insteadOfSyntheticDefault() {
|
| - TypeName typeName = null;
|
| - ConstructorName constructorName = null;
|
| - InstanceCreationExpression instanceCreation = null;
|
| - if (node is SimpleIdentifier) {
|
| - if (node.parent is TypeName) {
|
| - typeName = node.parent as TypeName;
|
| - if (typeName.name == node && typeName.parent is ConstructorName) {
|
| - constructorName = typeName.parent as ConstructorName;
|
| - // should be synthetic default constructor
|
| - {
|
| - ConstructorElement constructorElement =
|
| - constructorName.staticElement;
|
| - if (constructorElement == null ||
|
| - !constructorElement.isDefaultConstructor ||
|
| - !constructorElement.isSynthetic) {
|
| - return;
|
| - }
|
| - }
|
| - // prepare InstanceCreationExpression
|
| - if (constructorName.parent is InstanceCreationExpression) {
|
| - instanceCreation =
|
| - constructorName.parent as InstanceCreationExpression;
|
| - if (instanceCreation.constructorName != constructorName) {
|
| - return;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| - // do we have enough information?
|
| - if (instanceCreation == null) {
|
| - return;
|
| - }
|
| - // prepare target
|
| - DartType targetType = typeName.type;
|
| - if (targetType is! InterfaceType) {
|
| - return;
|
| - }
|
| - ClassElement targetElement = targetType.element as ClassElement;
|
| - String targetFile = targetElement.source.fullName;
|
| - ClassDeclaration targetClass = targetElement.node;
|
| - _ConstructorLocation targetLocation =
|
| - _prepareNewConstructorLocation(targetClass);
|
| - // build method source
|
| - SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
|
| - {
|
| - String indent = " ";
|
| - sb.append(targetLocation.prefix);
|
| - sb.append(indent);
|
| - sb.append(targetElement.name);
|
| - _addFix_undefinedMethod_create_parameters(
|
| - sb,
|
| - instanceCreation.argumentList);
|
| - sb.append(") {${eol}${indent}}");
|
| - sb.append(targetLocation.suffix);
|
| - }
|
| - // insert source
|
| - _insertBuilder(sb);
|
| - // add proposal
|
| - _addFixToElement(
|
| - FixKind.CREATE_CONSTRUCTOR,
|
| - [constructorName],
|
| - targetElement);
|
| - }
|
| -
|
| - void _addFix_createConstructor_named() {
|
| - SimpleIdentifier name = null;
|
| - ConstructorName constructorName = null;
|
| - InstanceCreationExpression instanceCreation = null;
|
| - if (node is SimpleIdentifier) {
|
| - // name
|
| - name = node as SimpleIdentifier;
|
| - if (name.parent is ConstructorName) {
|
| - constructorName = name.parent as ConstructorName;
|
| - if (constructorName.name == name) {
|
| - // Type.name
|
| - if (constructorName.parent is InstanceCreationExpression) {
|
| - instanceCreation =
|
| - constructorName.parent as InstanceCreationExpression;
|
| - // new Type.name()
|
| - if (instanceCreation.constructorName != constructorName) {
|
| - return;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| - // do we have enough information?
|
| - if (instanceCreation == null) {
|
| - return;
|
| - }
|
| - // prepare target interface type
|
| - DartType targetType = constructorName.type.type;
|
| - if (targetType is! InterfaceType) {
|
| - return;
|
| - }
|
| - ClassElement targetElement = targetType.element as ClassElement;
|
| - String targetFile = targetElement.source.fullName;
|
| - ClassDeclaration targetClass = targetElement.node;
|
| - _ConstructorLocation targetLocation =
|
| - _prepareNewConstructorLocation(targetClass);
|
| - // build method source
|
| - SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
|
| - {
|
| - String indent = " ";
|
| - sb.append(targetLocation.prefix);
|
| - sb.append(indent);
|
| - sb.append(targetElement.name);
|
| - sb.append(".");
|
| - // append name
|
| - {
|
| - sb.startPosition("NAME");
|
| - sb.append(name.name);
|
| - sb.endPosition();
|
| - }
|
| - _addFix_undefinedMethod_create_parameters(
|
| - sb,
|
| - instanceCreation.argumentList);
|
| - sb.append(") {${eol}${indent}}");
|
| - sb.append(targetLocation.suffix);
|
| - }
|
| - // insert source
|
| - _insertBuilder(sb);
|
| - if (targetFile == file) {
|
| - _addLinkedPosition("NAME", rf.rangeNode(name));
|
| - }
|
| - // add proposal
|
| - _addFixToElement(
|
| - FixKind.CREATE_CONSTRUCTOR,
|
| - [constructorName],
|
| - targetElement);
|
| - }
|
| -
|
| void _addFix_createField() {
|
| SimpleIdentifier nameNode = node;
|
| String name = nameNode.name;
|
| @@ -1539,6 +1532,13 @@ class FixProcessor {
|
| }
|
| }
|
|
|
| + void _addFixToElement(FixKind kind, List args, Element element) {
|
| + Source source = element.source;
|
| + String file = source.fullName;
|
| + int fileStamp = element.context.getModificationStamp(source);
|
| + _addFix(kind, args, file: file, fileStamp: fileStamp);
|
| + }
|
| +
|
| /**
|
| * Adds a new [Edit] to [edits].
|
| */
|
| @@ -1709,14 +1709,6 @@ class FixProcessor {
|
| edits.add(edit);
|
| }
|
|
|
| - void _appendParameterSource(SourceBuilder sb, DartType type, String name) {
|
| - Set<LibraryElement> librariesToImport = new Set<LibraryElement>();
|
| - // TODO(scheglov) use librariesToImport
|
| - String parameterSource =
|
| - utils.getParameterSource(type, name, librariesToImport);
|
| - sb.append(parameterSource);
|
| - }
|
| -
|
| void _appendParameters(SourceBuilder sb, List<ParameterElement> parameters) {
|
| sb.append("(");
|
| bool firstParameter = true;
|
| @@ -1765,6 +1757,14 @@ class FixProcessor {
|
| sb.append(")");
|
| }
|
|
|
| + void _appendParameterSource(SourceBuilder sb, DartType type, String name) {
|
| + Set<LibraryElement> librariesToImport = new Set<LibraryElement>();
|
| + // TODO(scheglov) use librariesToImport
|
| + String parameterSource =
|
| + utils.getParameterSource(type, name, librariesToImport);
|
| + sb.append(parameterSource);
|
| + }
|
| +
|
| void _appendType(SourceBuilder sb, DartType type, [String groupId]) {
|
| if (type != null && !type.isDynamic) {
|
| Set<LibraryElement> librariesToImport = new Set<LibraryElement>();
|
| @@ -1829,25 +1829,6 @@ class FixProcessor {
|
| }
|
|
|
| /**
|
| - * Returns `true` if [node] is in static context.
|
| - */
|
| - bool _inStaticContext() {
|
| - // constructor initializer cannot reference "this"
|
| - if (node.getAncestor((node) => node is ConstructorInitializer) != null) {
|
| - return true;
|
| - }
|
| - // field initializer cannot reference "this"
|
| - if (node.getAncestor((node) => node is FieldDeclaration) != null) {
|
| - return true;
|
| - }
|
| - // static method
|
| - MethodDeclaration method = node.getAncestor((node) {
|
| - return node is MethodDeclaration;
|
| - });
|
| - return method != null && method.isStatic;
|
| - }
|
| -
|
| - /**
|
| * Returns an expected [DartType] of [expression], may be `null` if cannot be
|
| * inferred.
|
| */
|
| @@ -1991,6 +1972,25 @@ class FixProcessor {
|
| });
|
| }
|
|
|
| + /**
|
| + * Returns `true` if [node] is in static context.
|
| + */
|
| + bool _inStaticContext() {
|
| + // constructor initializer cannot reference "this"
|
| + if (node.getAncestor((node) => node is ConstructorInitializer) != null) {
|
| + return true;
|
| + }
|
| + // field initializer cannot reference "this"
|
| + if (node.getAncestor((node) => node is FieldDeclaration) != null) {
|
| + return true;
|
| + }
|
| + // static method
|
| + MethodDeclaration method = node.getAncestor((node) {
|
| + return node is MethodDeclaration;
|
| + });
|
| + return method != null && method.isStatic;
|
| + }
|
| +
|
| _ConstructorLocation
|
| _prepareNewConstructorLocation(ClassDeclaration classDeclaration) {
|
| List<ClassMember> members = classDeclaration.members;
|
|
|