| Index: pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
|
| diff --git a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
|
| deleted file mode 100644
|
| index cfe406706935b67eb92c717770895bd5e8e7db1f..0000000000000000000000000000000000000000
|
| --- a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
|
| +++ /dev/null
|
| @@ -1,943 +0,0 @@
|
| -// Copyright (c) 2015, 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.
|
| -
|
| -import 'dart:async';
|
| -
|
| -import 'package:analysis_server/protocol/protocol_generated.dart'
|
| - hide Element, ElementKind;
|
| -import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
|
| -import 'package:analysis_server/src/provisional/edit/utilities/change_builder_dart.dart';
|
| -import 'package:analysis_server/src/services/correction/name_suggestion.dart';
|
| -import 'package:analysis_server/src/services/correction/source_range.dart';
|
| -import 'package:analysis_server/src/services/correction/util.dart';
|
| -import 'package:analysis_server/src/utilities/change_builder_core.dart';
|
| -import 'package:analyzer/dart/ast/ast.dart';
|
| -import 'package:analyzer/dart/ast/token.dart';
|
| -import 'package:analyzer/dart/element/element.dart';
|
| -import 'package:analyzer/dart/element/type.dart';
|
| -import 'package:analyzer/src/dart/analysis/driver.dart';
|
| -import 'package:analyzer/src/dart/ast/utilities.dart';
|
| -import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
|
| -import 'package:analyzer/src/generated/resolver.dart';
|
| -import 'package:analyzer/src/generated/source.dart';
|
| -import 'package:analyzer/src/generated/utilities_dart.dart';
|
| -
|
| -/**
|
| - * A [ChangeBuilder] used to build changes in Dart files.
|
| - */
|
| -class DartChangeBuilderImpl extends ChangeBuilderImpl
|
| - implements DartChangeBuilder {
|
| - /**
|
| - * The analysis driver in which the files being edited were analyzed.
|
| - */
|
| - final AnalysisDriver driver;
|
| -
|
| - /**
|
| - * Initialize a newly created change builder.
|
| - */
|
| - DartChangeBuilderImpl(this.driver);
|
| -
|
| - @override
|
| - Future<DartFileEditBuilderImpl> createFileEditBuilder(
|
| - String path, int fileStamp) async {
|
| - AnalysisResult result = await driver.getResult(path);
|
| - return new DartFileEditBuilderImpl(this, path, fileStamp, result.unit);
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * An [EditBuilder] used to build edits in Dart files.
|
| - */
|
| -class DartEditBuilderImpl extends EditBuilderImpl implements DartEditBuilder {
|
| - /**
|
| - * Initialize a newly created builder to build a source edit.
|
| - */
|
| - DartEditBuilderImpl(
|
| - DartFileEditBuilderImpl sourceFileEditBuilder, int offset, int length)
|
| - : super(sourceFileEditBuilder, offset, length);
|
| -
|
| - DartFileEditBuilderImpl get dartFileEditBuilder => fileEditBuilder;
|
| -
|
| - @override
|
| - LinkedEditBuilderImpl createLinkedEditBuilder() {
|
| - return new DartLinkedEditBuilderImpl(this);
|
| - }
|
| -
|
| - /**
|
| - * Returns the indentation with the given [level].
|
| - */
|
| - String getIndent(int level) => ' ' * level;
|
| -
|
| - /**
|
| - * Arrange to have an import added for the given [library].
|
| - */
|
| - void importLibrary(Source library) {
|
| - dartFileEditBuilder.librariesToImport.add(library);
|
| - }
|
| -
|
| - @override
|
| - void writeClassDeclaration(String name,
|
| - {Iterable<DartType> interfaces,
|
| - bool isAbstract: false,
|
| - void memberWriter(),
|
| - Iterable<DartType> mixins,
|
| - String nameGroupName,
|
| - DartType superclass,
|
| - String superclassGroupName}) {
|
| - // TODO(brianwilkerson) Add support for type parameters, probably as a
|
| - // parameterWriter parameter.
|
| - if (isAbstract) {
|
| - write(Keyword.ABSTRACT.lexeme);
|
| - write(' ');
|
| - }
|
| - write('class ');
|
| - if (nameGroupName == null) {
|
| - write(name);
|
| - } else {
|
| - addLinkedEdit(nameGroupName, (LinkedEditBuilder builder) {
|
| - write(name);
|
| - });
|
| - }
|
| - if (superclass != null) {
|
| - write(' extends ');
|
| - writeType(superclass, groupName: superclassGroupName);
|
| - } else if (mixins != null && mixins.isNotEmpty) {
|
| - write(' extends Object ');
|
| - }
|
| - writeTypes(mixins, prefix: ' with ');
|
| - writeTypes(interfaces, prefix: ' implements ');
|
| - writeln(' {');
|
| - if (memberWriter != null) {
|
| - writeln();
|
| - memberWriter();
|
| - writeln();
|
| - }
|
| - write('}');
|
| - }
|
| -
|
| - @override
|
| - void writeConstructorDeclaration(String className,
|
| - {ArgumentList argumentList,
|
| - SimpleIdentifier constructorName,
|
| - String constructorNameGroupName,
|
| - List<String> fieldNames,
|
| - bool isConst: false}) {
|
| - if (isConst) {
|
| - write(Keyword.CONST.lexeme);
|
| - write(' ');
|
| - }
|
| - write(className);
|
| - if (constructorName != null) {
|
| - write('.');
|
| - if (constructorNameGroupName == null) {
|
| - write(constructorName.name);
|
| - } else {
|
| - addLinkedEdit(constructorNameGroupName, (LinkedEditBuilder builder) {
|
| - write(constructorName.name);
|
| - });
|
| - }
|
| - }
|
| - write('(');
|
| - if (argumentList != null) {
|
| - writeParametersMatchingArguments(argumentList);
|
| - } else if (fieldNames != null) {
|
| - for (int i = 0; i < fieldNames.length; i++) {
|
| - if (i > 0) {
|
| - write(', ');
|
| - }
|
| - write('this.');
|
| - write(fieldNames[i]);
|
| - }
|
| - }
|
| - write(');');
|
| - }
|
| -
|
| - @override
|
| - void writeFieldDeclaration(String name,
|
| - {void initializerWriter(),
|
| - bool isConst: false,
|
| - bool isFinal: false,
|
| - bool isStatic: false,
|
| - String nameGroupName,
|
| - DartType type,
|
| - String typeGroupName}) {
|
| - if (isStatic) {
|
| - write(Keyword.STATIC.lexeme);
|
| - write(' ');
|
| - }
|
| - bool typeRequired = true;
|
| - if (isConst) {
|
| - write(Keyword.CONST.lexeme);
|
| - typeRequired = false;
|
| - } else if (isFinal) {
|
| - write(Keyword.FINAL.lexeme);
|
| - typeRequired = false;
|
| - }
|
| - if (type != null) {
|
| - writeType(type, groupName: typeGroupName, required: true);
|
| - } else if (typeRequired) {
|
| - write(Keyword.VAR.lexeme);
|
| - }
|
| - write(' ');
|
| - if (nameGroupName != null) {
|
| - addLinkedEdit(nameGroupName, (LinkedEditBuilder builder) {
|
| - write(name);
|
| - });
|
| - } else {
|
| - write(name);
|
| - }
|
| - if (initializerWriter != null) {
|
| - write(' = ');
|
| - initializerWriter();
|
| - }
|
| - write(';');
|
| - }
|
| -
|
| - @override
|
| - void writeFunctionDeclaration(String name,
|
| - {void bodyWriter(),
|
| - bool isStatic: false,
|
| - String nameGroupName,
|
| - void parameterWriter(),
|
| - DartType returnType,
|
| - String returnTypeGroupName}) {
|
| - if (isStatic) {
|
| - write(Keyword.STATIC.lexeme);
|
| - write(' ');
|
| - }
|
| - if (returnType != null) {
|
| - writeType(returnType, groupName: returnTypeGroupName);
|
| - write(' ');
|
| - }
|
| - if (nameGroupName != null) {
|
| - addLinkedEdit(nameGroupName, (LinkedEditBuilder builder) {
|
| - write(name);
|
| - });
|
| - } else {
|
| - write(name);
|
| - }
|
| - write('(');
|
| - if (parameterWriter != null) {
|
| - parameterWriter();
|
| - }
|
| - write(')');
|
| - if (bodyWriter == null) {
|
| - if (returnType != null) {
|
| - write(' => null;');
|
| - } else {
|
| - write(' {}');
|
| - }
|
| - } else {
|
| - write(' ');
|
| - bodyWriter();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - void writeGetterDeclaration(String name,
|
| - {void bodyWriter(),
|
| - bool isStatic: false,
|
| - String nameGroupName,
|
| - DartType returnType,
|
| - String returnTypeGroupName}) {
|
| - if (isStatic) {
|
| - write(Keyword.STATIC.lexeme);
|
| - write(' ');
|
| - }
|
| - if (returnType != null && !returnType.isDynamic) {
|
| - writeType(returnType, groupName: returnTypeGroupName);
|
| - write(' ');
|
| - }
|
| - write(Keyword.GET.lexeme);
|
| - write(' ');
|
| - if (nameGroupName != null) {
|
| - addLinkedEdit(nameGroupName, (LinkedEditBuilder builder) {
|
| - write(name);
|
| - });
|
| - } else {
|
| - write(name);
|
| - }
|
| - if (bodyWriter == null) {
|
| - write(' => null;');
|
| - } else {
|
| - write(' ');
|
| - bodyWriter();
|
| - }
|
| - }
|
| -
|
| - @override
|
| - void writeLocalVariableDeclaration(String name,
|
| - {void initializerWriter(),
|
| - bool isConst: false,
|
| - bool isFinal: false,
|
| - String nameGroupName,
|
| - DartType type,
|
| - String typeGroupName}) {
|
| - bool typeRequired = true;
|
| - if (isConst) {
|
| - write(Keyword.CONST.lexeme);
|
| - typeRequired = false;
|
| - } else if (isFinal) {
|
| - write(Keyword.FINAL.lexeme);
|
| - typeRequired = false;
|
| - }
|
| - if (type != null) {
|
| - if (!typeRequired) {
|
| - // The type is required unless we're written a keyword.
|
| - write(' ');
|
| - }
|
| - writeType(type, groupName: typeGroupName);
|
| - } else if (typeRequired) {
|
| - write(Keyword.VAR.lexeme);
|
| - }
|
| - write(' ');
|
| - if (nameGroupName != null) {
|
| - addLinkedEdit(nameGroupName, (LinkedEditBuilder builder) {
|
| - write(name);
|
| - });
|
| - } else {
|
| - write(name);
|
| - }
|
| - if (initializerWriter != null) {
|
| - write(' = ');
|
| - initializerWriter();
|
| - }
|
| - write(';');
|
| - }
|
| -
|
| - @override
|
| - void writeOverrideOfInheritedMember(ExecutableElement member,
|
| - {String returnTypeGroupName}) {
|
| - // prepare environment
|
| - String prefix = getIndent(1);
|
| - // may be property
|
| - String prefix2 = getIndent(2);
|
| - ElementKind elementKind = member.kind;
|
| - bool isGetter = elementKind == ElementKind.GETTER;
|
| - bool isSetter = elementKind == ElementKind.SETTER;
|
| - bool isMethod = elementKind == ElementKind.METHOD;
|
| - bool isOperator = isMethod && (member as MethodElement).isOperator;
|
| - write(prefix);
|
| - if (isGetter) {
|
| - writeln('// TODO: implement ${member.displayName}');
|
| - write(prefix);
|
| - }
|
| - // @override
|
| - writeln('@override');
|
| - write(prefix);
|
| - // return type
|
| - bool shouldReturn =
|
| - writeType(member.type.returnType, groupName: returnTypeGroupName);
|
| - write(' ');
|
| - if (isGetter) {
|
| - write(Keyword.GET.lexeme);
|
| - write(' ');
|
| - } else if (isSetter) {
|
| - write(Keyword.SET.lexeme);
|
| - write(' ');
|
| - } else if (isOperator) {
|
| - write(Keyword.OPERATOR.lexeme);
|
| - write(' ');
|
| - }
|
| - // name
|
| - write(member.displayName);
|
| - // parameters + body
|
| - if (isGetter) {
|
| - writeln(' => null;');
|
| - } else {
|
| - List<ParameterElement> parameters = member.parameters;
|
| - writeParameters(parameters);
|
| - writeln(' {');
|
| - // TO-DO
|
| - write(prefix2);
|
| - writeln('// TODO: implement ${member.displayName}');
|
| - // REVIEW: Added return statement.
|
| - if (shouldReturn) {
|
| - write(prefix2);
|
| - writeln('return null;');
|
| - }
|
| - // close method
|
| - write(prefix);
|
| - writeln('}');
|
| - }
|
| - }
|
| -
|
| - @override
|
| - void writeParameterMatchingArgument(
|
| - Expression argument, int index, Set<String> usedNames) {
|
| - // append type name
|
| - DartType type = argument.bestType;
|
| - if (writeType(type, addSupertypeProposals: true, groupName: 'TYPE$index')) {
|
| - write(' ');
|
| - }
|
| - // append parameter name
|
| - if (argument is NamedExpression) {
|
| - write(argument.name.label.name);
|
| - } else {
|
| - List<String> suggestions =
|
| - _getParameterNameSuggestions(usedNames, type, argument, index);
|
| - String favorite = suggestions[0];
|
| - usedNames.add(favorite);
|
| - addLinkedEdit('PARAM$index', (LinkedEditBuilder builder) {
|
| - write(favorite);
|
| - builder.addSuggestions(LinkedEditSuggestionKind.PARAMETER, suggestions);
|
| - });
|
| - }
|
| - }
|
| -
|
| - @override
|
| - void writeParameters(Iterable<ParameterElement> parameters) {
|
| - write('(');
|
| - bool sawNamed = false;
|
| - bool sawPositional = false;
|
| - for (int i = 0; i < parameters.length; i++) {
|
| - ParameterElement parameter = parameters.elementAt(i);
|
| - if (i > 0) {
|
| - write(', ');
|
| - }
|
| - // may be optional
|
| - ParameterKind parameterKind = parameter.parameterKind;
|
| - if (parameterKind == ParameterKind.NAMED) {
|
| - if (!sawNamed) {
|
| - write('{');
|
| - sawNamed = true;
|
| - }
|
| - }
|
| - if (parameterKind == ParameterKind.POSITIONAL) {
|
| - if (!sawPositional) {
|
| - write('[');
|
| - sawPositional = true;
|
| - }
|
| - }
|
| - // parameter
|
| - writeParameterSource(parameter.type, parameter.name);
|
| - // default value
|
| - String defaultCode = parameter.defaultValueCode;
|
| - if (defaultCode != null) {
|
| - if (sawPositional) {
|
| - write(' = ');
|
| - } else {
|
| - write(': ');
|
| - }
|
| - write(defaultCode);
|
| - }
|
| - }
|
| - // close parameters
|
| - if (sawNamed) {
|
| - write('}');
|
| - }
|
| - if (sawPositional) {
|
| - write(']');
|
| - }
|
| - write(')');
|
| - }
|
| -
|
| - @override
|
| - void writeParametersMatchingArguments(ArgumentList argumentList) {
|
| - // TODO(brianwilkerson) Handle the case when there are required parameters
|
| - // after named parameters.
|
| - Set<String> usedNames = new Set<String>();
|
| - List<Expression> arguments = argumentList.arguments;
|
| - bool hasNamedParameters = false;
|
| - for (int i = 0; i < arguments.length; i++) {
|
| - Expression argument = arguments[i];
|
| - if (i > 0) {
|
| - write(', ');
|
| - }
|
| - if (argument is NamedExpression && !hasNamedParameters) {
|
| - hasNamedParameters = true;
|
| - write('{');
|
| - }
|
| - writeParameterMatchingArgument(argument, i, usedNames);
|
| - }
|
| - if (hasNamedParameters) {
|
| - write('}');
|
| - }
|
| - }
|
| -
|
| - @override
|
| - void writeParameterSource(DartType type, String name) {
|
| - _EnclosingElementFinder finder = new _EnclosingElementFinder();
|
| - finder.find(dartFileEditBuilder.unit, offset);
|
| - String parameterSource = _getParameterSource(
|
| - type, name, finder.enclosingClass, finder.enclosingExecutable);
|
| - write(parameterSource);
|
| - }
|
| -
|
| - @override
|
| - bool writeType(DartType type,
|
| - {bool addSupertypeProposals: false,
|
| - String groupName,
|
| - bool required: false}) {
|
| - if (type != null && !type.isDynamic) {
|
| - _EnclosingElementFinder finder = new _EnclosingElementFinder();
|
| - finder.find(dartFileEditBuilder.unit, offset);
|
| - String typeSource = _getTypeSource(
|
| - type, finder.enclosingClass, finder.enclosingExecutable);
|
| - if (typeSource != 'dynamic') {
|
| - if (groupName != null) {
|
| - addLinkedEdit(groupName, (LinkedEditBuilder builder) {
|
| - write(typeSource);
|
| - if (addSupertypeProposals) {
|
| - _addSuperTypeProposals(builder, type, new Set<DartType>());
|
| - }
|
| - });
|
| - } else {
|
| - write(typeSource);
|
| - }
|
| - return true;
|
| - }
|
| - }
|
| - if (required) {
|
| - write(Keyword.VAR.lexeme);
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - @override
|
| - void writeTypeParameter(TypeParameterElement typeParameter) {
|
| - write(typeParameter.name);
|
| - if (typeParameter.bound != null) {
|
| - write(' extends ');
|
| - writeType(typeParameter.bound);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - void writeTypeParameters(List<TypeParameterElement> typeParameters) {
|
| - if (typeParameters.isNotEmpty) {
|
| - write('<');
|
| - bool isFirst = true;
|
| - for (TypeParameterElement typeParameter in typeParameters) {
|
| - if (!isFirst) {
|
| - write(', ');
|
| - }
|
| - isFirst = false;
|
| - writeTypeParameter(typeParameter);
|
| - }
|
| - write('>');
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Write the code for a comma-separated list of [types], optionally prefixed
|
| - * by a [prefix]. If the list of [types] is `null` or does not return any
|
| - * types, then nothing will be written.
|
| - */
|
| - void writeTypes(Iterable<DartType> types, {String prefix}) {
|
| - if (types == null || types.isEmpty) {
|
| - return;
|
| - }
|
| - bool first = true;
|
| - for (DartType type in types) {
|
| - if (first) {
|
| - if (prefix != null) {
|
| - write(prefix);
|
| - }
|
| - first = false;
|
| - } else {
|
| - write(', ');
|
| - }
|
| - writeType(type);
|
| - }
|
| - }
|
| -
|
| - void _addSuperTypeProposals(
|
| - LinkedEditBuilder builder, DartType type, Set<DartType> alreadyAdded) {
|
| - if (type != null &&
|
| - type.element is ClassElement &&
|
| - alreadyAdded.add(type)) {
|
| - ClassElement element = type.element as ClassElement;
|
| - builder.addSuggestion(LinkedEditSuggestionKind.TYPE, element.name);
|
| - _addSuperTypeProposals(builder, element.supertype, alreadyAdded);
|
| - for (InterfaceType interfaceType in element.interfaces) {
|
| - _addSuperTypeProposals(builder, interfaceType, alreadyAdded);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Return the import element used to import the given [element] into the given
|
| - * [library], or `null` if the element was not imported, such as when the
|
| - * element is declared in the same library.
|
| - */
|
| - ImportElement _getImportElement(Element element, LibraryElement library) {
|
| - for (ImportElement imp in library.imports) {
|
| - Map<String, Element> definedNames = getImportNamespace(imp);
|
| - if (definedNames.containsValue(element)) {
|
| - return imp;
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Return a list containing the suggested names for a parameter with the given
|
| - * [type] whose value in one location is computed by the given [expression].
|
| - * The list will not contain any names in the set of [excluded] names. The
|
| - * [index] is the index of the argument, used to create a name if no better
|
| - * name could be created. The first name in the list will be the best name.
|
| - */
|
| - List<String> _getParameterNameSuggestions(
|
| - Set<String> usedNames, DartType type, Expression expression, int index) {
|
| - List<String> suggestions =
|
| - getVariableNameSuggestionsForExpression(type, expression, usedNames);
|
| - if (suggestions.length != 0) {
|
| - return suggestions;
|
| - }
|
| - // TODO(brianwilkerson) Verify that the name below is not in the set of used names.
|
| - return <String>['param$index'];
|
| - }
|
| -
|
| - /**
|
| - * Return the source for the parameter with the given [type] and [name].
|
| - */
|
| - String _getParameterSource(DartType type, String name,
|
| - ClassElement enclosingClass, ExecutableElement enclosingExecutable) {
|
| - // no type
|
| - if (type == null || type.isDynamic) {
|
| - return name;
|
| - }
|
| - // function type
|
| - if (type is FunctionType && type.element.isSynthetic) {
|
| - FunctionType functionType = type;
|
| - StringBuffer sb = new StringBuffer();
|
| - // return type
|
| - DartType returnType = functionType.returnType;
|
| - if (returnType != null && !returnType.isDynamic) {
|
| - String returnTypeSource =
|
| - _getTypeSource(returnType, enclosingClass, enclosingExecutable);
|
| - sb.write(returnTypeSource);
|
| - sb.write(' ');
|
| - }
|
| - // parameter name
|
| - sb.write(name);
|
| - // parameters
|
| - sb.write('(');
|
| - List<ParameterElement> fParameters = functionType.parameters;
|
| - for (int i = 0; i < fParameters.length; i++) {
|
| - ParameterElement fParameter = fParameters[i];
|
| - if (i != 0) {
|
| - sb.write(", ");
|
| - }
|
| - sb.write(_getParameterSource(fParameter.type, fParameter.name,
|
| - enclosingClass, enclosingExecutable));
|
| - }
|
| - sb.write(')');
|
| - // done
|
| - return sb.toString();
|
| - }
|
| - // simple type
|
| - String typeSource =
|
| - _getTypeSource(type, enclosingClass, enclosingExecutable);
|
| - return '$typeSource $name';
|
| - }
|
| -
|
| - /**
|
| - * Returns the source to reference [type] in this [CompilationUnit].
|
| - *
|
| - * Fills [librariesToImport] with [LibraryElement]s whose elements are
|
| - * used by the generated source, but not imported.
|
| - */
|
| - String _getTypeSource(DartType type, ClassElement enclosingClass,
|
| - ExecutableElement enclosingExecutable,
|
| - {StringBuffer parametersBuffer}) {
|
| - StringBuffer sb = new StringBuffer();
|
| - // type parameter
|
| - if (!_isTypeVisible(type, enclosingClass, enclosingExecutable)) {
|
| - return 'dynamic';
|
| - }
|
| - // just a Function, not FunctionTypeAliasElement
|
| - if (type is FunctionType && type.element is! FunctionTypeAliasElement) {
|
| - if (parametersBuffer == null) {
|
| - return "Function";
|
| - }
|
| - parametersBuffer.write('(');
|
| - for (ParameterElement parameter in type.parameters) {
|
| - String parameterType =
|
| - _getTypeSource(parameter.type, enclosingClass, enclosingExecutable);
|
| - if (parametersBuffer.length != 1) {
|
| - parametersBuffer.write(', ');
|
| - }
|
| - parametersBuffer.write(parameterType);
|
| - parametersBuffer.write(' ');
|
| - parametersBuffer.write(parameter.name);
|
| - }
|
| - parametersBuffer.write(')');
|
| - return _getTypeSource(
|
| - type.returnType, enclosingClass, enclosingExecutable);
|
| - }
|
| - // <Bottom>, Null
|
| - if (type.isBottom || type.isDartCoreNull) {
|
| - return 'dynamic';
|
| - }
|
| - // prepare element
|
| - Element element = type.element;
|
| - if (element == null) {
|
| - String source = type.toString();
|
| - source = source.replaceAll('<dynamic>', '');
|
| - source = source.replaceAll('<dynamic, dynamic>', '');
|
| - return source;
|
| - }
|
| - // check if imported
|
| - LibraryElement definingLibrary = element.library;
|
| - LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
|
| - if (definingLibrary != null && definingLibrary != importingLibrary) {
|
| - // no source, if private
|
| - if (element.isPrivate) {
|
| - return null;
|
| - }
|
| - // ensure import
|
| - ImportElement importElement =
|
| - _getImportElement(element, importingLibrary);
|
| - if (importElement != null) {
|
| - if (importElement.prefix != null) {
|
| - sb.write(importElement.prefix.displayName);
|
| - sb.write(".");
|
| - }
|
| - } else {
|
| - importLibrary(definingLibrary.source);
|
| - }
|
| - }
|
| - // append simple name
|
| - String name = element.displayName;
|
| - sb.write(name);
|
| - // may be type arguments
|
| - if (type is ParameterizedType) {
|
| - List<DartType> arguments = type.typeArguments;
|
| - // check if has arguments
|
| - bool hasArguments = false;
|
| - bool allArgumentsVisible = true;
|
| - for (DartType argument in arguments) {
|
| - hasArguments = hasArguments || !argument.isDynamic;
|
| - allArgumentsVisible = allArgumentsVisible &&
|
| - _isTypeVisible(argument, enclosingClass, enclosingExecutable);
|
| - }
|
| - // append type arguments
|
| - if (hasArguments && allArgumentsVisible) {
|
| - sb.write("<");
|
| - for (int i = 0; i < arguments.length; i++) {
|
| - DartType argument = arguments[i];
|
| - if (i != 0) {
|
| - sb.write(", ");
|
| - }
|
| - String argumentSrc =
|
| - _getTypeSource(argument, enclosingClass, enclosingExecutable);
|
| - if (argumentSrc != null) {
|
| - sb.write(argumentSrc);
|
| - } else {
|
| - return null;
|
| - }
|
| - }
|
| - sb.write(">");
|
| - }
|
| - }
|
| - // done
|
| - return sb.toString();
|
| - }
|
| -
|
| - /**
|
| - * Checks if [type] is visible in either the [enclosingExecutable] or
|
| - * [enclosingClass].
|
| - */
|
| - bool _isTypeVisible(DartType type, ClassElement enclosingClass,
|
| - ExecutableElement enclosingExecutable) {
|
| - if (type is TypeParameterType) {
|
| - TypeParameterElement parameterElement = type.element;
|
| - Element parameterParent = parameterElement.enclosingElement;
|
| - // TODO(brianwilkerson) This needs to compare the parameterParent with
|
| - // each of the parents of the enclosingElement. (That means that we only
|
| - // need the most closely enclosing element.)
|
| - return identical(parameterParent, enclosingExecutable) ||
|
| - identical(parameterParent, enclosingClass);
|
| - }
|
| - return true;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A [FileEditBuilder] used to build edits for Dart files.
|
| - */
|
| -class DartFileEditBuilderImpl extends FileEditBuilderImpl
|
| - implements DartFileEditBuilder {
|
| - /**
|
| - * The compilation unit to which the code will be added.
|
| - */
|
| - CompilationUnit unit;
|
| -
|
| - /**
|
| - * A set containing the sources of the libraries that need to be imported in
|
| - * order to make visible the names used in generated code.
|
| - */
|
| - Set<Source> librariesToImport = new Set<Source>();
|
| -
|
| - /**
|
| - * The content of the file being edited.
|
| - */
|
| - String _content;
|
| -
|
| - /**
|
| - * Initialize a newly created builder to build a source file edit within the
|
| - * change being built by the given [changeBuilder]. The file being edited has
|
| - * the given [source] and [timeStamp], and the given fully resolved [unit].
|
| - */
|
| - DartFileEditBuilderImpl(DartChangeBuilderImpl changeBuilder, String path,
|
| - int timeStamp, this.unit)
|
| - : super(changeBuilder, path, timeStamp);
|
| -
|
| - @override
|
| - void convertFunctionFromSyncToAsync(
|
| - FunctionBody body, TypeProvider typeProvider) {
|
| - if (body == null && body.keyword != null) {
|
| - throw new ArgumentError(
|
| - 'The function must have a synchronous, non-generator body.');
|
| - }
|
| - addInsertion(body.offset, (EditBuilder builder) {
|
| - builder.write('async ');
|
| - });
|
| - _replaceReturnTypeWithFuture(body, typeProvider);
|
| - }
|
| -
|
| - @override
|
| - DartEditBuilderImpl createEditBuilder(int offset, int length) {
|
| - return new DartEditBuilderImpl(this, offset, length);
|
| - }
|
| -
|
| - @override
|
| - void finalize() {
|
| - addLibraryImports(
|
| - changeBuilder.sourceChange, unit.element.library, librariesToImport);
|
| - }
|
| -
|
| - /**
|
| - * Return the content of the file being edited.
|
| - */
|
| - String getContent() {
|
| - if (_content == null) {
|
| - CompilationUnitElement unitElement = unit.element;
|
| - AnalysisContext context = unitElement.context;
|
| - if (context == null) {
|
| - throw new CancelCorrectionException();
|
| - }
|
| - _content = context.getContents(unitElement.source).data;
|
| - }
|
| - return _content;
|
| - }
|
| -
|
| - @override
|
| - void importLibraries(Iterable<Source> libraries) {
|
| - librariesToImport.addAll(libraries);
|
| - }
|
| -
|
| - @override
|
| - void replaceTypeWithFuture(
|
| - TypeAnnotation typeAnnotation, TypeProvider typeProvider) {
|
| - InterfaceType futureType = typeProvider.futureType;
|
| - //
|
| - // Check whether the type needs to be replaced.
|
| - //
|
| - DartType type = typeAnnotation?.type;
|
| - if (type == null ||
|
| - type.isDynamic ||
|
| - type is InterfaceType && type.element == futureType.element) {
|
| - return;
|
| - }
|
| - futureType = futureType.instantiate(<DartType>[type]);
|
| - // prepare code for the types
|
| - addReplacement(rangeNode(typeAnnotation), (EditBuilder builder) {
|
| - if (!(builder as DartEditBuilder).writeType(futureType)) {
|
| - builder.write('void');
|
| - }
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * Returns the text of the given [AstNode] in the unit.
|
| - */
|
| - String _getNodeText(AstNode node) {
|
| - return _getText(node.offset, node.length);
|
| - }
|
| -
|
| - /**
|
| - * Returns the text of the given range in the unit.
|
| - */
|
| - String _getText(int offset, int length) {
|
| - return getContent().substring(offset, offset + length);
|
| - }
|
| -
|
| - /**
|
| - * Create an edit to replace the return type of the innermost function
|
| - * containing the given [node] with the type `Future`. The [typeProvider] is
|
| - * used to check the current return type, because if it is already `Future` no
|
| - * edit will be added.
|
| - */
|
| - void _replaceReturnTypeWithFuture(AstNode node, TypeProvider typeProvider) {
|
| - while (node != null) {
|
| - node = node.parent;
|
| - if (node is FunctionDeclaration) {
|
| - replaceTypeWithFuture(node.returnType, typeProvider);
|
| - return;
|
| - } else if (node is MethodDeclaration) {
|
| - replaceTypeWithFuture(node.returnType, typeProvider);
|
| - return;
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A [LinkedEditBuilder] used to build linked edits for Dart files.
|
| - *
|
| - * Clients may not extend, implement or mix-in this class.
|
| - */
|
| -class DartLinkedEditBuilderImpl extends LinkedEditBuilderImpl
|
| - implements DartLinkedEditBuilder {
|
| - /**
|
| - * Initialize a newly created linked edit builder.
|
| - */
|
| - DartLinkedEditBuilderImpl(EditBuilderImpl editBuilder) : super(editBuilder);
|
| -
|
| - @override
|
| - void addSuperTypesAsSuggestions(DartType type) {
|
| - _addSuperTypesAsSuggestions(type, new Set<DartType>());
|
| - }
|
| -
|
| - /**
|
| - * Safely implement [addSuperTypesAsSuggestions] by using the set of
|
| - * [alreadyAdded] types to prevent infinite loops.
|
| - */
|
| - void _addSuperTypesAsSuggestions(DartType type, Set<DartType> alreadyAdded) {
|
| - if (type is InterfaceType && alreadyAdded.add(type)) {
|
| - addSuggestion(LinkedEditSuggestionKind.TYPE, type.displayName);
|
| - _addSuperTypesAsSuggestions(type.superclass, alreadyAdded);
|
| - for (InterfaceType interfaceType in type.interfaces) {
|
| - _addSuperTypesAsSuggestions(interfaceType, alreadyAdded);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -class _EnclosingElementFinder {
|
| - ClassElement enclosingClass;
|
| - ExecutableElement enclosingExecutable;
|
| -
|
| - _EnclosingElementFinder();
|
| -
|
| - void find(AstNode target, int offset) {
|
| - AstNode node = new NodeLocator2(offset).searchWithin(target);
|
| - while (node != null) {
|
| - if (node is ClassDeclaration) {
|
| - enclosingClass = node.element;
|
| - } else if (node is ConstructorDeclaration) {
|
| - enclosingExecutable = node.element;
|
| - } else if (node is MethodDeclaration) {
|
| - enclosingExecutable = node.element;
|
| - } else if (node is FunctionDeclaration) {
|
| - enclosingExecutable = node.element;
|
| - }
|
| - node = node.parent;
|
| - }
|
| - }
|
| -}
|
|
|