mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:30:32 +00:00
Use DartEditBuilder to write types and remove dead code
R=scheglov@google.com Review-Url: https://codereview.chromium.org/2972463003 .
This commit is contained in:
parent
d31ed8690e
commit
aadafd1bd5
|
@ -221,26 +221,26 @@ class AssistProcessor {
|
|||
return;
|
||||
}
|
||||
_configureTargetLocation(node);
|
||||
Set<Source> librariesToImport = new Set<Source>();
|
||||
String typeSource = utils.getTypeSource(type, librariesToImport);
|
||||
if (typeSource == null) {
|
||||
// The type source might be null if the type is private.
|
||||
_coverageMarker();
|
||||
return;
|
||||
}
|
||||
|
||||
DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
|
||||
bool validChange = true;
|
||||
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
|
||||
Token keyword = declaredIdentifier.keyword;
|
||||
if (keyword.keyword == Keyword.VAR) {
|
||||
builder.addSimpleReplacement(range.token(keyword), typeSource);
|
||||
builder.addReplacement(range.token(keyword), (DartEditBuilder builder) {
|
||||
validChange = builder.writeType(type);
|
||||
});
|
||||
} else {
|
||||
builder.addSimpleInsertion(
|
||||
declaredIdentifier.identifier.offset, '$typeSource ');
|
||||
builder.addInsertion(declaredIdentifier.identifier.offset,
|
||||
(DartEditBuilder builder) {
|
||||
validChange = builder.writeType(type);
|
||||
builder.write(' ');
|
||||
});
|
||||
}
|
||||
builder.importLibraries(librariesToImport);
|
||||
});
|
||||
_addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
|
||||
if (validChange) {
|
||||
_addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> _addProposal_addTypeAnnotation_SimpleFormalParameter() async {
|
||||
|
@ -269,20 +269,18 @@ class AssistProcessor {
|
|||
}
|
||||
// prepare type source
|
||||
_configureTargetLocation(node);
|
||||
Set<Source> librariesToImport = new Set<Source>();
|
||||
String typeSource = utils.getTypeSource(type, librariesToImport);
|
||||
// type source might be null, if the type is private
|
||||
if (typeSource == null) {
|
||||
_coverageMarker();
|
||||
return;
|
||||
}
|
||||
|
||||
DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
|
||||
bool validChange = true;
|
||||
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
|
||||
builder.addSimpleInsertion(name.offset, '$typeSource ');
|
||||
builder.importLibraries(librariesToImport);
|
||||
builder.addInsertion(name.offset, (DartEditBuilder builder) {
|
||||
validChange = builder.writeType(type);
|
||||
builder.write(' ');
|
||||
});
|
||||
});
|
||||
_addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
|
||||
if (validChange) {
|
||||
_addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> _addProposal_addTypeAnnotation_VariableDeclaration() async {
|
||||
|
@ -325,42 +323,25 @@ class AssistProcessor {
|
|||
return;
|
||||
}
|
||||
_configureTargetLocation(node);
|
||||
Set<Source> librariesToImport = new Set<Source>();
|
||||
String typeSource = utils.getTypeSource(type, librariesToImport);
|
||||
// type source might be null, if the type is private
|
||||
if (typeSource == null) {
|
||||
_coverageMarker();
|
||||
return;
|
||||
}
|
||||
|
||||
DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
|
||||
if (unitLibraryFile == file) {
|
||||
// TODO(brianwilkerson) Make ChangeBuilder merge multiple edits to the
|
||||
// same file so that only the else block is necessary.
|
||||
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
|
||||
Token keyword = declarationList.keyword;
|
||||
if (keyword?.keyword == Keyword.VAR) {
|
||||
builder.addSimpleReplacement(range.token(keyword), typeSource);
|
||||
} else {
|
||||
builder.addSimpleInsertion(variable.offset, '$typeSource ');
|
||||
}
|
||||
builder.importLibraries(librariesToImport);
|
||||
});
|
||||
} else {
|
||||
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
|
||||
Token keyword = declarationList.keyword;
|
||||
if (keyword?.keyword == Keyword.VAR) {
|
||||
builder.addSimpleReplacement(range.token(keyword), typeSource);
|
||||
} else {
|
||||
builder.addSimpleInsertion(variable.offset, '$typeSource ');
|
||||
}
|
||||
});
|
||||
await changeBuilder.addFileEdit(unitLibraryFile,
|
||||
(DartFileEditBuilder builder) {
|
||||
builder.importLibraries(librariesToImport);
|
||||
});
|
||||
bool validChange = true;
|
||||
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
|
||||
Token keyword = declarationList.keyword;
|
||||
if (keyword?.keyword == Keyword.VAR) {
|
||||
builder.addReplacement(range.token(keyword), (DartEditBuilder builder) {
|
||||
validChange = builder.writeType(type);
|
||||
});
|
||||
} else {
|
||||
builder.addInsertion(variable.offset, (DartEditBuilder builder) {
|
||||
validChange = builder.writeType(type);
|
||||
builder.write(' ');
|
||||
});
|
||||
}
|
||||
});
|
||||
if (validChange) {
|
||||
_addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
|
||||
}
|
||||
_addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION);
|
||||
}
|
||||
|
||||
Future<Null> _addProposal_assignToLocalVariable() async {
|
||||
|
@ -1091,8 +1072,6 @@ class AssistProcessor {
|
|||
String name = (node as SimpleIdentifier).name;
|
||||
// prepare type
|
||||
DartType type = parameterElement.type;
|
||||
Set<Source> librariesToImport = new Set<Source>();
|
||||
String typeCode = utils.getTypeSource(type, librariesToImport);
|
||||
|
||||
DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
|
||||
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
|
||||
|
@ -1100,8 +1079,12 @@ class AssistProcessor {
|
|||
if (type.isDynamic) {
|
||||
builder.addSimpleReplacement(range.node(parameter), name);
|
||||
} else {
|
||||
builder.addSimpleReplacement(
|
||||
range.node(parameter), '$typeCode $name');
|
||||
builder.addReplacement(range.node(parameter),
|
||||
(DartEditBuilder builder) {
|
||||
builder.writeType(type);
|
||||
builder.write(' ');
|
||||
builder.write(name);
|
||||
});
|
||||
}
|
||||
// add field initializer
|
||||
List<ConstructorInitializer> initializers = constructor.initializers;
|
||||
|
|
|
@ -709,17 +709,6 @@ class CorrectionUtils {
|
|||
return _endOfLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an [Edit] that changes indentation of the source of the given
|
||||
* [SourceRange] from [oldIndent] to [newIndent], keeping indentation of lines
|
||||
* relative to each other.
|
||||
*/
|
||||
SourceEdit createIndentEdit(
|
||||
SourceRange range, String oldIndent, String newIndent) {
|
||||
String newSource = replaceSourceRangeIndent(range, oldIndent, newIndent);
|
||||
return new SourceEdit(range.offset, range.length, newSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the [AstNode] that encloses the given offset.
|
||||
*/
|
||||
|
@ -742,82 +731,11 @@ class CorrectionUtils {
|
|||
return conflicts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual type source of the given [Expression], may be `null`
|
||||
* if can not be resolved, should be treated as the `dynamic` type.
|
||||
*/
|
||||
String getExpressionTypeSource(
|
||||
Expression expression, Set<Source> librariesToImport) {
|
||||
if (expression == null) {
|
||||
return null;
|
||||
}
|
||||
DartType type = expression.bestType;
|
||||
if (type.isDynamic) {
|
||||
return null;
|
||||
}
|
||||
return getTypeSource(type, librariesToImport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the indentation with the given level.
|
||||
*/
|
||||
String getIndent(int level) => repeat(' ', level);
|
||||
|
||||
/**
|
||||
* Returns a [InsertDesc] describing where to insert a new library-related
|
||||
* directive.
|
||||
*/
|
||||
CorrectionUtils_InsertDesc getInsertDescImport() {
|
||||
// analyze directives
|
||||
Directive prevDirective = null;
|
||||
for (Directive directive in unit.directives) {
|
||||
if (directive is LibraryDirective ||
|
||||
directive is ImportDirective ||
|
||||
directive is ExportDirective) {
|
||||
prevDirective = directive;
|
||||
}
|
||||
}
|
||||
// insert after last library-related directive
|
||||
if (prevDirective != null) {
|
||||
CorrectionUtils_InsertDesc result = new CorrectionUtils_InsertDesc();
|
||||
result.offset = prevDirective.end;
|
||||
String eol = endOfLine;
|
||||
if (prevDirective is LibraryDirective) {
|
||||
result.prefix = "$eol$eol";
|
||||
} else {
|
||||
result.prefix = eol;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// no directives, use "top" location
|
||||
return getInsertDescTop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [InsertDesc] describing where to insert a new 'part' directive.
|
||||
*/
|
||||
CorrectionUtils_InsertDesc getInsertDescPart() {
|
||||
// analyze directives
|
||||
Directive prevDirective = null;
|
||||
for (Directive directive in unit.directives) {
|
||||
prevDirective = directive;
|
||||
}
|
||||
// insert after last directive
|
||||
if (prevDirective != null) {
|
||||
CorrectionUtils_InsertDesc result = new CorrectionUtils_InsertDesc();
|
||||
result.offset = prevDirective.end;
|
||||
String eol = endOfLine;
|
||||
if (prevDirective is PartDirective) {
|
||||
result.prefix = eol;
|
||||
} else {
|
||||
result.prefix = "$eol$eol";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// no directives, use "top" location
|
||||
return getInsertDescTop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [InsertDesc] describing where to insert a new directive or a
|
||||
* top-level declaration at the top of the file.
|
||||
|
@ -1031,48 +949,6 @@ class CorrectionUtils {
|
|||
return getText(node.offset, node.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the source for the parameter with the given type and name.
|
||||
*/
|
||||
String getParameterSource(
|
||||
DartType type, String name, Set<Source> librariesToImport) {
|
||||
// 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, librariesToImport);
|
||||
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, librariesToImport));
|
||||
}
|
||||
sb.write(')');
|
||||
// done
|
||||
return sb.toString();
|
||||
}
|
||||
// simple type
|
||||
String typeSource = getTypeSource(type, librariesToImport);
|
||||
return '$typeSource $name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the line prefix consisting of spaces and tabs on the left from the
|
||||
* given offset.
|
||||
|
|
|
@ -166,7 +166,10 @@ class A<T> {
|
|||
await assertNoAssistAt('var item', DartAssistKind.ADD_TYPE_ANNOTATION);
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_addTypeAnnotation_BAD_privateType_list() async {
|
||||
// This is now failing because we're suggesting "List" rather than nothing.
|
||||
// Is it really better to produce nothing?
|
||||
addSource(
|
||||
'/my_lib.dart',
|
||||
'''
|
||||
|
|
|
@ -486,7 +486,7 @@ class DartEditBuilderImpl extends EditBuilderImpl implements DartEditBuilder {
|
|||
String typeSource = _getTypeSource(
|
||||
type, finder.enclosingClass, finder.enclosingExecutable,
|
||||
methodBeingCopied: methodBeingCopied);
|
||||
if (typeSource != 'dynamic') {
|
||||
if (typeSource.isNotEmpty && typeSource != 'dynamic') {
|
||||
if (groupName != null) {
|
||||
addLinkedEdit(groupName, (LinkedEditBuilder builder) {
|
||||
write(typeSource);
|
||||
|
@ -957,6 +957,17 @@ class DartEditBuilderImpl extends EditBuilderImpl implements DartEditBuilder {
|
|||
parameterParent == enclosingClass ||
|
||||
parameterParent == methodBeingCopied;
|
||||
}
|
||||
Element element = type.element;
|
||||
if (element == null) {
|
||||
return true;
|
||||
}
|
||||
LibraryElement definingLibrary = element.library;
|
||||
LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
|
||||
if (definingLibrary != null && definingLibrary != importingLibrary) {
|
||||
if (element.isPrivate) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1015,8 +1026,19 @@ class DartFileEditBuilderImpl extends FileEditBuilderImpl
|
|||
|
||||
@override
|
||||
void finalize() {
|
||||
_addLibraryImports(
|
||||
changeBuilder.sourceChange, unit.element.library, librariesToImport);
|
||||
CompilationUnitElement unitElement = unit.element;
|
||||
LibraryElement libraryElement = unitElement.library;
|
||||
CompilationUnitElement definingUnitElement =
|
||||
libraryElement.definingCompilationUnit;
|
||||
if (definingUnitElement == unitElement) {
|
||||
_addLibraryImports(libraryElement, librariesToImport);
|
||||
} else {
|
||||
(changeBuilder as DartChangeBuilder).addFileEdit(
|
||||
definingUnitElement.source.fullName, (DartFileEditBuilder builder) {
|
||||
(builder as DartFileEditBuilderImpl)
|
||||
._addLibraryImports(libraryElement, librariesToImport);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1051,11 +1073,10 @@ class DartFileEditBuilderImpl extends FileEditBuilderImpl
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds edits to the given [change] that ensure that all the [libraries] are
|
||||
* imported into the given [targetLibrary].
|
||||
* Adds edits ensure that all the [libraries] are imported into the given
|
||||
* [targetLibrary].
|
||||
*/
|
||||
void _addLibraryImports(SourceChange change, LibraryElement targetLibrary,
|
||||
Set<Source> libraries) {
|
||||
void _addLibraryImports(LibraryElement targetLibrary, Set<Source> libraries) {
|
||||
// Prepare information about existing imports.
|
||||
LibraryDirective libraryDirective;
|
||||
List<ImportDirective> importDirectives = <ImportDirective>[];
|
||||
|
|
|
@ -226,6 +226,8 @@ abstract class DartEditBuilder implements EditBuilder {
|
|||
* If a [methodBeingCopied] is provided, then type parameters defined by that
|
||||
* method are assumed to be part of what is being written and hence valid
|
||||
* types.
|
||||
*
|
||||
* Return `true` if some text was written.
|
||||
*/
|
||||
bool writeType(DartType type,
|
||||
{bool addSupertypeProposals: false,
|
||||
|
|
Loading…
Reference in a new issue