Chromium Code Reviews| Index: pkg/analysis_services/lib/src/refactoring/rename.dart |
| diff --git a/pkg/analysis_services/lib/src/refactoring/rename.dart b/pkg/analysis_services/lib/src/refactoring/rename.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f383eca1a90272e2653817a01791ad99abefca8c |
| --- /dev/null |
| +++ b/pkg/analysis_services/lib/src/refactoring/rename.dart |
| @@ -0,0 +1,218 @@ |
| +// 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. |
| + |
| +// This code was auto-generated, is not intended to be edited, and is subject to |
| +// significant change. Please see the README file for more information. |
| + |
| +library services.src.refactoring.rename; |
| + |
| +import 'package:analysis_services/correction/status.dart'; |
| +import 'package:analysis_services/refactoring/progress_monitor.dart'; |
| +import 'package:analysis_services/refactoring/refactoring.dart'; |
| +import 'package:analysis_services/search/search_engine.dart'; |
| +import 'package:analysis_services/src/correction/source_range.dart'; |
| +import 'package:analysis_services/src/generated/change.dart'; |
| +import 'package:analysis_services/src/refactoring/refactoring.dart'; |
| +import 'package:analyzer/src/generated/element.dart'; |
| +import 'package:analyzer/src/generated/engine.dart'; |
| +import 'package:analyzer/src/generated/source.dart'; |
| + |
| + |
| +/** |
| + * Returns the [Edit] to replace the given [SearchMatch] reference. |
| + */ |
| +Edit createReferenceEdit(SourceReference reference, String newText) { |
| + return new Edit.range(reference.range, newText); |
| +} |
| + |
| + |
| +/** |
| + * Returns `true` if two given [Element]s are [LocalElement]s and have |
| + * intersecting with visibility ranges. |
| + */ |
| +bool haveIntersectingRanges(LocalElement localElement, Element element) { |
| + if (element is! LocalElement) { |
| + return false; |
| + } |
| + LocalElement localElement2 = element as LocalElement; |
| + Source localSource = localElement.source; |
| + Source localSource2 = localElement2.source; |
| + SourceRange localRange = localElement.visibleRange; |
| + SourceRange localRange2 = localElement2.visibleRange; |
| + return localSource2 == localSource && |
| + localRange != null && |
| + localRange2 != null && |
| + localRange2.intersects(localRange); |
| +} |
| + |
| + |
| +/** |
| + * Checks if the given [Element] is in the given [AnalysisContext]. |
| + */ |
| +bool isInContext(Element element, AnalysisContext context) { |
| + AnalysisContext elementContext = element.context; |
| + if (elementContext == context) { |
| + return true; |
| + } |
| + if (context is InstrumentedAnalysisContextImpl) { |
| + return elementContext == context.basis; |
| + } |
| + return false; |
| +} |
| + |
| + |
| +/** |
| + * Checks if the given [Element] is visible in the given [Source]. |
| + */ |
| +bool isInTheSameLibrary(Element element, AnalysisContext context, Source source) |
|
Brian Wilkerson
2014/08/11 16:27:47
The comment and the name don't appear to correspon
scheglov
2014/08/11 18:06:25
I've updated the comment.
|
| + { |
| + // should be the same AnalysisContext |
| + if (!isInContext(element, context)) { |
| + return false; |
| + } |
| + // private elements are visible only in their library |
| + List<Source> librarySourcesOfSource = context.getLibrariesContaining(source); |
| + Source librarySourceOfElement = element.library.source; |
| + return librarySourcesOfSource.contains(librarySourceOfElement); |
| +} |
| + |
| + |
| +/** |
| + * Checks if the given [Element] is visible in the given [Source]. |
| + */ |
| +bool isPublicOrInTheSameLibrary(Element element, AnalysisContext context, |
|
Brian Wilkerson
2014/08/11 16:27:47
This has the same comment as the previous function
scheglov
2014/08/11 18:06:25
I've updated the comment.
|
| + Source source) { |
| + // should be the same AnalysisContext |
| + if (!isInContext(element, context)) { |
| + return false; |
| + } |
| + // public elements are always visible |
| + if (element.isPublic) { |
| + return true; |
| + } |
| + // private elements are visible only in their library |
| + return isInTheSameLibrary(element, context, source); |
| +} |
| + |
| + |
| +/** |
| + * Checks if the given unqualified [SearchMatch] intersects with visibility |
| + * range of [localElement]. |
| + */ |
| +bool isReferenceInLocalRange(LocalElement localElement, SearchMatch reference) { |
| + if (reference.isQualified) { |
| + return false; |
| + } |
| + Source localSource = localElement.source; |
| + Source referenceSource = reference.element.source; |
| + SourceRange localRange = localElement.visibleRange; |
| + SourceRange referenceRange = reference.sourceRange; |
| + return referenceSource == localSource && |
| + referenceRange.intersects(localRange); |
| +} |
| + |
| + |
| +/** |
| + * An abstract implementation of [RenameRefactoring]. |
| + */ |
| +abstract class RenameRefactoringImpl extends RefactoringImpl implements |
| + RenameRefactoring { |
| + final SearchEngine searchEngine; |
| + final Element element; |
| + AnalysisContext context; |
| + String oldName; |
| + |
| + String newName; |
| + |
| + RenameRefactoringImpl(this.searchEngine, this.element) { |
| + this.context = element.context; |
| + this.oldName = _getDisplayName(element); |
| + } |
| + |
| + @override |
| + String get currentName => element.displayName; |
|
Brian Wilkerson
2014/08/11 16:27:47
This seems strange. Should this be "oldName" so th
scheglov
2014/08/11 18:06:25
The "currentName" field is gone now, "oldName" is
|
| + |
| + /** |
| + * Adds the "Update declaration" [Edit] to [sourceChange]. |
| + */ |
| + void addDeclarationEdit(SourceChange sourceChange, Element element) { |
| + Edit edit = new Edit.range(rangeElementName(element), newName); |
| + addEdit(sourceChange, "Update declaration", edit); |
| + } |
| + |
| + /** |
| + * Adds the [Edit] that replaces [oldName] in [sourceChange]. |
| + */ |
| + void addEdit(SourceChange sourceChange, String description, Edit edit) { |
|
Brian Wilkerson
2014/08/11 16:27:47
I don't understand the value of this method. Why i
scheglov
2014/08/11 18:06:25
Done.
|
| + sourceChange.addEdit(edit, description); |
| + } |
| + |
| + /** |
| + * Adds an "Update reference" [Edit] to [sourceChange]. |
| + */ |
| + void addReferenceEdit(SourceChange sourceChange, SourceReference reference) { |
| + Edit edit = createReferenceEdit(reference, newName); |
|
Brian Wilkerson
2014/08/11 16:27:47
As far as I can see, this is the only use of "crea
scheglov
2014/08/11 18:06:25
It will be used by other refactoring implementatio
|
| + addEdit(sourceChange, "Update reference", edit); |
| + } |
| + |
| + @override |
| + RefactoringStatus checkInitialConditions(ProgressMonitor pm) { |
| + return new RefactoringStatus(); |
| + } |
| + |
| + @override |
| + RefactoringStatus checkNewName(String newName) { |
| + RefactoringStatus result = new RefactoringStatus(); |
| + if (newName == currentName) { |
| + result.addFatalError("Choose another name."); |
|
Brian Wilkerson
2014/08/11 16:27:47
Is this user visible text? If so, perhaps somethin
scheglov
2014/08/11 18:06:25
Done.
|
| + } |
| + return result; |
| + } |
| + |
| + static String _getDisplayName(Element element) { |
| + if (element is ImportElement) { |
| + PrefixElement prefix = element.prefix; |
| + if (prefix != null) { |
| + return prefix.displayName; |
| + } |
| + } |
| + return element.displayName; |
| + } |
| +} |
| + |
| + |
| +/** |
| + * The [SourceRange] in some [Source]. |
| + */ |
| +class SourceReference { |
| + final MatchKind kind; |
| + final Source source; |
| + final SourceRange range; |
| + |
| + List<Element> elements = []; |
|
Brian Wilkerson
2014/08/11 16:27:47
This field isn't currently used (at least not in t
scheglov
2014/08/11 18:06:25
Done.
|
| + |
| + SourceReference(this.kind, this.source, this.range); |
| + |
| + @override |
| + int get hashCode { |
| + int hash = source.hashCode; |
| + hash = ((hash << 16) & 0xFFFFFFFF) + range.hashCode; |
| + return hash; |
| + } |
| + |
| + @override |
| + bool operator ==(Object obj) { |
| + if (identical(obj, this)) { |
| + return true; |
| + } |
| + if (obj is! SourceReference) { |
| + return false; |
| + } |
| + SourceReference other = obj as SourceReference; |
| + return other.source == source && other.range == range; |
| + } |
| + |
| + @override |
| + String toString() => '${source}@${range}'; |
| +} |