blob: 86d6ebffd443f3cb90c52bb250dcf1e6d4487774 [file] [log] [blame]
// Copyright (c) 2016, 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 'package:path/path.dart' as pathos;
import 'analysis_target.dart';
import 'timestamped_data.dart';
import 'uri_kind.dart';
/// Base class providing implementations for the methods in [Source] that don't
/// require filesystem access.
abstract class BasicSource extends Source {
final Uri uri;
BasicSource(this.uri);
@override
String get encoding => uri.toString();
@override
String get fullName => encoding;
@override
int get hashCode => uri.hashCode;
@override
bool get isInSystemLibrary => uri.scheme == 'dart';
@override
String get shortName => pathos.basename(fullName);
@override
bool operator ==(Object object) => object is Source && object.uri == uri;
}
/**
* The interface `Source` defines the behavior of objects representing source
* code that can be analyzed by the analysis engine.
*
* Implementations of this interface need to be aware of some assumptions made
* by the analysis engine concerning sources:
*
* * Sources are not required to be unique. That is, there can be multiple
* instances representing the same source.
* * Sources are long lived. That is, the engine is allowed to hold on to a
* source for an extended period of time and that source must continue to
* report accurate and up-to-date information.
*
* Because of these assumptions, most implementations will not maintain any
* state but will delegate to an authoritative system of record in order to
* implement this API. For example, a source that represents files on disk
* would typically query the file system to determine the state of the file.
*
* If the instances that implement this API are the system of record, then they
* will typically be unique. In that case, sources that are created that
* represent non-existent files must also be retained so that if those files
* are created at a later date the long-lived sources representing those files
* will know that they now exist.
*/
abstract class Source implements AnalysisTarget {
/**
* An empty list of sources.
*/
static const List<Source> EMPTY_LIST = const <Source>[];
/**
* Get the contents and timestamp of this source.
*
* 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 and timestamp of the source
* @throws Exception if the contents of this source could not be accessed
*/
TimestampedData<String> get contents;
/**
* Return an encoded representation of this source that can be used to create
* a source that is equal to this source.
*
* @return an encoded representation of this source
* See [SourceFactory.fromEncoding].
*/
String get encoding;
/**
* Return the full (long) version of the name that can be displayed to the
* user to denote this source. For example, for a source representing a file
* this would typically be the absolute path of the file.
*
* @return a name that can be displayed to the user to denote this source
*/
String get fullName;
/**
* Return a hash code for this source.
*
* @return a hash code for this source
* See [Object.hashCode].
*/
@override
int get hashCode;
/**
* Return `true` if this source is in one of the system libraries.
*
* @return `true` if this is in a system library
*/
bool get isInSystemLibrary;
@override
Source get librarySource => null;
/**
* Return the modification stamp for this source, or a negative value if the
* source does not exist. A modification stamp is a non-negative integer with
* the property that if the contents of the source have not been modified
* since the last time the modification stamp was accessed then the same
* value will be returned, but if the contents of the source have been
* modified one or more times (even if the net change is zero) the stamps
* will be different.
*
* Clients should consider using the method
* [AnalysisContext.getModificationStamp] because contexts can have local
* overrides of the content of a source that the source is not aware of.
*/
int get modificationStamp;
/**
* Return a short version of the name that can be displayed to the user to
* denote this source. For example, for a source representing a file this
* would typically be the name of the file.
*
* @return a name that can be displayed to the user to denote this source
*/
String get shortName;
@override
Source get source => this;
/**
* Return the URI from which this source was originally derived.
*
* @return the URI from which this source was originally derived
*/
Uri get uri;
/**
* Return the kind of URI from which this source was originally derived. If
* this source was created from an absolute URI, then the returned kind will
* reflect the scheme of the absolute URI. If it was created from a relative
* URI, then the returned kind will be the same as the kind of the source
* against which the relative URI was resolved.
*
* @return the kind of URI from which this source was originally derived
*/
UriKind get uriKind;
/**
* Return `true` if the given object is a source that represents the same
* source code as this source.
*
* @param object the object to be compared with this object
* @return `true` if the given object is a source that represents the same
* source code as this source
* See [Object.==].
*/
@override
bool operator ==(Object object);
/**
* Return `true` if this source exists.
*
* Clients should consider using the method [AnalysisContext.exists] because
* contexts can have local overrides of the content of a source that the
* source is not aware of and a source with local content is considered to
* exist even if there is no file on disk.
*
* @return `true` if this source exists
*/
bool exists();
}