blob: d56aa3d63cf49642bde09ff1e5681c9f11f3714f [file] [log] [blame]
// 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/plugin/protocol/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);
}
}