| // 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. |
| |
| import 'dart:collection'; |
| |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/java_io.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| |
| export 'package:analyzer/src/generated/source.dart'; |
| |
| /// Instances of the class `FileBasedSource` implement a source that represents |
| /// a file. |
| class FileBasedSource extends Source { |
| /// Map from encoded URI/filepath pair to a unique integer identifier. This |
| /// identifier is used for equality tests and hash codes. |
| /// |
| /// The URI and filepath are joined into a pair by separating them with an '@' |
| /// character. |
| static final Map<String, int> _idTable = HashMap<String, int>(); |
| |
| /// The URI from which this source was originally derived. |
| @override |
| final Uri uri; |
| |
| /// The unique ID associated with this [FileBasedSource]. |
| final int id; |
| |
| /// The file represented by this source. |
| final JavaFile file; |
| |
| /// The cached absolute path of this source. |
| String? _absolutePath; |
| |
| /// The cached encoding for this source. |
| String? _encoding; |
| |
| /// Initialize a newly created source object to represent the given [file]. If |
| /// a [uri] is given, then it will be used as the URI from which the source |
| /// was derived, otherwise a `file:` URI will be created based on the [file]. |
| FileBasedSource(JavaFile file, [Uri? uri]) |
| : uri = uri ?? file.toURI(), |
| file = file, |
| id = _idTable.putIfAbsent( |
| '${uri ?? file.toURI()}@${file.getPath()}', () => _idTable.length); |
| |
| @override |
| TimestampedData<String> get contents { |
| return contentsFromFile; |
| } |
| |
| /// Get the contents and timestamp of the underlying file. |
| /// |
| /// Clients should consider using the method [AnalysisContext.getContents] |
| /// because contexts can have local overrides of the content of a source that |
| /// the source is not aware of. |
| /// |
| /// @return the contents of the source paired with the modification stamp of |
| /// the source |
| /// @throws Exception if the contents of this source could not be accessed |
| /// See [contents]. |
| TimestampedData<String> get contentsFromFile { |
| return TimestampedData<String>( |
| file.lastModified(), file.readAsStringSync()); |
| } |
| |
| @override |
| String get encoding { |
| return _encoding ??= uri.toString(); |
| } |
| |
| @override |
| String get fullName { |
| return _absolutePath ??= file.getAbsolutePath(); |
| } |
| |
| @override |
| int get hashCode => uri.hashCode; |
| |
| @override |
| bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME; |
| |
| @override |
| int get modificationStamp => file.lastModified(); |
| |
| @override |
| String get shortName => file.getName(); |
| |
| @override |
| UriKind get uriKind { |
| String scheme = uri.scheme; |
| return UriKind.fromScheme(scheme); |
| } |
| |
| @override |
| bool operator ==(Object object) { |
| if (object is FileBasedSource) { |
| return id == object.id; |
| } else if (object is Source) { |
| return uri == object.uri; |
| } |
| return false; |
| } |
| |
| @override |
| bool exists() => file.isFile(); |
| |
| @override |
| String toString() { |
| return file.getAbsolutePath(); |
| } |
| } |