| // 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.source_buffer; |
| |
| import 'package:analysis_server/src/protocol.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| |
| |
| /** |
| * Helper for building Dart source with linked positions. |
| */ |
| class SourceBuilder { |
| final String file; |
| final int offset; |
| final StringBuffer _buffer = new StringBuffer(); |
| |
| final Map<String, LinkedEditGroup> linkedPositionGroups = <String, |
| LinkedEditGroup>{}; |
| LinkedEditGroup _currentLinkedPositionGroup; |
| int _currentPositionStart; |
| int _exitOffset; |
| |
| SourceBuilder(this.file, this.offset); |
| |
| SourceBuilder.buffer() |
| : file = null, |
| offset = 0; |
| |
| /** |
| * Returns the exit offset, maybe `null` if not set. |
| */ |
| int get exitOffset { |
| if (_exitOffset == null) { |
| return null; |
| } |
| return offset + _exitOffset; |
| } |
| |
| int get length => _buffer.length; |
| |
| void addSuggestion(LinkedEditSuggestionKind kind, String value) { |
| var suggestion = new LinkedEditSuggestion(value, kind); |
| _currentLinkedPositionGroup.addSuggestion(suggestion); |
| } |
| |
| void addSuggestions(LinkedEditSuggestionKind kind, List<String> values) { |
| values.forEach((value) => addSuggestion(kind, value)); |
| } |
| |
| /** |
| * Appends [s] to the buffer. |
| */ |
| SourceBuilder append(String s) { |
| _buffer.write(s); |
| return this; |
| } |
| |
| /** |
| * Ends position started using [startPosition]. |
| */ |
| void endPosition() { |
| assert(_currentLinkedPositionGroup != null); |
| _addPosition(); |
| _currentLinkedPositionGroup = null; |
| } |
| |
| /** |
| * Marks the current offset as an "exit" one. |
| */ |
| void setExitOffset() { |
| _exitOffset = _buffer.length; |
| } |
| |
| /** |
| * Marks start of a new linked position for the group with the given ID. |
| */ |
| void startPosition(String id) { |
| assert(_currentLinkedPositionGroup == null); |
| _currentLinkedPositionGroup = linkedPositionGroups[id]; |
| if (_currentLinkedPositionGroup == null) { |
| _currentLinkedPositionGroup = new LinkedEditGroup.empty(); |
| linkedPositionGroups[id] = _currentLinkedPositionGroup; |
| } |
| _currentPositionStart = _buffer.length; |
| } |
| |
| @override |
| String toString() => _buffer.toString(); |
| |
| /** |
| * Adds position location [SourceRange] using current fields. |
| */ |
| void _addPosition() { |
| int start = offset + _currentPositionStart; |
| int end = offset + _buffer.length; |
| int length = end - start; |
| Position position = new Position(file, start); |
| _currentLinkedPositionGroup.addPosition(position, length); |
| } |
| } |