mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
Put fully resolved analysis results (just errors now) into the byte cache.
R=brianwilkerson@google.com, paulberry@google.com BUG= Review URL: https://codereview.chromium.org/2455573003 .
This commit is contained in:
parent
205e9a58e1
commit
bd594d453f
|
@ -236,7 +236,8 @@ class AnalysisDriver {
|
||||||
for (String path in _priorityFiles) {
|
for (String path in _priorityFiles) {
|
||||||
if (_filesToAnalyze.remove(path)) {
|
if (_filesToAnalyze.remove(path)) {
|
||||||
_File file = _fileForPath(path);
|
_File file = _fileForPath(path);
|
||||||
AnalysisResult result = _computeAnalysisResult(file);
|
AnalysisResult result =
|
||||||
|
_computeAnalysisResult(file, withUnit: true);
|
||||||
yield result;
|
yield result;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +253,7 @@ class AnalysisDriver {
|
||||||
if (_filesToAnalyze.isNotEmpty) {
|
if (_filesToAnalyze.isNotEmpty) {
|
||||||
String path = _removeFirst(_filesToAnalyze);
|
String path = _removeFirst(_filesToAnalyze);
|
||||||
_File file = _fileForPath(path);
|
_File file = _fileForPath(path);
|
||||||
AnalysisResult result = _computeAnalysisResult(file);
|
AnalysisResult result = _computeAnalysisResult(file, withUnit: false);
|
||||||
yield result;
|
yield result;
|
||||||
// Repeat the processing loop.
|
// Repeat the processing loop.
|
||||||
_hasWork.notify();
|
_hasWork.notify();
|
||||||
|
@ -366,10 +367,32 @@ class AnalysisDriver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the [AnalysisResult] for the [file].
|
* Compute the [AnalysisResult] for the [file].
|
||||||
|
*
|
||||||
|
* The result will have the fully resolved unit only if [withUnit] is `true`.
|
||||||
*/
|
*/
|
||||||
AnalysisResult _computeAnalysisResult(_File file) {
|
AnalysisResult _computeAnalysisResult(_File file, {bool withUnit: false}) {
|
||||||
|
// If we don't need to the fully resolved unit, check for a cached result.
|
||||||
|
if (!withUnit) {
|
||||||
|
AnalysisResult result = _getCachedAnalysisResult(file);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need the fully resolved unit, or the result is not cached.
|
||||||
return _logger.run('Compute analysis result for $file', () {
|
return _logger.run('Compute analysis result for $file', () {
|
||||||
_LibraryContext libraryContext = _createLibraryContext(file);
|
_LibraryContext libraryContext = _createLibraryContext(file);
|
||||||
|
|
||||||
|
// We recomputed the dependency hash, and we might have a cached result.
|
||||||
|
if (!withUnit) {
|
||||||
|
AnalysisResult result = _getCachedAnalysisResult(file);
|
||||||
|
if (result != null) {
|
||||||
|
_logger.writeln('Return the cached analysis result.');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still no result, compute and store it.
|
||||||
AnalysisContext analysisContext = _createAnalysisContext(libraryContext);
|
AnalysisContext analysisContext = _createAnalysisContext(libraryContext);
|
||||||
try {
|
try {
|
||||||
analysisContext.setContents(file.source, file.content);
|
analysisContext.setContents(file.source, file.content);
|
||||||
|
@ -377,6 +400,25 @@ class AnalysisDriver {
|
||||||
CompilationUnit resolvedUnit =
|
CompilationUnit resolvedUnit =
|
||||||
analysisContext.resolveCompilationUnit2(file.source, file.source);
|
analysisContext.resolveCompilationUnit2(file.source, file.source);
|
||||||
List<AnalysisError> errors = analysisContext.computeErrors(file.source);
|
List<AnalysisError> errors = analysisContext.computeErrors(file.source);
|
||||||
|
|
||||||
|
// Store the result into the cache.
|
||||||
|
{
|
||||||
|
List<int> bytes = new AnalysisDriverResolvedUnitBuilder(
|
||||||
|
errors: errors
|
||||||
|
.map((error) => new AnalysisDriverUnitErrorBuilder(
|
||||||
|
offset: error.offset,
|
||||||
|
length: error.length,
|
||||||
|
uniqueName: error.errorCode.uniqueName,
|
||||||
|
message: error.message,
|
||||||
|
correction: error.correction))
|
||||||
|
.toList())
|
||||||
|
.toBuffer();
|
||||||
|
String key = _getResolvedUnitKey(file);
|
||||||
|
_byteStore.put(key, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the full result.
|
||||||
|
_logger.writeln('Computed new analysis result.');
|
||||||
return new AnalysisResult(file.path, file.uri, file.content,
|
return new AnalysisResult(file.path, file.uri, file.content,
|
||||||
file.contentHash, resolvedUnit, errors);
|
file.contentHash, resolvedUnit, errors);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -526,6 +568,47 @@ class AnalysisDriver {
|
||||||
return new _File.forResolution(this, source);
|
return new _File.forResolution(this, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we know the dependency signature for the [file], try to load the
|
||||||
|
* analysis result from the cache. Return `null` if not found.
|
||||||
|
*/
|
||||||
|
AnalysisResult _getCachedAnalysisResult(_File file) {
|
||||||
|
String key = _getResolvedUnitKey(file);
|
||||||
|
if (key != null) {
|
||||||
|
List<int> bytes = _byteStore.get(key);
|
||||||
|
if (bytes != null) {
|
||||||
|
var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes);
|
||||||
|
List<AnalysisError> errors = unit.errors
|
||||||
|
.map((error) => new AnalysisError.forValues(
|
||||||
|
file.source,
|
||||||
|
error.offset,
|
||||||
|
error.length,
|
||||||
|
ErrorCode.byUniqueName(error.uniqueName),
|
||||||
|
error.message,
|
||||||
|
error.correction))
|
||||||
|
.toList();
|
||||||
|
return new AnalysisResult(
|
||||||
|
file.path, file.uri, null, file.contentHash, null, errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the key to store fully resolved results for the [file] into the
|
||||||
|
* cache. Return `null` if the dependency signature is not known yet.
|
||||||
|
*/
|
||||||
|
String _getResolvedUnitKey(_File file) {
|
||||||
|
String dependencyHash = _dependencySignatureMap[file.uri];
|
||||||
|
if (dependencyHash != null) {
|
||||||
|
ApiSignature signature = new ApiSignature();
|
||||||
|
signature.addString(dependencyHash);
|
||||||
|
signature.addString(file.contentHash);
|
||||||
|
return '${signature.toHex()}.resolved';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the API signature for the file with the given [path], and decide
|
* Verify the API signature for the file with the given [path], and decide
|
||||||
* which linked libraries should be invalidated, and files reanalyzed.
|
* which linked libraries should be invalidated, and files reanalyzed.
|
||||||
|
|
|
@ -129,6 +129,296 @@ class _UnlinkedParamKindReader extends fb.Reader<idl.UnlinkedParamKind> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AnalysisDriverResolvedUnitBuilder extends Object with _AnalysisDriverResolvedUnitMixin implements idl.AnalysisDriverResolvedUnit {
|
||||||
|
List<AnalysisDriverUnitErrorBuilder> _errors;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<AnalysisDriverUnitErrorBuilder> get errors => _errors ??= <AnalysisDriverUnitErrorBuilder>[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full list of analysis errors, both syntactic and semantic.
|
||||||
|
*/
|
||||||
|
void set errors(List<AnalysisDriverUnitErrorBuilder> value) {
|
||||||
|
this._errors = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnalysisDriverResolvedUnitBuilder({List<AnalysisDriverUnitErrorBuilder> errors})
|
||||||
|
: _errors = errors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush [informative] data recursively.
|
||||||
|
*/
|
||||||
|
void flushInformative() {
|
||||||
|
_errors?.forEach((b) => b.flushInformative());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulate non-[informative] data into [signature].
|
||||||
|
*/
|
||||||
|
void collectApiSignature(api_sig.ApiSignature signature) {
|
||||||
|
if (this._errors == null) {
|
||||||
|
signature.addInt(0);
|
||||||
|
} else {
|
||||||
|
signature.addInt(this._errors.length);
|
||||||
|
for (var x in this._errors) {
|
||||||
|
x?.collectApiSignature(signature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> toBuffer() {
|
||||||
|
fb.Builder fbBuilder = new fb.Builder();
|
||||||
|
return fbBuilder.finish(finish(fbBuilder), "ADRU");
|
||||||
|
}
|
||||||
|
|
||||||
|
fb.Offset finish(fb.Builder fbBuilder) {
|
||||||
|
fb.Offset offset_errors;
|
||||||
|
if (!(_errors == null || _errors.isEmpty)) {
|
||||||
|
offset_errors = fbBuilder.writeList(_errors.map((b) => b.finish(fbBuilder)).toList());
|
||||||
|
}
|
||||||
|
fbBuilder.startTable();
|
||||||
|
if (offset_errors != null) {
|
||||||
|
fbBuilder.addOffset(0, offset_errors);
|
||||||
|
}
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idl.AnalysisDriverResolvedUnit readAnalysisDriverResolvedUnit(List<int> buffer) {
|
||||||
|
fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
|
||||||
|
return const _AnalysisDriverResolvedUnitReader().read(rootRef, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnalysisDriverResolvedUnitReader extends fb.TableReader<_AnalysisDriverResolvedUnitImpl> {
|
||||||
|
const _AnalysisDriverResolvedUnitReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AnalysisDriverResolvedUnitImpl createObject(fb.BufferContext bc, int offset) => new _AnalysisDriverResolvedUnitImpl(bc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnalysisDriverResolvedUnitImpl extends Object with _AnalysisDriverResolvedUnitMixin implements idl.AnalysisDriverResolvedUnit {
|
||||||
|
final fb.BufferContext _bc;
|
||||||
|
final int _bcOffset;
|
||||||
|
|
||||||
|
_AnalysisDriverResolvedUnitImpl(this._bc, this._bcOffset);
|
||||||
|
|
||||||
|
List<idl.AnalysisDriverUnitError> _errors;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<idl.AnalysisDriverUnitError> get errors {
|
||||||
|
_errors ??= const fb.ListReader<idl.AnalysisDriverUnitError>(const _AnalysisDriverUnitErrorReader()).vTableGet(_bc, _bcOffset, 0, const <idl.AnalysisDriverUnitError>[]);
|
||||||
|
return _errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _AnalysisDriverResolvedUnitMixin implements idl.AnalysisDriverResolvedUnit {
|
||||||
|
@override
|
||||||
|
Map<String, Object> toJson() {
|
||||||
|
Map<String, Object> _result = <String, Object>{};
|
||||||
|
if (errors.isNotEmpty) _result["errors"] = errors.map((_value) => _value.toJson()).toList();
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, Object> toMap() => {
|
||||||
|
"errors": errors,
|
||||||
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => convert.JSON.encode(toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnalysisDriverUnitErrorBuilder extends Object with _AnalysisDriverUnitErrorMixin implements idl.AnalysisDriverUnitError {
|
||||||
|
String _correction;
|
||||||
|
int _length;
|
||||||
|
String _message;
|
||||||
|
int _offset;
|
||||||
|
String _uniqueName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get correction => _correction ??= '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The optional correction hint for the error.
|
||||||
|
*/
|
||||||
|
void set correction(String value) {
|
||||||
|
this._correction = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get length => _length ??= 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The length of the error in the file.
|
||||||
|
*/
|
||||||
|
void set length(int value) {
|
||||||
|
assert(value == null || value >= 0);
|
||||||
|
this._length = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get message => _message ??= '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message of the error.
|
||||||
|
*/
|
||||||
|
void set message(String value) {
|
||||||
|
this._message = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get offset => _offset ??= 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The offset from the beginning of the file.
|
||||||
|
*/
|
||||||
|
void set offset(int value) {
|
||||||
|
assert(value == null || value >= 0);
|
||||||
|
this._offset = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get uniqueName => _uniqueName ??= '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique name of the error code.
|
||||||
|
*/
|
||||||
|
void set uniqueName(String value) {
|
||||||
|
this._uniqueName = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnalysisDriverUnitErrorBuilder({String correction, int length, String message, int offset, String uniqueName})
|
||||||
|
: _correction = correction,
|
||||||
|
_length = length,
|
||||||
|
_message = message,
|
||||||
|
_offset = offset,
|
||||||
|
_uniqueName = uniqueName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush [informative] data recursively.
|
||||||
|
*/
|
||||||
|
void flushInformative() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulate non-[informative] data into [signature].
|
||||||
|
*/
|
||||||
|
void collectApiSignature(api_sig.ApiSignature signature) {
|
||||||
|
signature.addInt(this._offset ?? 0);
|
||||||
|
signature.addInt(this._length ?? 0);
|
||||||
|
signature.addString(this._uniqueName ?? '');
|
||||||
|
signature.addString(this._message ?? '');
|
||||||
|
signature.addString(this._correction ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
fb.Offset finish(fb.Builder fbBuilder) {
|
||||||
|
fb.Offset offset_correction;
|
||||||
|
fb.Offset offset_message;
|
||||||
|
fb.Offset offset_uniqueName;
|
||||||
|
if (_correction != null) {
|
||||||
|
offset_correction = fbBuilder.writeString(_correction);
|
||||||
|
}
|
||||||
|
if (_message != null) {
|
||||||
|
offset_message = fbBuilder.writeString(_message);
|
||||||
|
}
|
||||||
|
if (_uniqueName != null) {
|
||||||
|
offset_uniqueName = fbBuilder.writeString(_uniqueName);
|
||||||
|
}
|
||||||
|
fbBuilder.startTable();
|
||||||
|
if (offset_correction != null) {
|
||||||
|
fbBuilder.addOffset(4, offset_correction);
|
||||||
|
}
|
||||||
|
if (_length != null && _length != 0) {
|
||||||
|
fbBuilder.addUint32(1, _length);
|
||||||
|
}
|
||||||
|
if (offset_message != null) {
|
||||||
|
fbBuilder.addOffset(3, offset_message);
|
||||||
|
}
|
||||||
|
if (_offset != null && _offset != 0) {
|
||||||
|
fbBuilder.addUint32(0, _offset);
|
||||||
|
}
|
||||||
|
if (offset_uniqueName != null) {
|
||||||
|
fbBuilder.addOffset(2, offset_uniqueName);
|
||||||
|
}
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnalysisDriverUnitErrorReader extends fb.TableReader<_AnalysisDriverUnitErrorImpl> {
|
||||||
|
const _AnalysisDriverUnitErrorReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AnalysisDriverUnitErrorImpl createObject(fb.BufferContext bc, int offset) => new _AnalysisDriverUnitErrorImpl(bc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnalysisDriverUnitErrorImpl extends Object with _AnalysisDriverUnitErrorMixin implements idl.AnalysisDriverUnitError {
|
||||||
|
final fb.BufferContext _bc;
|
||||||
|
final int _bcOffset;
|
||||||
|
|
||||||
|
_AnalysisDriverUnitErrorImpl(this._bc, this._bcOffset);
|
||||||
|
|
||||||
|
String _correction;
|
||||||
|
int _length;
|
||||||
|
String _message;
|
||||||
|
int _offset;
|
||||||
|
String _uniqueName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get correction {
|
||||||
|
_correction ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
|
||||||
|
return _correction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get length {
|
||||||
|
_length ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
|
||||||
|
return _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get message {
|
||||||
|
_message ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
|
||||||
|
return _message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get offset {
|
||||||
|
_offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
|
||||||
|
return _offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get uniqueName {
|
||||||
|
_uniqueName ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 2, '');
|
||||||
|
return _uniqueName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _AnalysisDriverUnitErrorMixin implements idl.AnalysisDriverUnitError {
|
||||||
|
@override
|
||||||
|
Map<String, Object> toJson() {
|
||||||
|
Map<String, Object> _result = <String, Object>{};
|
||||||
|
if (correction != '') _result["correction"] = correction;
|
||||||
|
if (length != 0) _result["length"] = length;
|
||||||
|
if (message != '') _result["message"] = message;
|
||||||
|
if (offset != 0) _result["offset"] = offset;
|
||||||
|
if (uniqueName != '') _result["uniqueName"] = uniqueName;
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, Object> toMap() => {
|
||||||
|
"correction": correction,
|
||||||
|
"length": length,
|
||||||
|
"message": message,
|
||||||
|
"offset": offset,
|
||||||
|
"uniqueName": uniqueName,
|
||||||
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => convert.JSON.encode(toJson());
|
||||||
|
}
|
||||||
|
|
||||||
class CodeRangeBuilder extends Object with _CodeRangeMixin implements idl.CodeRange {
|
class CodeRangeBuilder extends Object with _CodeRangeMixin implements idl.CodeRange {
|
||||||
int _length;
|
int _length;
|
||||||
int _offset;
|
int _offset;
|
||||||
|
|
|
@ -781,6 +781,46 @@ enum UnlinkedParamKind : byte {
|
||||||
named
|
named
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a resolved unit.
|
||||||
|
*/
|
||||||
|
table AnalysisDriverResolvedUnit {
|
||||||
|
/**
|
||||||
|
* The full list of analysis errors, both syntactic and semantic.
|
||||||
|
*/
|
||||||
|
errors:[AnalysisDriverUnitError] (id: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about an error in a resolved unit.
|
||||||
|
*/
|
||||||
|
table AnalysisDriverUnitError {
|
||||||
|
/**
|
||||||
|
* The optional correction hint for the error.
|
||||||
|
*/
|
||||||
|
correction:string (id: 4);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The length of the error in the file.
|
||||||
|
*/
|
||||||
|
length:uint (id: 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message of the error.
|
||||||
|
*/
|
||||||
|
message:string (id: 3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The offset from the beginning of the file.
|
||||||
|
*/
|
||||||
|
offset:uint (id: 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique name of the error code.
|
||||||
|
*/
|
||||||
|
uniqueName:string (id: 2);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about an element code range.
|
* Information about an element code range.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -57,6 +57,56 @@ import 'format.dart' as generated;
|
||||||
*/
|
*/
|
||||||
const informative = null;
|
const informative = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a resolved unit.
|
||||||
|
*/
|
||||||
|
@TopLevel('ADRU')
|
||||||
|
abstract class AnalysisDriverResolvedUnit extends base.SummaryClass {
|
||||||
|
factory AnalysisDriverResolvedUnit.fromBuffer(List<int> buffer) =>
|
||||||
|
generated.readAnalysisDriverResolvedUnit(buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full list of analysis errors, both syntactic and semantic.
|
||||||
|
*/
|
||||||
|
@Id(0)
|
||||||
|
List<AnalysisDriverUnitError> get errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about an error in a resolved unit.
|
||||||
|
*/
|
||||||
|
abstract class AnalysisDriverUnitError extends base.SummaryClass {
|
||||||
|
/**
|
||||||
|
* The optional correction hint for the error.
|
||||||
|
*/
|
||||||
|
@Id(4)
|
||||||
|
String get correction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The length of the error in the file.
|
||||||
|
*/
|
||||||
|
@Id(1)
|
||||||
|
int get length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message of the error.
|
||||||
|
*/
|
||||||
|
@Id(3)
|
||||||
|
String get message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The offset from the beginning of the file.
|
||||||
|
*/
|
||||||
|
@Id(0)
|
||||||
|
int get offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique name of the error code.
|
||||||
|
*/
|
||||||
|
@Id(2)
|
||||||
|
String get uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about an element code range.
|
* Information about an element code range.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue