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

Unified Diff: pkg/analysis_services/lib/src/correction/fix.dart

Issue 484733003: Import analysis_services.dart into analysis_server.dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 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
Index: pkg/analysis_services/lib/src/correction/fix.dart
diff --git a/pkg/analysis_services/lib/src/correction/fix.dart b/pkg/analysis_services/lib/src/correction/fix.dart
deleted file mode 100644
index dfaac9c7436e93129fe5227b905c5b63c92c3cf8..0000000000000000000000000000000000000000
--- a/pkg/analysis_services/lib/src/correction/fix.dart
+++ /dev/null
@@ -1,1912 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.correction.fix;
-
-import 'dart:collection';
-
-import 'package:analysis_services/correction/change.dart';
-import 'package:analysis_services/correction/fix.dart';
-import 'package:analysis_services/search/hierarchy.dart';
-import 'package:analysis_services/search/search_engine.dart';
-import 'package:analysis_services/src/correction/levenshtein.dart';
-import 'package:analysis_services/src/correction/name_suggestion.dart';
-import 'package:analysis_services/src/correction/source_buffer.dart';
-import 'package:analysis_services/src/correction/source_range.dart' as rf;
-import 'package:analysis_services/src/correction/strings.dart';
-import 'package:analysis_services/src/correction/util.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:path/path.dart';
-
-
-/**
- * A predicate is a one-argument function that returns a boolean value.
- */
-typedef bool Predicate<E>(E argument);
-
-
-/**
- * The computer for Dart fixes.
- */
-class FixProcessor {
- static const int MAX_LEVENSHTEIN_DISTANCE = 3;
-
- final SearchEngine searchEngine;
- final Source source;
- final String file;
- final CompilationUnit unit;
- final AnalysisError error;
- CompilationUnitElement unitElement;
- Source unitSource;
- LibraryElement unitLibraryElement;
- String unitLibraryFile;
- String unitLibraryFolder;
-
- final List<Edit> edits = <Edit>[];
- final Map<String, LinkedEditGroup> linkedPositionGroups = <String,
- LinkedEditGroup>{};
- Position exitPosition = null;
- final List<Fix> fixes = <Fix>[];
-
- CorrectionUtils utils;
- int errorOffset;
- int errorLength;
- int errorEnd;
- AstNode node;
- AstNode coveredNode;
-
- FixProcessor(this.searchEngine, this.source, this.file, this.unit, this.error)
- {
- unitElement = unit.element;
- unitSource = unitElement.source;
- unitLibraryElement = unitElement.library;
- unitLibraryFile = unitLibraryElement.source.fullName;
- unitLibraryFolder = dirname(unitLibraryFile);
- }
-
- DartType get coreTypeBool => _getCoreType("bool");
-
- /**
- * Returns the EOL to use for this [CompilationUnit].
- */
- String get eol => utils.endOfLine;
-
- List<Fix> compute() {
- utils = new CorrectionUtils(unit);
- errorOffset = error.offset;
- errorLength = error.length;
- errorEnd = errorOffset + errorLength;
- node = new NodeLocator.con1(errorOffset).searchWithin(unit);
- coveredNode = new NodeLocator.con2(
- errorOffset,
- errorOffset + errorLength).searchWithin(unit);
- // analyze ErrorCode
- ErrorCode errorCode = error.errorCode;
- if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) {
- _addFix_boolInsteadOfBoolean();
- }
- if (errorCode ==
- CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) {
- _addFix_replaceWithConstInstanceCreation();
- }
- if (errorCode ==
- CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) {
- _addFix_createConstructorSuperExplicit();
- }
- if (errorCode ==
- CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) {
- _addFix_createConstructorSuperImplicit();
- }
- if (errorCode ==
- CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) {
- _addFix_createConstructorSuperExplicit();
- }
- if (errorCode == HintCode.DIVISION_OPTIMIZATION) {
- _addFix_useEffectiveIntegerDivision();
- }
- if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) {
- _addFix_isNotNull();
- }
- if (errorCode == HintCode.TYPE_CHECK_IS_NULL) {
- _addFix_isNull();
- }
- if (errorCode == HintCode.UNNECESSARY_CAST) {
- _addFix_removeUnnecessaryCast();
- }
- if (errorCode == HintCode.UNUSED_IMPORT) {
- _addFix_removeUnusedImport();
- }
- if (errorCode == ParserErrorCode.EXPECTED_TOKEN) {
- _addFix_insertSemicolon();
- }
- if (errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS) {
- _addFix_removeParameters_inGetterDeclaration();
- }
- if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER) {
- _addFix_makeEnclosingClassAbstract();
- }
- if (errorCode == StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS) {
- _addFix_createConstructor_insteadOfSyntheticDefault();
- }
- if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) {
- _addFix_createConstructor_named();
- }
- if (errorCode ==
- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
- errorCode ==
- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO ||
- errorCode ==
- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE ||
- errorCode ==
- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR ||
- errorCode ==
- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
- // make class abstract
- _addFix_makeEnclosingClassAbstract();
- // implement methods
- AnalysisErrorWithProperties errorWithProperties =
- error as AnalysisErrorWithProperties;
- Object property =
- errorWithProperties.getProperty(ErrorProperty.UNIMPLEMENTED_METHODS);
- List<ExecutableElement> missingOverrides =
- property as List<ExecutableElement>;
- _addFix_createMissingOverrides(missingOverrides);
- _addFix_createNoSuchMethod();
- }
- if (errorCode == StaticWarningCode.UNDEFINED_CLASS) {
- _addFix_importLibrary_withType();
- _addFix_createClass();
- _addFix_undefinedClass_useSimilar();
- }
- if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) {
- _addFix_createFunction_forFunctionType();
- _addFix_importLibrary_withType();
- _addFix_importLibrary_withTopLevelVariable();
- }
- if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) {
- _addFix_useStaticAccess_method();
- _addFix_useStaticAccess_property();
- }
- if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) {
- _addFix_removeParentheses_inGetterInvocation();
- }
- if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) {
- _addFix_importLibrary_withFunction();
- _addFix_undefinedFunction_useSimilar();
- _addFix_undefinedFunction_create();
- }
- if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) {
- _addFix_createFunction_forFunctionType();
- }
- if (errorCode == HintCode.UNDEFINED_METHOD ||
- errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
- _addFix_undefinedMethod_useSimilar();
- _addFix_undefinedMethod_create();
- _addFix_undefinedFunction_create();
- }
- // done
- return fixes;
- }
-
- void _addFix(FixKind kind, List args, {String fixFile}) {
- if (fixFile == null) {
- fixFile = file;
- }
- FileEdit fileEdit = new FileEdit(file);
- fileEdit.addAll(edits);
- // prepare Change
- String message = formatList(kind.message, args);
- Change change = new Change(message);
- change.addFileEdit(fileEdit);
- linkedPositionGroups.values.forEach(
- (group) => change.addLinkedEditGroup(group));
- change.selection = exitPosition;
- // add Fix
- Fix fix = new Fix(kind, change);
- fixes.add(fix);
- // clear
- edits.clear();
- linkedPositionGroups.clear();
- exitPosition = null;
- }
-
- void _addFix_boolInsteadOfBoolean() {
- SourceRange range = rf.rangeError(error);
- _addReplaceEdit(range, "bool");
- _addFix(FixKind.REPLACE_BOOLEAN_WITH_BOOL, []);
- }
-
- void _addFix_createClass() {
- if (_mayBeTypeIdentifier(node)) {
- String name = (node as SimpleIdentifier).name;
- // prepare environment
- CompilationUnitMember enclosingMember =
- node.getAncestor((node) => node is CompilationUnitMember);
- int offset = enclosingMember.end;
- String prefix = "";
- // prepare source
- SourceBuilder sb = new SourceBuilder(file, offset);
- {
- sb.append("${eol}${eol}");
- sb.append(prefix);
- // "class"
- sb.append("class ");
- // append name
- {
- sb.startPosition("NAME");
- sb.append(name);
- sb.endPosition();
- }
- // no members
- sb.append(" {");
- sb.append(eol);
- sb.append("}");
- }
- // insert source
- _insertBuilder(sb);
- _addLinkedPosition("NAME", rf.rangeNode(node));
- // add proposal
- _addFix(FixKind.CREATE_CLASS, [name]);
- }
- }
-
- void _addFix_createConstructorSuperExplicit() {
- ConstructorDeclaration targetConstructor =
- node.parent as ConstructorDeclaration;
- ClassDeclaration targetClassNode =
- targetConstructor.parent as ClassDeclaration;
- ClassElement targetClassElement = targetClassNode.element;
- ClassElement superClassElement = targetClassElement.supertype.element;
- // add proposals for all super constructors
- List<ConstructorElement> superConstructors = superClassElement.constructors;
- for (ConstructorElement superConstructor in superConstructors) {
- String constructorName = superConstructor.name;
- // skip private
- if (Identifier.isPrivateName(constructorName)) {
- continue;
- }
- // prepare SourceBuilder
- SourceBuilder sb;
- {
- List<ConstructorInitializer> initializers =
- targetConstructor.initializers;
- if (initializers.isEmpty) {
- int insertOffset = targetConstructor.parameters.end;
- sb = new SourceBuilder(file, insertOffset);
- sb.append(" : ");
- } else {
- ConstructorInitializer lastInitializer =
- initializers[initializers.length - 1];
- int insertOffset = lastInitializer.end;
- sb = new SourceBuilder(file, insertOffset);
- sb.append(", ");
- }
- }
- // add super constructor name
- sb.append("super");
- if (!StringUtils.isEmpty(constructorName)) {
- sb.append(".");
- sb.append(constructorName);
- }
- // add arguments
- sb.append("(");
- bool firstParameter = true;
- for (ParameterElement parameter in superConstructor.parameters) {
- // skip non-required parameters
- if (parameter.parameterKind != ParameterKind.REQUIRED) {
- break;
- }
- // comma
- if (firstParameter) {
- firstParameter = false;
- } else {
- sb.append(", ");
- }
- // default value
- DartType parameterType = parameter.type;
- sb.startPosition(parameter.name);
- sb.append(getDefaultValueCode(parameterType));
- sb.endPosition();
- }
- sb.append(")");
- // insert proposal
- _insertBuilder(sb);
- // add proposal
- String proposalName = _getConstructorProposalName(superConstructor);
- _addFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, [proposalName]);
- }
- }
-
- void _addFix_createConstructorSuperImplicit() {
- ClassDeclaration targetClassNode = node.parent as ClassDeclaration;
- ClassElement targetClassElement = targetClassNode.element;
- ClassElement superClassElement = targetClassElement.supertype.element;
- String targetClassName = targetClassElement.name;
- // add proposals for all super constructors
- List<ConstructorElement> superConstructors = superClassElement.constructors;
- for (ConstructorElement superConstructor in superConstructors) {
- String constructorName = superConstructor.name;
- // skip private
- if (Identifier.isPrivateName(constructorName)) {
- continue;
- }
- // prepare parameters and arguments
- SourceBuilder parametersBuffer = new SourceBuilder.buffer();
- SourceBuilder argumentsBuffer = new SourceBuilder.buffer();
- bool firstParameter = true;
- for (ParameterElement parameter in superConstructor.parameters) {
- // skip non-required parameters
- if (parameter.parameterKind != ParameterKind.REQUIRED) {
- break;
- }
- // comma
- if (firstParameter) {
- firstParameter = false;
- } else {
- parametersBuffer.append(', ');
- argumentsBuffer.append(', ');
- }
- // name
- String parameterName = parameter.displayName;
- if (parameterName.length > 1 && parameterName.startsWith('_')) {
- parameterName = parameterName.substring(1);
- }
- // parameter & argument
- _appendParameterSource(parametersBuffer, parameter.type, parameterName);
- argumentsBuffer.append(parameterName);
- }
- // add proposal
- _ConstructorLocation targetLocation =
- _prepareNewConstructorLocation(targetClassNode);
- SourceBuilder sb = new SourceBuilder(file, targetLocation._offset);
- {
- String indent = utils.getIndent(1);
- sb.append(targetLocation._prefix);
- sb.append(indent);
- sb.append(targetClassName);
- if (!constructorName.isEmpty) {
- sb.startPosition('NAME');
- sb.append('.');
- sb.append(constructorName);
- sb.endPosition();
- }
- sb.append("(");
- sb.append(parametersBuffer.toString());
- sb.append(') : super');
- if (!constructorName.isEmpty) {
- sb.append('.');
- sb.append(constructorName);
- }
- sb.append('(');
- sb.append(argumentsBuffer.toString());
- sb.append(');');
- sb.append(targetLocation._suffix);
- }
- _insertBuilder(sb);
- // add proposal
- String proposalName = _getConstructorProposalName(superConstructor);
- _addFix(FixKind.CREATE_CONSTRUCTOR_SUPER, [proposalName]);
- }
- }
-
- 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
- _addFix(FixKind.CREATE_CONSTRUCTOR, [constructorName], fixFile: targetFile);
- }
-
- 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
- _addFix(FixKind.CREATE_CONSTRUCTOR, [constructorName], fixFile: targetFile);
- }
-
- void _addFix_createFunction_forFunctionType() {
- if (node is SimpleIdentifier) {
- SimpleIdentifier nameNode = node as SimpleIdentifier;
- // prepare argument expression (to get parameter)
- ClassElement targetElement;
- Expression argument;
- {
- Expression target = getQualifiedPropertyTarget(node);
- if (target != null) {
- DartType targetType = target.bestType;
- if (targetType != null && targetType.element is ClassElement) {
- targetElement = targetType.element as ClassElement;
- argument = target.parent as Expression;
- } else {
- return;
- }
- } else {
- ClassDeclaration enclosingClass =
- node.getAncestor((node) => node is ClassDeclaration);
- targetElement = enclosingClass != null ?
- enclosingClass.element :
- null;
- argument = nameNode;
- }
- }
- // should be argument of some invocation
- ParameterElement parameterElement = argument.bestParameterElement;
- if (parameterElement == null) {
- return;
- }
- // should be parameter of function type
- DartType parameterType = parameterElement.type;
- if (parameterType is! FunctionType) {
- return;
- }
- FunctionType functionType = parameterType as FunctionType;
- // add proposal
- if (targetElement != null) {
- _addProposal_createFunction_method(targetElement, functionType);
- } else {
- _addProposal_createFunction_function(functionType);
- }
- }
- }
-
- void
- _addFix_createMissingOverrides(List<ExecutableElement> missingOverrides) {
- // sort by name
- missingOverrides.sort((Element firstElement, Element secondElement) {
- return compareStrings(
- firstElement.displayName,
- secondElement.displayName);
- });
- ClassDeclaration targetClass = node.parent as ClassDeclaration;
- int insertOffset = targetClass.end - 1;
- SourceBuilder sb = new SourceBuilder(file, insertOffset);
- // add elements
- bool isFirst = true;
- for (ExecutableElement missingOverride in missingOverrides) {
- if (!isFirst || !targetClass.members.isEmpty) {
- sb.append(eol);
- }
- _addFix_createMissingOverrides_single(sb, targetClass, missingOverride);
- isFirst = false;
- }
- // add proposal
- exitPosition = new Position(file, insertOffset);
- _insertBuilder(sb);
- _addFix(FixKind.CREATE_MISSING_OVERRIDES, [missingOverrides.length]);
- }
-
- void _addFix_createMissingOverrides_single(SourceBuilder sb,
- ClassDeclaration targetClass, ExecutableElement missingOverride) {
- // prepare environment
- String prefix = utils.getIndent(1);
- String prefix2 = utils.getIndent(2);
- // may be property
- ElementKind elementKind = missingOverride.kind;
- bool isGetter = elementKind == ElementKind.GETTER;
- bool isSetter = elementKind == ElementKind.SETTER;
- bool isMethod = elementKind == ElementKind.METHOD;
- bool isOperator = isMethod && (missingOverride as MethodElement).isOperator;
- sb.append(prefix);
- if (isGetter) {
- sb.append('// TODO: implement ${missingOverride.displayName}');
- sb.append(eol);
- sb.append(prefix);
- }
- // @override
- {
- sb.append('@override');
- sb.append(eol);
- sb.append(prefix);
- }
- // return type
- _appendType(sb, missingOverride.type.returnType);
- if (isGetter) {
- sb.append('get ');
- } else if (isSetter) {
- sb.append('set ');
- } else if (isOperator) {
- sb.append('operator ');
- }
- // name
- sb.append(missingOverride.displayName);
- // parameters + body
- if (isGetter) {
- sb.append(' => null;');
- } else {
- List<ParameterElement> parameters = missingOverride.parameters;
- _appendParameters(sb, parameters, _getDefaultValueMap(parameters));
- sb.append(' {');
- // TO-DO
- sb.append(eol);
- sb.append(prefix2);
- sb.append('// TODO: implement ${missingOverride.displayName}');
- sb.append(eol);
- // close method
- sb.append(prefix);
- sb.append('}');
- }
- sb.append(eol);
- }
-
- void _addFix_createNoSuchMethod() {
- ClassDeclaration targetClass = node.parent as ClassDeclaration;
- // prepare environment
- String prefix = utils.getIndent(1);
- int insertOffset = targetClass.end - 1;
- // prepare source
- SourceBuilder sb = new SourceBuilder(file, insertOffset);
- {
- // insert empty line before existing member
- if (!targetClass.members.isEmpty) {
- sb.append(eol);
- }
- // append method
- sb.append(prefix);
- sb.append(
- "noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);");
- sb.append(eol);
- }
- // done
- _insertBuilder(sb);
- exitPosition = new Position(file, insertOffset);
- // add proposal
- _addFix(FixKind.CREATE_NO_SUCH_METHOD, []);
- }
-
- void _addFix_importLibrary(FixKind kind, String importPath) {
- CompilationUnitElement libraryUnitElement =
- unitLibraryElement.definingCompilationUnit;
- CompilationUnit libraryUnit = libraryUnitElement.node;
- // prepare new import location
- int offset = 0;
- String prefix;
- String suffix;
- {
- // if no directives
- prefix = "";
- suffix = eol;
- CorrectionUtils libraryUtils = new CorrectionUtils(libraryUnit);
- // after last directive in library
- for (Directive directive in libraryUnit.directives) {
- if (directive is LibraryDirective || directive is ImportDirective) {
- offset = directive.end;
- prefix = eol;
- suffix = "";
- }
- }
- // if still beginning of file, skip shebang and line comments
- if (offset == 0) {
- CorrectionUtils_InsertDesc desc = libraryUtils.getInsertDescTop();
- offset = desc.offset;
- prefix = desc.prefix;
- suffix = "${desc.suffix}${eol}";
- }
- }
- // insert new import
- String importSource = "${prefix}import '${importPath}';${suffix}";
- _addInsertEdit(offset, importSource);
- // add proposal
- _addFix(kind, [importPath], fixFile: libraryUnitElement.source.fullName);
- }
-
- void _addFix_importLibrary_withElement(String name, ElementKind kind) {
- // ignore if private
- if (name.startsWith("_")) {
- return;
- }
-
- // may be there is an existing import,
- // but it is with prefix and we don't use this prefix
- for (ImportElement imp in unitLibraryElement.imports) {
- // prepare element
- LibraryElement libraryElement = imp.importedLibrary;
- Element element = getExportedElement(libraryElement, name);
- if (element == null) {
- continue;
- }
- if (element is PropertyAccessorElement) {
- element = (element as PropertyAccessorElement).variable;
- }
- if (element.kind != kind) {
- continue;
- }
- // may be apply prefix
- PrefixElement prefix = imp.prefix;
- if (prefix != null) {
- SourceRange range = rf.rangeStartLength(node, 0);
- _addReplaceEdit(range, "${prefix.displayName}.");
- _addFix(
- FixKind.IMPORT_LIBRARY_PREFIX,
- [libraryElement.displayName, prefix.displayName]);
- continue;
- }
- // may be update "show" directive
- List<NamespaceCombinator> combinators = imp.combinators;
- if (combinators.length == 1 && combinators[0] is ShowElementCombinator) {
- ShowElementCombinator showCombinator =
- combinators[0] as ShowElementCombinator;
- // prepare new set of names to show
- Set<String> showNames = new SplayTreeSet<String>();
- showNames.addAll(showCombinator.shownNames);
- showNames.add(name);
- // prepare library name - unit name or 'dart:name' for SDK library
- String libraryName = libraryElement.definingCompilationUnit.displayName;
- if (libraryElement.isInSdk) {
- libraryName = imp.uri;
- }
- // update library
- String newShowCode = "show ${StringUtils.join(showNames, ", ")}";
- _addReplaceEdit(rf.rangeOffsetEnd(showCombinator), newShowCode);
- _addFix(
- FixKind.IMPORT_LIBRARY_SHOW,
- [libraryName],
- fixFile: unitLibraryFile);
- // we support only one import without prefix
- return;
- }
- }
- // check SDK libraries
- AnalysisContext context = unitLibraryElement.context;
- {
- DartSdk sdk = context.sourceFactory.dartSdk;
- List<SdkLibrary> sdkLibraries = sdk.sdkLibraries;
- for (SdkLibrary sdkLibrary in sdkLibraries) {
- SourceFactory sdkSourceFactory = context.sourceFactory;
- String libraryUri = 'dart:' + sdkLibrary.shortName;
- Source librarySource =
- sdkSourceFactory.resolveUri(unitSource, libraryUri);
- // prepare LibraryElement
- LibraryElement libraryElement =
- context.getLibraryElement(librarySource);
- if (libraryElement == null) {
- continue;
- }
- // prepare exported Element
- Element element = getExportedElement(libraryElement, name);
- if (element == null) {
- continue;
- }
- if (element is PropertyAccessorElement) {
- element = (element as PropertyAccessorElement).variable;
- }
- if (element.kind != kind) {
- continue;
- }
- // add import
- _addFix_importLibrary(FixKind.IMPORT_LIBRARY_SDK, libraryUri);
- }
- }
- // check project libraries
- {
- List<Source> librarySources = context.librarySources;
- for (Source librarySource in librarySources) {
- // we don't need SDK libraries here
- if (librarySource.isInSystemLibrary) {
- continue;
- }
- // prepare LibraryElement
- LibraryElement libraryElement =
- context.getLibraryElement(librarySource);
- if (libraryElement == null) {
- continue;
- }
- // prepare exported Element
- Element element = getExportedElement(libraryElement, name);
- if (element == null) {
- continue;
- }
- if (element is PropertyAccessorElement) {
- element = (element as PropertyAccessorElement).variable;
- }
- if (element.kind != kind) {
- continue;
- }
- // prepare "library" file
- String libraryFile = librarySource.fullName;
- // may be "package:" URI
- {
- String libraryPackageUri = _findPackageUri(context, libraryFile);
- if (libraryPackageUri != null) {
- _addFix_importLibrary(
- FixKind.IMPORT_LIBRARY_PROJECT,
- libraryPackageUri);
- continue;
- }
- }
- // relative URI
- String relativeFile = relative(libraryFile, from: unitLibraryFolder);
- relativeFile = split(relativeFile).join('/');
- _addFix_importLibrary(FixKind.IMPORT_LIBRARY_PROJECT, relativeFile);
- }
- }
- }
-
- void _addFix_importLibrary_withFunction() {
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- MethodInvocation invocation = node.parent as MethodInvocation;
- if (invocation.realTarget == null && invocation.methodName == node) {
- String name = (node as SimpleIdentifier).name;
- _addFix_importLibrary_withElement(name, ElementKind.FUNCTION);
- }
- }
- }
-
- void _addFix_importLibrary_withTopLevelVariable() {
- if (node is SimpleIdentifier) {
- String name = (node as SimpleIdentifier).name;
- _addFix_importLibrary_withElement(name, ElementKind.TOP_LEVEL_VARIABLE);
- }
- }
-
- void _addFix_importLibrary_withType() {
- if (_mayBeTypeIdentifier(node)) {
- String typeName = (node as SimpleIdentifier).name;
- _addFix_importLibrary_withElement(typeName, ElementKind.CLASS);
- }
- }
-
- void _addFix_insertSemicolon() {
- if (error.message.contains("';'")) {
- int insertOffset = error.offset + error.length;
- _addInsertEdit(insertOffset, ";");
- _addFix(FixKind.INSERT_SEMICOLON, []);
- }
- }
-
- void _addFix_isNotNull() {
- if (coveredNode is IsExpression) {
- IsExpression isExpression = coveredNode as IsExpression;
- _addReplaceEdit(
- rf.rangeEndEnd(isExpression.expression, isExpression),
- " != null");
- _addFix(FixKind.USE_NOT_EQ_NULL, []);
- }
- }
-
- void _addFix_isNull() {
- if (coveredNode is IsExpression) {
- IsExpression isExpression = coveredNode as IsExpression;
- _addReplaceEdit(
- rf.rangeEndEnd(isExpression.expression, isExpression),
- " == null");
- _addFix(FixKind.USE_EQ_EQ_NULL, []);
- }
- }
-
- void _addFix_makeEnclosingClassAbstract() {
- ClassDeclaration enclosingClass =
- node.getAncestor((node) => node is ClassDeclaration);
- String className = enclosingClass.name.name;
- _addInsertEdit(enclosingClass.classKeyword.offset, "abstract ");
- _addFix(FixKind.MAKE_CLASS_ABSTRACT, [className]);
- }
-
- void _addFix_removeParameters_inGetterDeclaration() {
- if (node is SimpleIdentifier && node.parent is MethodDeclaration) {
- MethodDeclaration method = node.parent as MethodDeclaration;
- FunctionBody body = method.body;
- if (method.name == node && body != null) {
- _addReplaceEdit(rf.rangeEndStart(node, body), " ");
- _addFix(FixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, []);
- }
- }
- }
-
- void _addFix_removeParentheses_inGetterInvocation() {
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- MethodInvocation invocation = node.parent as MethodInvocation;
- if (invocation.methodName == node && invocation.target != null) {
- _addRemoveEdit(rf.rangeEndEnd(node, invocation));
- _addFix(FixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, []);
- }
- }
- }
-
- void _addFix_removeUnnecessaryCast() {
- if (coveredNode is! AsExpression) {
- return;
- }
- AsExpression asExpression = coveredNode as AsExpression;
- Expression expression = asExpression.expression;
- int expressionPrecedence = getExpressionPrecedence(expression);
- // remove 'as T' from 'e as T'
- _addRemoveEdit(rf.rangeEndEnd(expression, asExpression));
- _removeEnclosingParentheses(asExpression, expressionPrecedence);
- // done
- _addFix(FixKind.REMOVE_UNNECASSARY_CAST, []);
- }
-
- void _addFix_removeUnusedImport() {
- // prepare ImportDirective
- ImportDirective importDirective =
- node.getAncestor((node) => node is ImportDirective);
- if (importDirective == null) {
- return;
- }
- // remove the whole line with import
- _addRemoveEdit(utils.getLinesRange(rf.rangeNode(importDirective)));
- // done
- _addFix(FixKind.REMOVE_UNUSED_IMPORT, []);
- }
-
- void _addFix_replaceWithConstInstanceCreation() {
- if (coveredNode is InstanceCreationExpression) {
- var instanceCreation = coveredNode as InstanceCreationExpression;
- _addReplaceEdit(rf.rangeToken(instanceCreation.keyword), "const");
- _addFix(FixKind.USE_CONST, []);
- }
- }
-
- void _addFix_undefinedClass_useSimilar() {
- if (_mayBeTypeIdentifier(node)) {
- String name = (node as SimpleIdentifier).name;
- _ClosestElementFinder finder =
- new _ClosestElementFinder(
- name,
- (Element element) => element is ClassElement,
- MAX_LEVENSHTEIN_DISTANCE);
- // find closest element
- {
- // elements of this library
- for (CompilationUnitElement unit in unitLibraryElement.units) {
- finder._updateList(unit.types);
- }
- // elements from imports
- for (ImportElement importElement in unitLibraryElement.imports) {
- if (importElement.prefix == null) {
- Map<String, Element> namespace = getImportNamespace(importElement);
- finder._updateList(namespace.values);
- }
- }
- }
- // if we have close enough element, suggest to use it
- if (finder._element != null) {
- String closestName = finder._element.name;
- _addReplaceEdit(rf.rangeNode(node), closestName);
- // add proposal
- if (closestName != null) {
- _addFix(FixKind.CHANGE_TO, [closestName]);
- }
- }
- }
- }
-
- void _addFix_undefinedFunction_create() {
- // should be the name of the invocation
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- } else {
- return;
- }
- String name = (node as SimpleIdentifier).name;
- MethodInvocation invocation = node.parent as MethodInvocation;
- // function invocation has no target
- Expression target = invocation.realTarget;
- if (target != null) {
- return;
- }
- // prepare environment
- int insertOffset;
- String sourcePrefix;
- AstNode enclosingMember =
- node.getAncestor((node) => node is CompilationUnitMember);
- insertOffset = enclosingMember.end;
- sourcePrefix = "${eol}${eol}";
- // build method source
- SourceBuilder sb = new SourceBuilder(file, insertOffset);
- {
- sb.append(sourcePrefix);
- // append return type
- {
- DartType type = _inferReturnType(invocation);
- _appendType(sb, type, 'RETURN_TYPE');
- }
- // append name
- {
- sb.startPosition("NAME");
- sb.append(name);
- sb.endPosition();
- }
- _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList);
- sb.append(") {${eol}}");
- }
- // insert source
- _insertBuilder(sb);
- _addLinkedPosition3('NAME', sb, rf.rangeNode(node));
- // add proposal
- _addFix(FixKind.CREATE_FUNCTION, [name]);
- }
-
- void _addFix_undefinedFunction_useSimilar() {
- if (node is SimpleIdentifier) {
- String name = (node as SimpleIdentifier).name;
- _ClosestElementFinder finder =
- new _ClosestElementFinder(
- name,
- (Element element) => element is FunctionElement,
- MAX_LEVENSHTEIN_DISTANCE);
- // this library
- for (CompilationUnitElement unit in unitLibraryElement.units) {
- finder._updateList(unit.functions);
- }
- // imports
- for (ImportElement importElement in unitLibraryElement.imports) {
- if (importElement.prefix == null) {
- Map<String, Element> namespace = getImportNamespace(importElement);
- finder._updateList(namespace.values);
- }
- }
- // if we have close enough element, suggest to use it
- if (finder._element != null) {
- String closestName = finder._element.name;
- _addReplaceEdit(rf.rangeNode(node), closestName);
- _addFix(FixKind.CHANGE_TO, [closestName]);
- }
- }
- }
-
- void _addFix_undefinedMethod_create() {
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- String name = (node as SimpleIdentifier).name;
- MethodInvocation invocation = node.parent as MethodInvocation;
- // prepare environment
- Source targetSource;
- String prefix;
- int insertOffset;
- String sourcePrefix;
- String sourceSuffix;
- bool staticModifier = false;
- Expression target = invocation.realTarget;
- if (target == null) {
- targetSource = source;
- ClassMember enclosingMember =
- node.getAncestor((node) => node is ClassMember);
- staticModifier = _inStaticContext();
- prefix = utils.getNodePrefix(enclosingMember);
- insertOffset = enclosingMember.end;
- sourcePrefix = "${eol}${eol}";
- sourceSuffix = "";
- } else {
- // prepare target interface type
- DartType targetType = target.bestType;
- if (targetType is! InterfaceType) {
- return;
- }
- ClassElement targetElement = targetType.element as ClassElement;
- targetSource = targetElement.source;
- // may be static
- if (target is Identifier) {
- staticModifier = target.bestElement.kind == ElementKind.CLASS;
- }
- // prepare insert offset
- ClassDeclaration targetClass = targetElement.node;
- prefix = " ";
- insertOffset = targetClass.end - 1;
- if (targetClass.members.isEmpty) {
- sourcePrefix = "";
- } else {
- sourcePrefix = eol;
- }
- sourceSuffix = eol;
- }
- String targetFile = targetSource.fullName;
- // build method source
- SourceBuilder sb = new SourceBuilder(targetFile, insertOffset);
- {
- sb.append(sourcePrefix);
- sb.append(prefix);
- // maybe "static"
- if (staticModifier) {
- sb.append("static ");
- }
- // append return type
- _appendType(sb, _inferReturnType(invocation), 'RETURN_TYPE');
- // append name
- {
- sb.startPosition("NAME");
- sb.append(name);
- sb.endPosition();
- }
- _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList);
- sb.append(") {${eol}${prefix}}");
- sb.append(sourceSuffix);
- }
- // insert source
- _insertBuilder(sb);
- // add linked positions
- if (targetSource == source) {
- _addLinkedPosition3('NAME', sb, rf.rangeNode(node));
- }
- // add proposal
- _addFix(FixKind.CREATE_METHOD, [name], fixFile: targetFile);
- }
- }
-
- void _addFix_undefinedMethod_create_parameters(SourceBuilder sb,
- ArgumentList argumentList) {
- // append parameters
- sb.append("(");
- Set<String> excluded = new Set();
- List<Expression> arguments = argumentList.arguments;
- for (int i = 0; i < arguments.length; i++) {
- Expression argument = arguments[i];
- // append separator
- if (i != 0) {
- sb.append(", ");
- }
- // append type name
- DartType type = argument.bestType;
- String typeSource = utils.getTypeSource(type);
- {
- sb.startPosition("TYPE${i}");
- sb.append(typeSource);
- _addSuperTypeProposals(sb, new Set(), type);
- sb.endPosition();
- }
- sb.append(" ");
- // append parameter name
- {
- List<String> suggestions =
- _getArgumentNameSuggestions(excluded, type, argument, i);
- String favorite = suggestions[0];
- excluded.add(favorite);
- sb.startPosition("ARG${i}");
- sb.append(favorite);
- sb.addSuggestions(LinkedEditSuggestionKind.PARAMETER, suggestions);
- sb.endPosition();
- }
- }
- }
-
- void _addFix_undefinedMethod_useSimilar() {
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- MethodInvocation invocation = node.parent as MethodInvocation;
- String name = (node as SimpleIdentifier).name;
- _ClosestElementFinder finder =
- new _ClosestElementFinder(
- name,
- (Element element) => element is MethodElement && !element.isOperator,
- MAX_LEVENSHTEIN_DISTANCE);
- // unqualified invocation
- Expression target = invocation.realTarget;
- if (target == null) {
- ClassDeclaration clazz =
- invocation.getAncestor((node) => node is ClassDeclaration);
- if (clazz != null) {
- ClassElement classElement = clazz.element;
- _updateFinderWithClassMembers(finder, classElement);
- }
- } else {
- DartType type = target.bestType;
- if (type is InterfaceType) {
- ClassElement classElement = type.element;
- _updateFinderWithClassMembers(finder, classElement);
- }
- }
- // if we have close enough element, suggest to use it
- if (finder._element != null) {
- String closestName = finder._element.name;
- _addReplaceEdit(rf.rangeNode(node), closestName);
- _addFix(FixKind.CHANGE_TO, [closestName]);
- }
- }
- }
-
- void _addFix_useEffectiveIntegerDivision() {
- for (AstNode n = node; n != null; n = n.parent) {
- if (n is MethodInvocation &&
- n.offset == errorOffset &&
- n.length == errorLength) {
- MethodInvocation invocation = n as MethodInvocation;
- Expression target = invocation.target;
- while (target is ParenthesizedExpression) {
- target = (target as ParenthesizedExpression).expression;
- }
- // replace "/" with "~/"
- BinaryExpression binary = target as BinaryExpression;
- _addReplaceEdit(rf.rangeToken(binary.operator), "~/");
- // remove everything before and after
- _addRemoveEdit(rf.rangeStartStart(invocation, binary.leftOperand));
- _addRemoveEdit(rf.rangeEndEnd(binary.rightOperand, invocation));
- // add proposal
- _addFix(FixKind.USE_EFFECTIVE_INTEGER_DIVISION, []);
- // done
- break;
- }
- }
- }
-
- void _addFix_useStaticAccess_method() {
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- MethodInvocation invocation = node.parent as MethodInvocation;
- if (invocation.methodName == node) {
- Expression target = invocation.target;
- String targetType = utils.getExpressionTypeSource(target);
- // replace "target" with class name
- SourceRange range = rf.rangeNode(target);
- _addReplaceEdit(range, targetType);
- // add proposal
- _addFix(FixKind.CHANGE_TO_STATIC_ACCESS, [targetType]);
- }
- }
- }
-
- void _addFix_useStaticAccess_property() {
- if (node is SimpleIdentifier) {
- if (node.parent is PrefixedIdentifier) {
- PrefixedIdentifier prefixed = node.parent as PrefixedIdentifier;
- if (prefixed.identifier == node) {
- Expression target = prefixed.prefix;
- String targetType = utils.getExpressionTypeSource(target);
- // replace "target" with class name
- SourceRange range = rf.rangeNode(target);
- _addReplaceEdit(range, targetType);
- // add proposal
- _addFix(FixKind.CHANGE_TO_STATIC_ACCESS, [targetType]);
- }
- }
- }
- }
-
- /**
- * Adds a new [Edit] to [edits].
- */
- void _addInsertEdit(int offset, String text) {
- Edit edit = new Edit(offset, 0, text);
- edits.add(edit);
- }
-
- /**
- * Adds a single linked position to [groupId].
- */
- void _addLinkedPosition(String groupId, SourceRange range) {
- Position position = new Position(file, range.offset);
- LinkedEditGroup group = _getLinkedPosition(groupId);
- group.addPosition(position, range.length);
- }
-
- /**
- * Adds a single linked position to [groupId].
- */
- void _addLinkedPosition3(String groupId, SourceBuilder sb,
- SourceRange range) {
- if (sb.offset < range.offset) {
- int delta = sb.length;
- range = range.getTranslated(delta);
- }
- _addLinkedPosition(groupId, range);
- }
-
- /**
- * Prepares proposal for creating function corresponding to the given [FunctionType].
- */
- void _addProposal_createFunction(FunctionType functionType, String name,
- Source targetSource, int insertOffset, bool isStatic, String prefix,
- String sourcePrefix, String sourceSuffix) {
- // build method source
- String targetFile = targetSource.fullName;
- SourceBuilder sb = new SourceBuilder(targetFile, insertOffset);
- {
- sb.append(sourcePrefix);
- sb.append(prefix);
- // may be static
- if (isStatic) {
- sb.append("static ");
- }
- // append return type
- _appendType(sb, functionType.returnType, 'RETURN_TYPE');
- // append name
- {
- sb.startPosition("NAME");
- sb.append(name);
- sb.endPosition();
- }
- // append parameters
- sb.append("(");
- List<ParameterElement> parameters = functionType.parameters;
- for (int i = 0; i < parameters.length; i++) {
- ParameterElement parameter = parameters[i];
- // append separator
- if (i != 0) {
- sb.append(", ");
- }
- // append type name
- DartType type = parameter.type;
- if (!type.isDynamic) {
- String typeSource = utils.getTypeSource(type);
- {
- sb.startPosition("TYPE${i}");
- sb.append(typeSource);
- _addSuperTypeProposals(sb, new Set(), type);
- sb.endPosition();
- }
- sb.append(" ");
- }
- // append parameter name
- {
- sb.startPosition("ARG${i}");
- sb.append(parameter.displayName);
- sb.endPosition();
- }
- }
- sb.append(")");
- // close method
- sb.append(" {${eol}${prefix}}");
- sb.append(sourceSuffix);
- }
- // insert source
- _insertBuilder(sb);
- // add linked positions
- if (targetSource == source) {
- _addLinkedPosition3("NAME", sb, rf.rangeNode(node));
- }
- }
-
- /**
- * Adds proposal for creating method corresponding to the given [FunctionType] in the given
- * [ClassElement].
- */
- void _addProposal_createFunction_function(FunctionType functionType) {
- String name = (node as SimpleIdentifier).name;
- // prepare environment
- int insertOffset = unit.end;
- // prepare prefix
- String prefix = "";
- String sourcePrefix = "${eol}";
- String sourceSuffix = eol;
- _addProposal_createFunction(
- functionType,
- name,
- source,
- insertOffset,
- false,
- prefix,
- sourcePrefix,
- sourceSuffix);
- // add proposal
- _addFix(FixKind.CREATE_FUNCTION, [name], fixFile: file);
- }
-
- /**
- * Adds proposal for creating method corresponding to the given [FunctionType] in the given
- * [ClassElement].
- */
- void _addProposal_createFunction_method(ClassElement targetClassElement,
- FunctionType functionType) {
- String name = (node as SimpleIdentifier).name;
- // prepare environment
- Source targetSource = targetClassElement.source;
- String targetFile = targetSource.fullName;
- // prepare insert offset
- ClassDeclaration targetClassNode = targetClassElement.node;
- int insertOffset = targetClassNode.end - 1;
- // prepare prefix
- String prefix = " ";
- String sourcePrefix;
- if (targetClassNode.members.isEmpty) {
- sourcePrefix = "";
- } else {
- sourcePrefix = eol;
- }
- String sourceSuffix = eol;
- _addProposal_createFunction(
- functionType,
- name,
- targetSource,
- insertOffset,
- _inStaticContext(),
- prefix,
- sourcePrefix,
- sourceSuffix);
- // add proposal
- _addFix(FixKind.CREATE_METHOD, [name], fixFile: targetFile);
- }
-
- /**
- * Adds a new [Edit] to [edits].
- */
- void _addRemoveEdit(SourceRange range) {
- _addReplaceEdit(range, '');
- }
-
- /**
- * Adds a new [Edit] to [edits].
- */
- void _addReplaceEdit(SourceRange range, String text) {
- Edit edit = new Edit(range.offset, range.length, text);
- edits.add(edit);
- }
-
- void _appendParameterSource(SourceBuilder sb, DartType type, String name) {
- String parameterSource = utils.getParameterSource(type, name);
- sb.append(parameterSource);
- }
-
- void _appendParameters(SourceBuilder sb, List<ParameterElement> parameters,
- Map<ParameterElement, String> defaultValueMap) {
- sb.append("(");
- bool firstParameter = true;
- bool sawNamed = false;
- bool sawPositional = false;
- for (ParameterElement parameter in parameters) {
- if (!firstParameter) {
- sb.append(", ");
- } else {
- firstParameter = false;
- }
- // may be optional
- ParameterKind parameterKind = parameter.parameterKind;
- if (parameterKind == ParameterKind.NAMED) {
- if (!sawNamed) {
- sb.append("{");
- sawNamed = true;
- }
- }
- if (parameterKind == ParameterKind.POSITIONAL) {
- if (!sawPositional) {
- sb.append("[");
- sawPositional = true;
- }
- }
- // parameter
- _appendParameterSource(sb, parameter.type, parameter.name);
- // default value
- if (defaultValueMap != null) {
- String defaultSource = defaultValueMap[parameter];
- if (defaultSource != null) {
- if (sawPositional) {
- sb.append(" = ");
- } else {
- sb.append(": ");
- }
- sb.append(defaultSource);
- }
- }
- }
- // close parameters
- if (sawNamed) {
- sb.append("}");
- }
- if (sawPositional) {
- sb.append("]");
- }
- sb.append(")");
- }
-
- void _appendType(SourceBuilder sb, DartType type, [String groupId]) {
- if (type != null && !type.isDynamic) {
- String typeSource = utils.getTypeSource(type);
- if (groupId != null) {
- sb.startPosition(groupId);
- sb.append(typeSource);
- sb.endPosition();
- } else {
- sb.append(typeSource);
- }
- sb.append(' ');
- }
- }
-
- /**
- * @return the string to display as the name of the given constructor in a proposal name.
- */
- String _getConstructorProposalName(ConstructorElement constructor) {
- SourceBuilder proposalNameBuffer = new SourceBuilder.buffer();
- proposalNameBuffer.append("super");
- // may be named
- String constructorName = constructor.displayName;
- if (!constructorName.isEmpty) {
- proposalNameBuffer.append(".");
- proposalNameBuffer.append(constructorName);
- }
- // parameters
- _appendParameters(proposalNameBuffer, constructor.parameters, null);
- // done
- return proposalNameBuffer.toString();
- }
-
- /**
- * Returns the [Type] with given name from the `dart:core` library.
- */
- DartType _getCoreType(String name) {
- List<LibraryElement> libraries = unitLibraryElement.importedLibraries;
- for (LibraryElement library in libraries) {
- if (library.isDartCore) {
- ClassElement classElement = library.getType(name);
- if (classElement != null) {
- return classElement.type;
- }
- return null;
- }
- }
- return null;
- }
-
- Map<ParameterElement, String>
- _getDefaultValueMap(List<ParameterElement> parameters) {
- Map<ParameterElement, String> defaultSourceMap = {};
- Map<Source, String> sourceContentMap = {};
- for (ParameterElement parameter in parameters) {
- SourceRange valueRange = parameter.defaultValueRange;
- if (valueRange != null) {
- Source source = parameter.source;
- String sourceContent = sourceContentMap[source];
- if (sourceContent == null) {
- sourceContent = getSourceContent(parameter.context, source);
- sourceContentMap[source] = sourceContent;
- }
- String valueSource =
- sourceContent.substring(valueRange.offset, valueRange.end);
- defaultSourceMap[parameter] = valueSource;
- }
- }
- return defaultSourceMap;
- }
-
- /**
- * Returns an existing or just added [LinkedEditGroup] with [groupId].
- */
- LinkedEditGroup _getLinkedPosition(String groupId) {
- LinkedEditGroup group = linkedPositionGroups[groupId];
- if (group == null) {
- group = new LinkedEditGroup(groupId);
- linkedPositionGroups[groupId] = group;
- }
- return group;
- }
-
- /**
- * 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 a possible return [Type], may be `null` if cannot be inferred.
- */
- DartType _inferReturnType(MethodInvocation invocation) {
- AstNode parent = invocation.parent;
- // myFunction();
- if (parent is ExpressionStatement) {
- return VoidTypeImpl.instance;
- }
- // return myFunction();
- if (parent is ReturnStatement) {
- ExecutableElement executable = getEnclosingExecutableElement(invocation);
- return executable != null ? executable.returnType : null;
- }
- // int v = myFunction();
- if (parent is VariableDeclaration) {
- VariableDeclaration variableDeclaration = parent;
- if (variableDeclaration.initializer == invocation) {
- VariableElement variableElement = variableDeclaration.element;
- if (variableElement != null) {
- return variableElement.type;
- }
- }
- }
- // v = myFunction();
- if (parent is AssignmentExpression) {
- AssignmentExpression assignment = parent;
- if (assignment.rightHandSide == invocation) {
- if (assignment.operator.type == TokenType.EQ) {
- // v = myFunction();
- Expression lhs = assignment.leftHandSide;
- if (lhs != null) {
- return lhs.bestType;
- }
- } else {
- // v += myFunction();
- MethodElement method = assignment.bestElement;
- if (method != null) {
- List<ParameterElement> parameters = method.parameters;
- if (parameters.length == 1) {
- return parameters[0].type;
- }
- }
- }
- }
- }
- // v + myFunction();
- if (parent is BinaryExpression) {
- BinaryExpression binary = parent;
- MethodElement method = binary.bestElement;
- if (method != null) {
- if (binary.rightOperand == invocation) {
- List<ParameterElement> parameters = method.parameters;
- return parameters.length == 1 ? parameters[0].type : null;
- }
- }
- }
- // foo( myFunction() );
- if (parent is ArgumentList) {
- ParameterElement parameter = invocation.bestParameterElement;
- return parameter != null ? parameter.type : null;
- }
- // bool
- {
- // assert( myFunction() );
- if (parent is AssertStatement) {
- AssertStatement statement = parent;
- if (statement.condition == invocation) {
- return coreTypeBool;
- }
- }
- // if ( myFunction() ) {}
- if (parent is IfStatement) {
- IfStatement statement = parent;
- if (statement.condition == invocation) {
- return coreTypeBool;
- }
- }
- // while ( myFunction() ) {}
- if (parent is WhileStatement) {
- WhileStatement statement = parent;
- if (statement.condition == invocation) {
- return coreTypeBool;
- }
- }
- // do {} while ( myFunction() );
- if (parent is DoStatement) {
- DoStatement statement = parent;
- if (statement.condition == invocation) {
- return coreTypeBool;
- }
- }
- // !myFunction()
- if (parent is PrefixExpression) {
- PrefixExpression prefixExpression = parent;
- if (prefixExpression.operator.type == TokenType.BANG) {
- return coreTypeBool;
- }
- }
- // binary expression '&&' or '||'
- if (parent is BinaryExpression) {
- BinaryExpression binaryExpression = parent;
- TokenType operatorType = binaryExpression.operator.type;
- if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
- operatorType == TokenType.BAR_BAR) {
- return coreTypeBool;
- }
- }
- }
- // we don't know
- return null;
- }
-
- /**
- * Inserts the given [SourceBuilder] at its offset.
- */
- void _insertBuilder(SourceBuilder builder) {
- String text = builder.toString();
- _addInsertEdit(builder.offset, text);
- // add linked positions
- builder.linkedPositionGroups.forEach((LinkedEditGroup group) {
- LinkedEditGroup fixGroup = _getLinkedPosition(group.id);
- group.positions.forEach((Position position) {
- fixGroup.addPosition(position, group.length);
- });
- group.suggestions.forEach((LinkedEditSuggestion suggestion) {
- fixGroup.addSuggestion(suggestion);
- });
- });
- }
-
-// void _addLinkedPositionProposal(String group,
-// LinkedPositionProposal proposal) {
-// List<LinkedPositionProposal> nodeProposals = linkedPositionProposals[group];
-// if (nodeProposals == null) {
-// nodeProposals = <LinkedPositionProposal>[];
-// linkedPositionProposals[group] = nodeProposals;
-// }
-// nodeProposals.add(proposal);
-// }
-
-// /**
-// * Returns `true` if the given [ClassMember] is a part of a static method or
-// * a field initializer.
-// */
-// bool _inStaticMemberContext2(ClassMember member) {
-// if (member is MethodDeclaration) {
-// return member.isStatic;
-// }
-// // field initializer cannot reference "this"
-// if (member is FieldDeclaration) {
-// return true;
-// }
-// return false;
-// }
-
- _ConstructorLocation
- _prepareNewConstructorLocation(ClassDeclaration classDeclaration) {
- List<ClassMember> members = classDeclaration.members;
- // find the last field/constructor
- ClassMember lastFieldOrConstructor = null;
- for (ClassMember member in members) {
- if (member is FieldDeclaration || member is ConstructorDeclaration) {
- lastFieldOrConstructor = member;
- } else {
- break;
- }
- }
- // after the field/constructor
- if (lastFieldOrConstructor != null) {
- return new _ConstructorLocation(
- "${eol}${eol}",
- lastFieldOrConstructor.end,
- "");
- }
- // at the beginning of the class
- String suffix = members.isEmpty ? "" : eol;
- return new _ConstructorLocation(
- eol,
- classDeclaration.leftBracket.end,
- suffix);
- }
-
- /**
- * Removes any [ParenthesizedExpression] enclosing [expr].
- *
- * [exprPrecedence] - the effective precedence of [expr].
- */
- void _removeEnclosingParentheses(Expression expr, int exprPrecedence) {
- while (expr.parent is ParenthesizedExpression) {
- ParenthesizedExpression parenthesized =
- expr.parent as ParenthesizedExpression;
- if (getExpressionParentPrecedence(parenthesized) > exprPrecedence) {
- break;
- }
- _addRemoveEdit(rf.rangeToken(parenthesized.leftParenthesis));
- _addRemoveEdit(rf.rangeToken(parenthesized.rightParenthesis));
- expr = parenthesized;
- }
- }
-
- void _updateFinderWithClassMembers(_ClosestElementFinder finder,
- ClassElement clazz) {
- if (clazz != null) {
- List<Element> members = getMembers(clazz);
- finder._updateList(members);
- }
- }
-
- static void _addSuperTypeProposals(SourceBuilder sb,
- Set<DartType> alreadyAdded, DartType type) {
- if (type != null &&
- !alreadyAdded.contains(type) &&
- type.element is ClassElement) {
- alreadyAdded.add(type);
- ClassElement element = type.element as ClassElement;
- sb.addSuggestion(LinkedEditSuggestionKind.TYPE, element.name);
- _addSuperTypeProposals(sb, alreadyAdded, element.supertype);
- for (InterfaceType interfaceType in element.interfaces) {
- _addSuperTypeProposals(sb, alreadyAdded, interfaceType);
- }
- }
- }
-
- /**
- * Attempts to convert the given absolute path into a "package" URI.
- *
- * [context] - the [AnalysisContext] to work in.
- * [path] - the absolute path, not `null`.
- *
- * Returns the "package" URI, may be `null`.
- */
- static String _findPackageUri(AnalysisContext context, String path) {
-// Source fileSource = new FileBasedSource.con1(path);
- Source fileSource = new NonExistingSource(path, UriKind.FILE_URI);
- Uri uri = context.sourceFactory.restoreUri(fileSource);
- if (uri == null) {
- return null;
- }
- return uri.toString();
- }
-
- /**
- * @return the suggestions for given [Type] and [DartExpression], not empty.
- */
- static List<String> _getArgumentNameSuggestions(Set<String> excluded,
- DartType type, Expression expression, int index) {
- List<String> suggestions =
- getVariableNameSuggestionsForExpression(type, expression, excluded);
- if (suggestions.length != 0) {
- return suggestions;
- }
- return <String>["arg${index}"];
- }
-
- /**
- * Returns `true` if [node] is a type name.
- */
- static bool _mayBeTypeIdentifier(AstNode node) {
- if (node is SimpleIdentifier) {
- AstNode parent = node.parent;
- if (parent is TypeName) {
- return true;
- }
- if (parent is MethodInvocation) {
- return parent.realTarget == node;
- }
- if (parent is PrefixedIdentifier) {
- return parent.prefix == node;
- }
- }
- return false;
- }
-}
-
-/**
- * Helper for finding [Element] with name closest to the given.
- */
-class _ClosestElementFinder {
- final String _targetName;
- final Predicate<Element> _predicate;
-
- Element _element = null;
- int _distance;
-
- _ClosestElementFinder(this._targetName, this._predicate, this._distance);
-
- void _update(Element element) {
- if (_predicate(element)) {
- int memberDistance = levenshtein(element.name, _targetName, _distance);
- if (memberDistance < _distance) {
- _element = element;
- _distance = memberDistance;
- }
- }
- }
-
- void _updateList(Iterable<Element> elements) {
- for (Element element in elements) {
- _update(element);
- }
- }
-}
-
-/**
- * Describes the location for a newly created [ConstructorDeclaration].
- */
-class _ConstructorLocation {
- final String _prefix;
- final int _offset;
- final String _suffix;
-
- _ConstructorLocation(this._prefix, this._offset, this._suffix);
-}
« no previous file with comments | « pkg/analysis_services/lib/src/correction/assist.dart ('k') | pkg/analysis_services/lib/src/correction/levenshtein.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698