Convert more doc comments in analysis_server

Change-Id: I333d0af4444226a8152e840c4d9015fb4c30bd32
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135700
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Brian Wilkerson 2020-02-13 19:29:28 +00:00 committed by commit-bot@chromium.org
parent 4ca3d267ee
commit b03ef5b3fe
50 changed files with 950 additions and 1954 deletions

View file

@ -24,9 +24,7 @@ import 'package:meta/meta.dart';
import 'src/utilities/mock_packages.dart';
/**
* Finds an [Element] with the given [name].
*/
/// Finds an [Element] with the given [name].
Element findChildElement(Element root, String name, [ElementKind kind]) {
Element result;
root.accept(_ElementVisitorFunctionWrapper((Element element) {
@ -41,9 +39,7 @@ Element findChildElement(Element root, String name, [ElementKind kind]) {
return result;
}
/**
* A function to be called for every [Element].
*/
/// A function to be called for every [Element].
typedef _ElementVisitorFunction = void Function(Element element);
class AbstractContextTest with ResourceProviderMixin {
@ -213,10 +209,8 @@ test:${toUriStr('/home/test/lib')}
}
}
/**
* Wraps the given [_ElementVisitorFunction] into an instance of
* [engine.GeneralizingElementVisitor].
*/
/// Wraps the given [_ElementVisitorFunction] into an instance of
/// [engine.GeneralizingElementVisitor].
class _ElementVisitorFunctionWrapper extends GeneralizingElementVisitor<void> {
final _ElementVisitorFunction function;
_ElementVisitorFunctionWrapper(this.function);

View file

@ -44,9 +44,7 @@ class AbstractSingleUnitTest extends AbstractContextTest {
return findOffset(search) + search.length;
}
/**
* Returns the [SimpleIdentifier] at the given search pattern.
*/
/// Returns the [SimpleIdentifier] at the given search pattern.
SimpleIdentifier findIdentifier(String search) {
return findNodeAtString(search, (node) => node is SimpleIdentifier);
}

View file

@ -24,12 +24,10 @@ class AnalysisNotificationImplementedTest extends AbstractAnalysisTest {
List<ImplementedClass> implementedClasses;
List<ImplementedMember> implementedMembers;
/**
* Validates that there is an [ImplementedClass] at the offset of [search].
*
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
/// Validates that there is an [ImplementedClass] at the offset of [search].
///
/// If [length] is not specified explicitly, then length of an identifier
/// from [search] is used.
void assertHasImplementedClass(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -47,12 +45,10 @@ class AnalysisNotificationImplementedTest extends AbstractAnalysisTest {
' in $implementedClasses');
}
/**
* Validates that there is an [ImplementedClass] at the offset of [search].
*
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
/// Validates that there is an [ImplementedClass] at the offset of [search].
///
/// If [length] is not specified explicitly, then length of an identifier
/// from [search] is used.
void assertHasImplementedMember(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -70,12 +66,10 @@ class AnalysisNotificationImplementedTest extends AbstractAnalysisTest {
' in $implementedMembers');
}
/**
* Validates that there is no [ImplementedMember] at the offset of [search].
*
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
/// Validates that there is no [ImplementedMember] at the offset of [search].
///
/// If [length] is not specified explicitly, then length of an identifier
/// from [search] is used.
void assertNoImplementedMember(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -92,9 +86,7 @@ class AnalysisNotificationImplementedTest extends AbstractAnalysisTest {
}
}
/**
* Subscribe for `IMPLEMENTED` and wait for the notification.
*/
/// Subscribe for `IMPLEMENTED` and wait for the notification.
Future prepareImplementedElements() {
subscribeForImplemented();
return waitForImplementedElements();

View file

@ -29,10 +29,8 @@ class AbstractNavigationTest extends AbstractAnalysisTest {
List<NavigationTarget> testTargets;
NavigationTarget testTarget;
/**
* Validates that there is a target in [testTargetIndexes] with [file],
* at [offset] and with the given [length].
*/
/// Validates that there is a target in [testTargetIndexes] with [file],
/// at [offset] and with the given [length].
void assertHasFileTarget(String file, int offset, int length) {
for (NavigationTarget target in testTargets) {
if (targetFiles[target.fileIndex] == file &&
@ -54,11 +52,9 @@ class AbstractNavigationTest extends AbstractAnalysisTest {
assertHasTarget(targetSearch, targetLength);
}
/**
* Validates that there is a region at the offset of [search] in [testFile].
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
/// Validates that there is a region at the offset of [search] in [testFile].
/// If [length] is not specified explicitly, then length of an identifier
/// from [search] is used.
void assertHasRegion(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -67,10 +63,8 @@ class AbstractNavigationTest extends AbstractAnalysisTest {
findRegion(offset, length, true);
}
/**
* Validates that there is a region at the offset of [search] in [testFile]
* with the given [length] or the length of [search].
*/
/// Validates that there is a region at the offset of [search] in [testFile]
/// with the given [length] or the length of [search].
void assertHasRegionString(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -79,20 +73,16 @@ class AbstractNavigationTest extends AbstractAnalysisTest {
findRegion(offset, length, true);
}
/**
* Validates that there is an identifier region at [regionSearch] with target
* at [targetSearch].
*/
/// Validates that there is an identifier region at [regionSearch] with target
/// at [targetSearch].
void assertHasRegionTarget(String regionSearch, String targetSearch) {
assertHasRegion(regionSearch);
assertHasTarget(targetSearch);
}
/**
* Validates that there is a target in [testTargets] with [testFile], at the
* offset of [search] in [testFile], and with the given [length] or the length
* of an leading identifier in [search].
*/
/// Validates that there is a target in [testTargets] with [testFile], at the
/// offset of [search] in [testFile], and with the given [length] or the
/// length of an leading identifier in [search].
void assertHasTarget(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -101,34 +91,26 @@ class AbstractNavigationTest extends AbstractAnalysisTest {
assertHasFileTarget(testFile, offset, length);
}
/**
* Validates that there is a target in [testTargets] with [testFile], at the
* offset of [str] in [testFile], and with the length of [str].
*/
/// Validates that there is a target in [testTargets] with [testFile], at the
/// offset of [str] in [testFile], and with the length of [str].
void assertHasTargetString(String str) {
assertHasTarget(str, str.length);
}
/**
* Validates that there is no a region at [search] and with the given
* [length].
*/
/// Validates that there is no a region at [search] and with the given
/// [length].
void assertNoRegion(String search, int length) {
int offset = findOffset(search);
findRegion(offset, length, false);
}
/**
* Validates that there is no a region at [search] with any length.
*/
/// Validates that there is no a region at [search] with any length.
void assertNoRegionAt(String search) {
int offset = findOffset(search);
findRegion(offset, -1, false);
}
/**
* Validates that there is no a region for [search] string.
*/
/// Validates that there is no a region for [search] string.
void assertNoRegionString(String search) {
int offset = findOffset(search);
int length = search.length;
@ -146,16 +128,14 @@ class AbstractNavigationTest extends AbstractAnalysisTest {
}
}
/**
* Finds the navigation region with the given [offset] and [length].
* If [length] is `-1`, then it is ignored.
*
* If [exists] is `true`, then fails if such region does not exist.
* Otherwise remembers this it into [testRegion].
* Also fills [testTargets] with its targets.
*
* If [exists] is `false`, then fails if such region exists.
*/
/// Finds the navigation region with the given [offset] and [length].
/// If [length] is `-1`, then it is ignored.
///
/// If [exists] is `true`, then fails if such region does not exist.
/// Otherwise remembers this it into [testRegion].
/// Also fills [testTargets] with its targets.
///
/// If [exists] is `false`, then fails if such region exists.
void findRegion(int offset, int length, bool exists) {
for (NavigationRegion region in regions) {
if (region.offset == offset &&

View file

@ -26,19 +26,15 @@ class AnalysisNotificationOccurrencesTest extends AbstractAnalysisTest {
final Completer<void> _resultsAvailable = Completer();
/**
* Asserts that there is an offset of [search] in [testOccurrences].
*/
/// Asserts that there is an offset of [search] in [testOccurrences].
void assertHasOffset(String search) {
int offset = findOffset(search);
expect(testOccurrences.offsets, contains(offset));
}
/**
* Validates that there is a region at the offset of [search] in [testFile].
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
/// Validates that there is a region at the offset of [search] in [testFile].
/// If [length] is not specified explicitly, then length of an identifier
/// from [search] is used.
void assertHasRegion(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -47,14 +43,12 @@ class AnalysisNotificationOccurrencesTest extends AbstractAnalysisTest {
findRegion(offset, length, true);
}
/**
* Finds an [Occurrences] with the given [offset] and [length].
*
* If [exists] is `true`, then fails if such [Occurrences] does not exist.
* Otherwise remembers this it into [testOccurrences].
*
* If [exists] is `false`, then fails if such [Occurrences] exists.
*/
/// Finds an [Occurrences] with the given [offset] and [length].
///
/// If [exists] is `true`, then fails if such [Occurrences] does not exist.
/// Otherwise remembers this it into [testOccurrences].
///
/// If [exists] is `false`, then fails if such [Occurrences] exists.
void findRegion(int offset, int length, [bool exists]) {
for (Occurrences occurrences in occurrencesList) {
if (occurrences.length != length) {

View file

@ -25,10 +25,8 @@ class AnalysisNotificationOverridesTest extends AbstractAnalysisTest {
final Completer<void> _resultsAvailable = Completer();
/**
* Asserts that there is an overridden interface [OverriddenMember] at the
* offset of [search] in [override].
*/
/// Asserts that there is an overridden interface [OverriddenMember] at the
/// offset of [search] in [override].
void assertHasInterfaceMember(String search) {
int offset = findOffset(search);
for (OverriddenMember member in overrideObject.interfaceMembers) {
@ -40,12 +38,10 @@ class AnalysisNotificationOverridesTest extends AbstractAnalysisTest {
'${overrideObject.interfaceMembers.join('\n')}');
}
/**
* Validates that there is an [Override] at the offset of [search].
*
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
/// Validates that there is an [Override] at the offset of [search].
///
/// If [length] is not specified explicitly, then length of an identifier
/// from [search] is used.
void assertHasOverride(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -54,29 +50,23 @@ class AnalysisNotificationOverridesTest extends AbstractAnalysisTest {
findOverride(offset, length, true);
}
/**
* Asserts that there is an overridden superclass [OverriddenMember] at the
* offset of [search] in [override].
*/
/// Asserts that there is an overridden superclass [OverriddenMember] at the
/// offset of [search] in [override].
void assertHasSuperElement(String search) {
int offset = findOffset(search);
OverriddenMember member = overrideObject.superclassMember;
expect(member.element.location.offset, offset);
}
/**
* Asserts that there are no overridden members from interfaces.
*/
/// Asserts that there are no overridden members from interfaces.
void assertNoInterfaceMembers() {
expect(overrideObject.interfaceMembers, isNull);
}
/**
* Validates that there is no [Override] at the offset of [search].
*
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
/// Validates that there is no [Override] at the offset of [search].
///
/// If [length] is not specified explicitly, then length of an identifier
/// from [search] is used.
void assertNoOverride(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
@ -85,21 +75,17 @@ class AnalysisNotificationOverridesTest extends AbstractAnalysisTest {
findOverride(offset, length, false);
}
/**
* Asserts that there are no overridden member from the superclass.
*/
/// Asserts that there are no overridden member from the superclass.
void assertNoSuperMember() {
expect(overrideObject.superclassMember, isNull);
}
/**
* Finds an [Override] with the given [offset] and [length].
*
* If [exists] is `true`, then fails if such [Override] does not exist.
* Otherwise remembers this it into [override].
*
* If [exists] is `false`, then fails if such [Override] exists.
*/
/// Finds an [Override] with the given [offset] and [length].
///
/// If [exists] is `true`, then fails if such [Override] does not exist.
/// Otherwise remembers this it into [override].
///
/// If [exists] is `false`, then fails if such [Override] exists.
void findOverride(int offset, int length, [bool exists]) {
for (Override override in overridesList) {
if (override.offset == offset && override.length == length) {

View file

@ -37,9 +37,7 @@ int findIdentifierLength(String search) {
return length;
}
/**
* An abstract base for all 'analysis' domain tests.
*/
/// An abstract base for all 'analysis' domain tests.
class AbstractAnalysisTest with ResourceProviderMixin {
bool generateSummaryFiles = false;
MockServerChannel serverChannel;
@ -130,9 +128,7 @@ class AbstractAnalysisTest with ResourceProviderMixin {
InstrumentationService.NULL_SERVICE);
}
/**
* Creates a project [projectPath].
*/
/// Creates a project [projectPath].
void createProject({Map<String, String> packageRoots}) {
newFolder(projectPath);
Request request = AnalysisSetAnalysisRootsParams([projectPath], [],
@ -147,10 +143,8 @@ class AbstractAnalysisTest with ResourceProviderMixin {
}
}
/**
* Returns the offset of [search] in the file at the given [path].
* Fails if not found.
*/
/// Returns the offset of [search] in the file at the given [path].
/// Fails if not found.
int findFileOffset(String path, String search) {
File file = getFile(path);
String code = file.createSource().contents.data;
@ -159,19 +153,15 @@ class AbstractAnalysisTest with ResourceProviderMixin {
return offset;
}
/**
* Returns the offset of [search] in [testCode].
* Fails if not found.
*/
/// Returns the offset of [search] in [testCode].
/// Fails if not found.
int findOffset(String search) {
int offset = testCode.indexOf(search);
expect(offset, isNot(-1));
return offset;
}
/**
* Validates that the given [request] is handled successfully.
*/
/// Validates that the given [request] is handled successfully.
Response handleSuccessfulRequest(Request request, {RequestHandler handler}) {
handler ??= this.handler;
Response response = handler.handleRequest(request);
@ -227,17 +217,13 @@ class AbstractAnalysisTest with ResourceProviderMixin {
serverChannel = null;
}
/**
* Returns a [Future] that completes when the server's analysis is complete.
*/
/// Returns a [Future] that completes when the server's analysis is complete.
Future waitForTasksFinished() {
return server.onAnalysisComplete;
}
/**
* Completes with a successful [Response] for the given [request].
* Otherwise fails.
*/
/// Completes with a successful [Response] for the given [request].
/// Otherwise fails.
Future<Response> waitResponse(Request request,
{bool throwOnError = true}) async {
return serverChannel.sendRequest(request, throwOnError: throwOnError);

View file

@ -30,10 +30,8 @@ class AnalysisServerTest with ResourceProviderMixin {
MockServerChannel channel;
AnalysisServer server;
/**
* Test that having multiple analysis contexts analyze the same file doesn't
* cause that file to receive duplicate notifications when it's modified.
*/
/// Test that having multiple analysis contexts analyze the same file doesn't
/// cause that file to receive duplicate notifications when it's modified.
Future do_not_test_no_duplicate_notifications() async {
// Subscribe to STATUS so we'll know when analysis is done.
server.serverServices = {ServerService.STATUS};

View file

@ -23,20 +23,14 @@ void main() {
class ByteStreamClientChannelTest {
ByteStreamClientChannel channel;
/**
* Sink that may be used to deliver data to the channel, as though it's
* coming from the server.
*/
/// Sink that may be used to deliver data to the channel, as though it's
/// coming from the server.
IOSink inputSink;
/**
* Sink through which the channel delivers data to the server.
*/
/// Sink through which the channel delivers data to the server.
IOSink outputSink;
/**
* Stream of lines sent back to the client by the channel.
*/
/// Stream of lines sent back to the client by the channel.
Stream<String> outputLineStream;
void setUp() {
@ -109,30 +103,20 @@ class ByteStreamClientChannelTest {
class ByteStreamServerChannelTest {
ByteStreamServerChannel channel;
/**
* Sink that may be used to deliver data to the channel, as though it's
* coming from the client.
*/
/// Sink that may be used to deliver data to the channel, as though it's
/// coming from the client.
IOSink inputSink;
/**
* Stream of lines sent back to the client by the channel.
*/
/// Stream of lines sent back to the client by the channel.
Stream<String> outputLineStream;
/**
* Stream of requests received from the channel via [listen()].
*/
/// Stream of requests received from the channel via [listen()].
Stream<Request> requestStream;
/**
* Stream of errors received from the channel via [listen()].
*/
/// Stream of errors received from the channel via [listen()].
Stream errorStream;
/**
* Future which is completed when then [listen()] reports [onDone].
*/
/// Future which is completed when then [listen()] reports [onDone].
Future doneFuture;
void setUp() {

View file

@ -14,18 +14,12 @@ void main() {
builder.buildAll();
}
/**
* A builder that builds the completion tests.
*/
/// A builder that builds the completion tests.
class CompletionTestBuilder {
/**
* Number of tests that have been built that are expected to pass.
*/
/// Number of tests that have been built that are expected to pass.
int expectedPassCount = 0;
/**
* Number of tests that have been built that are expected to fail.
*/
/// Number of tests that have been built that are expected to fail.
int expectedFailCount = 0;
void buildAll() {
@ -2401,26 +2395,24 @@ class A<Z extends X> {
<String>['2+B']);
}
/**
* Generate a set of completion tests based on the given [originalSource].
*
* The source string has completion points embedded in it, which are
* identified by '!X' where X is a single character. Each X is matched to
* positive or negative results in the array of [validationStrings].
* Validation strings contain the name of a prediction with a two character
* prefix. The first character of the prefix corresponds to an X in the
* [originalSource]. The second character is either a '+' or a '-' indicating
* whether the string is a positive or negative result.
*
* The [originalSource] is the source for a completion test that contains
* completion points. The [validationStrings] are the positive and negative
* predictions.
*
* Optional argument [failingTests], if given, is a string, each character of
* which corresponds to an X in the [originalSource] for which the test is
* expected to fail. This should be used to mark known completion bugs that
* have not yet been fixed.
*/
/// Generate a set of completion tests based on the given [originalSource].
///
/// The source string has completion points embedded in it, which are
/// identified by '!X' where X is a single character. Each X is matched to
/// positive or negative results in the array of [validationStrings].
/// Validation strings contain the name of a prediction with a two character
/// prefix. The first character of the prefix corresponds to an X in the
/// [originalSource]. The second character is either a '+' or a '-' indicating
/// whether the string is a positive or negative result.
///
/// The [originalSource] is the source for a completion test that contains
/// completion points. The [validationStrings] are the positive and negative
/// predictions.
///
/// Optional argument [failingTests], if given, is a string, each character of
/// which corresponds to an X in the [originalSource] for which the test is
/// expected to fail. This should be used to mark known completion bugs that
/// have not yet been fixed.
void buildTests(String baseName, String originalSource, List<String> results,
{Map<String, String> extraFiles, String failingTests = ''}) {
List<LocationSpec> completionTests =

View file

@ -10,9 +10,7 @@ import 'package:test/test.dart';
import 'domain_completion_test.dart';
/**
* A base class for classes containing completion tests.
*/
/// A base class for classes containing completion tests.
class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest {
static const String CURSOR_MARKER = '!';
@ -64,10 +62,8 @@ class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest {
}
}
/**
* Discard any results that do not start with the characters the user has
* "already typed".
*/
/// Discard any results that do not start with the characters the user has
/// "already typed".
void filterResults(String content) {
String charsAlreadyTyped =
content.substring(replacementOffset, completionOffset).toLowerCase();
@ -103,9 +99,7 @@ class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest {
}
}
/**
* A specification of the completion results expected at a given location.
*/
/// A specification of the completion results expected at a given location.
class LocationSpec {
String id;
int testLocation = -1;
@ -115,22 +109,21 @@ class LocationSpec {
LocationSpec(this.id);
/**
* Parse a set of tests from the given `originalSource`. Return a list of the
* specifications that were parsed.
*
* The source string has test locations embedded in it, which are identified
* by '!X' where X is a single character. Each X is matched to positive or
* negative results in the array of [validationStrings]. Validation strings
* contain the name of a prediction with a two character prefix. The first
* character of the prefix corresponds to an X in the [originalSource]. The
* second character is either a '+' or a '-' indicating whether the string is
* a positive or negative result. If logical not is needed in the source it
* can be represented by '!!'.
*
* The [originalSource] is the source for a test that contains test locations.
* The [validationStrings] are the positive and negative predictions.
*/
/// Parse a set of tests from the given `originalSource`. Return a list of the
/// specifications that were parsed.
///
/// The source string has test locations embedded in it, which are identified
/// by '!X' where X is a single character. Each X is matched to positive or
/// negative results in the array of [validationStrings]. Validation strings
/// contain the name of a prediction with a two character prefix. The first
/// character of the prefix corresponds to an X in the [originalSource]. The
/// second character is either a '+' or a '-' indicating whether the string is
/// a positive or negative result. If logical not is needed in the source it
/// can be represented by '!!'.
///
/// The [originalSource] is the source for a test that contains test
/// locations. The [validationStrings] are the positive and negative
/// predictions.
static List<LocationSpec> from(
String originalSource, List<String> validationStrings) {
Map<String, LocationSpec> tests = HashMap<String, LocationSpec>();

View file

@ -1601,10 +1601,8 @@ sky_engine:lib/''');
});
}
/**
* Verify that package URI's for source files in [path] will be resolved
* using a package root matching [expectation].
*/
/// Verify that package URI's for source files in [path] will be resolved
/// using a package root matching [expectation].
void _checkPackageRoot(String path, expectation) {
// TODO(brianwilkerson) Figure out how to test this. Possibly by comparing
// the contents of the package map (although that approach doesn't work at
@ -1617,29 +1615,19 @@ sky_engine:lib/''');
}
abstract class ContextManagerTest with ResourceProviderMixin {
/**
* The name of the 'bin' directory.
*/
/// The name of the 'bin' directory.
static const String BIN_NAME = 'bin';
/**
* The name of the 'example' directory.
*/
/// The name of the 'example' directory.
static const String EXAMPLE_NAME = 'example';
/**
* The name of the 'lib' directory.
*/
/// The name of the 'lib' directory.
static const String LIB_NAME = 'lib';
/**
* The name of the 'src' directory.
*/
/// The name of the 'src' directory.
static const String SRC_NAME = 'src';
/**
* The name of the 'test' directory.
*/
/// The name of the 'test' directory.
static const String TEST_NAME = 'test';
ContextManagerImpl manager;
@ -1687,10 +1675,8 @@ abstract class ContextManagerTest with ResourceProviderMixin {
Map<String, List<Folder>> get _currentPackageMap => _packageMap(projPath);
/**
* TODO(brianwilkerson) This doesn't add the strong mode processor when using
* the new analysis driver.
*/
/// TODO(brianwilkerson) This doesn't add the strong mode processor when using
/// the new analysis driver.
ErrorProcessor getProcessor(AnalysisError error) => errorProcessors
.firstWhere((ErrorProcessor p) => p.appliesTo(error), orElse: () => null);
@ -2353,67 +2339,43 @@ analyzer:
}
class TestContextManagerCallbacks extends ContextManagerCallbacks {
/**
* Source of timestamps stored in [currentContextFilePaths].
*/
/// Source of timestamps stored in [currentContextFilePaths].
int now = 0;
/**
* The analysis driver that was created.
*/
/// The analysis driver that was created.
AnalysisDriver currentDriver;
/**
* A table mapping paths to the analysis driver associated with that path.
*/
/// A table mapping paths to the analysis driver associated with that path.
Map<String, AnalysisDriver> driverMap = <String, AnalysisDriver>{};
/**
* Map from context to the timestamp when the context was created.
*/
/// Map from context to the timestamp when the context was created.
Map<String, int> currentContextTimestamps = <String, int>{};
/**
* Map from context to (map from file path to timestamp of last event).
*/
/// Map from context to (map from file path to timestamp of last event).
final Map<String, Map<String, int>> currentContextFilePaths =
<String, Map<String, int>>{};
/**
* A map from the paths of contexts to a set of the sources that should be
* explicitly analyzed in those contexts.
*/
/// A map from the paths of contexts to a set of the sources that should be
/// explicitly analyzed in those contexts.
final Map<String, Set<Source>> currentContextSources =
<String, Set<Source>>{};
/**
* Resource provider used for this test.
*/
/// Resource provider used for this test.
final ResourceProvider resourceProvider;
/**
* The manager managing the SDKs.
*/
/// The manager managing the SDKs.
final DartSdkManager sdkManager;
/**
* The logger used by the scheduler and the driver.
*/
/// The logger used by the scheduler and the driver.
final PerformanceLog logger;
/**
* The scheduler used by the driver.
*/
/// The scheduler used by the driver.
final AnalysisDriverScheduler scheduler;
/**
* The list of `flushedFiles` in the last [removeContext] invocation.
*/
/// The list of `flushedFiles` in the last [removeContext] invocation.
List<String> lastFlushedFiles;
/**
* The watch events that have been broadcast.
*/
/// The watch events that have been broadcast.
List<WatchEvent> watchEvents = <WatchEvent>[];
@override
@ -2422,21 +2384,15 @@ class TestContextManagerCallbacks extends ContextManagerCallbacks {
TestContextManagerCallbacks(
this.resourceProvider, this.sdkManager, this.logger, this.scheduler);
/**
* Return the current set of analysis options.
*/
/// Return the current set of analysis options.
AnalysisOptions get analysisOptions => currentDriver?.analysisOptions;
/**
* Return the paths to the context roots that currently exist.
*/
/// Return the paths to the context roots that currently exist.
Iterable<String> get currentContextRoots {
return currentContextTimestamps.keys;
}
/**
* Return the paths to the files being analyzed in the current context root.
*/
/// Return the paths to the files being analyzed in the current context root.
Iterable<String> get currentFilePaths {
if (currentDriver == null) {
return <String>[];
@ -2444,9 +2400,7 @@ class TestContextManagerCallbacks extends ContextManagerCallbacks {
return currentDriver.addedFiles;
}
/**
* Return the current source factory.
*/
/// Return the current source factory.
SourceFactory get sourceFactory => currentDriver?.sourceFactory;
@override
@ -2525,9 +2479,7 @@ class TestContextManagerCallbacks extends ContextManagerCallbacks {
return builder;
}
/**
* Return the paths to the files being analyzed in the current context root.
*/
/// Return the paths to the files being analyzed in the current context root.
Iterable<Source> currentFileSources(String contextPath) {
if (currentDriver == null) {
return <Source>[];
@ -2542,9 +2494,7 @@ class TestContextManagerCallbacks extends ContextManagerCallbacks {
});
}
/**
* Return the paths to the files being analyzed in the current context root.
*/
/// Return the paths to the files being analyzed in the current context root.
Iterable<String> getCurrentFilePaths(String contextPath) {
if (currentDriver == null) {
return <String>[];

View file

@ -337,9 +337,7 @@ main(A a) {
}
}
/**
* A helper to test 'analysis.*' requests.
*/
/// A helper to test 'analysis.*' requests.
class AnalysisTestHelper with ResourceProviderMixin {
MockServerChannel serverChannel;
AnalysisServer server;
@ -387,9 +385,7 @@ class AnalysisTestHelper with ResourceProviderMixin {
});
}
/**
* Returns a [Future] that completes when the server's analysis is complete.
*/
/// Returns a [Future] that completes when the server's analysis is complete.
Future get onAnalysisComplete {
return server.onAnalysisComplete;
}
@ -416,9 +412,7 @@ class AnalysisTestHelper with ResourceProviderMixin {
addAnalysisSubscription(AnalysisService.NAVIGATION, file);
}
/**
* Creates an empty project `/project`.
*/
/// Creates an empty project `/project`.
void createEmptyProject() {
newFolder(projectPath);
Request request =
@ -426,10 +420,8 @@ class AnalysisTestHelper with ResourceProviderMixin {
handleSuccessfulRequest(request);
}
/**
* Creates a project with a single Dart file `/project/bin/test.dart` with
* the given [code].
*/
/// Creates a project with a single Dart file `/project/bin/test.dart` with
/// the given [code].
void createSingleFileProject(code) {
testCode = _getCodeString(code);
newFolder(projectPath);
@ -439,20 +431,16 @@ class AnalysisTestHelper with ResourceProviderMixin {
handleSuccessfulRequest(request);
}
/**
* Returns the offset of [search] in [testCode].
* Fails if not found.
*/
/// Returns the offset of [search] in [testCode].
/// Fails if not found.
int findOffset(String search) {
int offset = testCode.indexOf(search);
expect(offset, isNot(-1));
return offset;
}
/**
* Returns [AnalysisError]s recorded for the given [file].
* May be empty, but not `null`.
*/
/// Returns [AnalysisError]s recorded for the given [file].
/// May be empty, but not `null`.
List<AnalysisError> getErrors(String file) {
List<AnalysisError> errors = filesErrors[file];
if (errors != null) {
@ -461,10 +449,8 @@ class AnalysisTestHelper with ResourceProviderMixin {
return <AnalysisError>[];
}
/**
* Returns highlights recorded for the given [file].
* May be empty, but not `null`.
*/
/// Returns highlights recorded for the given [file].
/// May be empty, but not `null`.
List<HighlightRegion> getHighlights(String file) {
List<HighlightRegion> highlights = filesHighlights[file];
if (highlights != null) {
@ -473,10 +459,8 @@ class AnalysisTestHelper with ResourceProviderMixin {
return [];
}
/**
* Returns navigation regions recorded for the given [file].
* May be empty, but not `null`.
*/
/// Returns navigation regions recorded for the given [file].
/// May be empty, but not `null`.
List<NavigationRegion> getNavigation(String file) {
List<NavigationRegion> navigation = filesNavigation[file];
if (navigation != null) {
@ -485,50 +469,38 @@ class AnalysisTestHelper with ResourceProviderMixin {
return [];
}
/**
* Returns [AnalysisError]s recorded for the [testFile].
* May be empty, but not `null`.
*/
/// Returns [AnalysisError]s recorded for the [testFile].
/// May be empty, but not `null`.
List<AnalysisError> getTestErrors() {
return getErrors(testFile);
}
/**
* Returns highlights recorded for the given [testFile].
* May be empty, but not `null`.
*/
/// Returns highlights recorded for the given [testFile].
/// May be empty, but not `null`.
List<HighlightRegion> getTestHighlights() {
return getHighlights(testFile);
}
/**
* Returns navigation information recorded for the given [testFile].
* May be empty, but not `null`.
*/
/// Returns navigation information recorded for the given [testFile].
/// May be empty, but not `null`.
List<NavigationRegion> getTestNavigation() {
return getNavigation(testFile);
}
/**
* Validates that the given [request] is handled successfully.
*/
/// Validates that the given [request] is handled successfully.
void handleSuccessfulRequest(Request request) {
Response response = handler.handleRequest(request);
expect(response, isResponseSuccess('0'));
}
/**
* Send an `updateContent` request for [testFile].
*/
/// Send an `updateContent` request for [testFile].
void sendContentChange(dynamic contentChange) {
Request request =
AnalysisUpdateContentParams({testFile: contentChange}).toRequest('0');
handleSuccessfulRequest(request);
}
/**
* Stops the associated server.
*/
/// Stops the associated server.
void stopServer() {
server.done();
}

View file

@ -822,10 +822,8 @@ flutter:${libFolder.toUri()}
''');
}
/**
* Tests that there is refactoring of the given [kind] is available at the
* [search] offset.
*/
/// Tests that there is refactoring of the given [kind] is available at the
/// [search] offset.
Future assertHasKind(
String code, String search, RefactoringKind kind, bool expected) async {
addTestFile(code);
@ -839,17 +837,13 @@ flutter:${libFolder.toUri()}
expect(kinds, matcher);
}
/**
* Tests that there is a RENAME refactoring available at the [search] offset.
*/
/// Tests that there is a RENAME refactoring available at the [search] offset.
Future assertHasRenameRefactoring(String code, String search) async {
return assertHasKind(code, search, RefactoringKind.RENAME, true);
}
/**
* Returns the list of available refactorings for the given [offset] and
* [length].
*/
/// Returns the list of available refactorings for the given [offset] and
/// [length].
Future getRefactorings(int offset, int length) async {
Request request =
EditGetAvailableRefactoringsParams(testFile, offset, length)
@ -860,9 +854,7 @@ flutter:${libFolder.toUri()}
kinds = result.kinds;
}
/**
* Returns the list of available refactorings at the offset of [search].
*/
/// Returns the list of available refactorings at the offset of [search].
Future getRefactoringsAtString(String search) {
int offset = findOffset(search);
return getRefactorings(offset, 0);
@ -2132,9 +2124,7 @@ main() {
class _AbstractGetRefactoring_Test extends AbstractAnalysisTest {
bool shouldWaitForFullAnalysis = true;
/**
* Asserts that [problems] has a single ERROR problem.
*/
/// Asserts that [problems] has a single ERROR problem.
void assertResultProblemsError(List<RefactoringProblem> problems,
[String message]) {
RefactoringProblem problem = problems[0];
@ -2145,9 +2135,7 @@ class _AbstractGetRefactoring_Test extends AbstractAnalysisTest {
}
}
/**
* Asserts that [result] has a single FATAL problem.
*/
/// Asserts that [result] has a single FATAL problem.
void assertResultProblemsFatal(List<RefactoringProblem> problems,
[String message]) {
RefactoringProblem problem = problems[0];
@ -2159,18 +2147,14 @@ class _AbstractGetRefactoring_Test extends AbstractAnalysisTest {
}
}
/**
* Asserts that [result] has no problems at all.
*/
/// Asserts that [result] has no problems at all.
void assertResultProblemsOK(EditGetRefactoringResult result) {
expect(result.initialProblems, isEmpty);
expect(result.optionsProblems, isEmpty);
expect(result.finalProblems, isEmpty);
}
/**
* Asserts that [result] has a single WARNING problem.
*/
/// Asserts that [result] has a single WARNING problem.
void assertResultProblemsWarning(List<RefactoringProblem> problems,
[String message]) {
RefactoringProblem problem = problems[0];
@ -2193,10 +2177,8 @@ class _AbstractGetRefactoring_Test extends AbstractAnalysisTest {
assertTestRefactoringResult(result, expectedCode);
}
/**
* Asserts that the given [EditGetRefactoringResult] has a [testFile] change
* which results in the [expectedCode].
*/
/// Asserts that the given [EditGetRefactoringResult] has a [testFile] change
/// which results in the [expectedCode].
void assertTestRefactoringResult(
EditGetRefactoringResult result, String expectedCode) {
SourceChange change = result.change;

View file

@ -18,10 +18,8 @@ void main() {
});
}
/**
* Tests that when an SDK path is specified on the command-line (via the `--sdk`
* argument) that the specified SDK is used.
*/
/// Tests that when an SDK path is specified on the command-line (via the
/// `--sdk` argument) that the specified SDK is used.
@reflectiveTest
class AnalysisDomainGetErrorsTest
extends AbstractAnalysisServerIntegrationTest {

View file

@ -20,14 +20,10 @@ void main() {
@reflectiveTest
class AnalysisGetHoverIntegrationTest
extends AbstractAnalysisServerIntegrationTest {
/**
* Pathname of the file containing Dart code.
*/
/// Pathname of the file containing Dart code.
String pathname;
/**
* Dart code under test.
*/
/// Dart code under test.
final String text = r'''
library lib.test;
@ -48,19 +44,17 @@ main() {
}
''';
/**
* Check that a getHover request on the substring [target] produces a result
* which has length [length], has an elementDescription matching every
* regexp in [descriptionRegexps], has a kind of [kind], and has a staticType
* matching [staticTypeRegexps].
*
* [isCore] means the hover info should indicate that the element is defined
* in dart.core. [docRegexp], if specified, should match the documentation
* string of the element. [isLiteral] means the hover should indicate a
* literal value. [parameterRegexps] means is a set of regexps which should
* match the hover parameters. [propagatedType], if specified, is the
* expected propagated type of the element.
*/
/// Check that a getHover request on the substring [target] produces a result
/// which has length [length], has an elementDescription matching every
/// regexp in [descriptionRegexps], has a kind of [kind], and has a staticType
/// matching [staticTypeRegexps].
///
/// [isCore] means the hover info should indicate that the element is defined
/// in dart.core. [docRegexp], if specified, should match the documentation
/// string of the element. [isLiteral] means the hover should indicate a
/// literal value. [parameterRegexps] means is a set of regexps which should
/// match the hover parameters. [propagatedType], if specified, is the
/// expected propagated type of the element.
Future<AnalysisGetHoverResult> checkHover(
String target,
int length,
@ -123,10 +117,8 @@ main() {
});
}
/**
* Check that a getHover request on the substring [target] produces no
* results.
*/
/// Check that a getHover request on the substring [target] produces no
/// results.
Future checkNoHover(String target) {
int offset = text.indexOf(target);
return sendAnalysisGetHover(pathname, offset).then((result) {

View file

@ -21,21 +21,15 @@ void main() {
@reflectiveTest
class AnalysisGetImportedElementsIntegrationTest
extends AbstractAnalysisServerIntegrationTest {
/**
* Pathname of the file containing Dart code.
*/
/// Pathname of the file containing Dart code.
String pathname;
/**
* Dart code under test.
*/
/// Dart code under test.
String text;
/**
* Check that an analysis.getImportedElements request on the region starting
* with the first character that matches [target] and having the given
* [length] matches the given list of [expected] imported elements.
*/
/// Check that an analysis.getImportedElements request on the region starting
/// with the first character that matches [target] and having the given
/// [length] matches the given list of [expected] imported elements.
Future<void> checkElements(
String target, List<ImportedElements> expected) async {
bool equals(
@ -81,10 +75,8 @@ class AnalysisGetImportedElementsIntegrationTest
}
}
/**
* Check that an analysis.getImportedElements request on the region matching
* [target] produces an empty list of elements.
*/
/// Check that an analysis.getImportedElements request on the region matching
/// [target] produces an empty list of elements.
Future<void> checkNoElements(String target) async {
int offset = text.indexOf(target);
AnalysisGetImportedElementsResult result =

View file

@ -2,12 +2,10 @@
// 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.
/**
* This test verifies that if reanalysis is performed while reanalysis is in
* progress, no problems occur.
*
* See dartbug.com/21448.
*/
/// This test verifies that if reanalysis is performed while reanalysis is in
/// progress, no problems occur.
///
/// See dartbug.com/21448.
import 'dart:async';
import 'package:test/test.dart';

View file

@ -22,15 +22,11 @@ void main() {
@reflectiveTest
class AnalysisGetImportElementsIntegrationTest
extends AbstractAnalysisServerIntegrationTest {
/**
* Pathname of the file containing Dart code.
*/
/// Pathname of the file containing Dart code.
String pathname;
/**
* Check that an edit.importElements request with the given list of [elements]
* produces the [expected] list of edits.
*/
/// Check that an edit.importElements request with the given list of
/// [elements] produces the [expected] list of edits.
Future<void> checkEdits(
List<ImportedElements> elements, List<SourceEdit> expected,
{String expectedFile}) async {
@ -71,10 +67,8 @@ class AnalysisGetImportElementsIntegrationTest
}
}
/**
* Check that an edit.importElements request with the given list of [elements]
* produces no edits.
*/
/// Check that an edit.importElements request with the given list of
/// [elements] produces no edits.
Future<void> checkNoEdits(List<ImportedElements> elements) async {
EditImportElementsResult result =
await sendEditImportElements(pathname, <ImportedElements>[]);

View file

@ -123,10 +123,8 @@ class LspServerClient {
_process.kill();
}
/**
* Find the root directory of the analysis_server package by proceeding
* upward to the 'test' dir, and then going up one more directory.
*/
/// Find the root directory of the analysis_server package by proceeding
/// upward to the 'test' dir, and then going up one more directory.
String findRoot(String pathname) {
while (!['benchmark', 'test'].contains(basename(pathname))) {
String parent = dirname(pathname);

View file

@ -19,9 +19,7 @@ void main() {
@reflectiveTest
class GetTypeHierarchyTest extends AbstractAnalysisServerIntegrationTest {
/**
* Pathname of the main file to run tests in.
*/
/// Pathname of the main file to run tests in.
String pathname;
Future getTypeHierarchy_badTarget() {
@ -229,30 +227,20 @@ class Pivot /* target */ extends Base2 {}
}
}
/**
* Results of a getTypeHierarchy request, processed for easier testing.
*/
/// Results of a getTypeHierarchy request, processed for easier testing.
class HierarchyResults {
/**
* The list of hierarchy items from the result.
*/
/// The list of hierarchy items from the result.
List<TypeHierarchyItem> items;
/**
* The first hierarchy item from the result, which represents the pivot
* class.
*/
/// The first hierarchy item from the result, which represents the pivot
/// class.
TypeHierarchyItem pivot;
/**
* A map from element name to item index.
*/
/// A map from element name to item index.
Map<String, int> nameToIndex;
/**
* Create a [HierarchyResults] object based on the result from a
* getTypeHierarchy request.
*/
/// Create a [HierarchyResults] object based on the result from a
/// getTypeHierarchy request.
HierarchyResults(this.items) {
pivot = items[0];
nameToIndex = <String, int>{};
@ -261,9 +249,7 @@ class HierarchyResults {
}
}
/**
* Get an item by class name.
*/
/// Get an item by class name.
TypeHierarchyItem getItem(String name) {
if (nameToIndex.containsKey(name)) {
return items[nameToIndex[name]];

View file

@ -38,9 +38,7 @@ Matcher isMapOf(Matcher keyMatcher, Matcher valueMatcher) =>
Matcher isOneOf(List<Matcher> choiceMatchers) => _OneOf(choiceMatchers);
/**
* Assert that [actual] matches [matcher].
*/
/// Assert that [actual] matches [matcher].
void outOfTestExpect(actual, Matcher matcher,
{String reason, skip, bool verbose = false}) {
var matchState = {};
@ -68,80 +66,57 @@ String _defaultFailFormatter(
return description.toString();
}
/**
* Type of closures used by LazyMatcher.
*/
/// Type of closures used by LazyMatcher.
typedef MatcherCreator = Matcher Function();
/**
* Type of closures used by MatchesJsonObject to record field mismatches.
*/
/// Type of closures used by MatchesJsonObject to record field mismatches.
typedef MismatchDescriber = Description Function(
Description mismatchDescription);
/**
* Type of callbacks used to process notifications.
*/
/// Type of callbacks used to process notifications.
typedef NotificationProcessor = void Function(String event, Map params);
/**
* Base class for analysis server integration tests.
*/
/// Base class for analysis server integration tests.
abstract class AbstractAnalysisServerIntegrationTest
extends IntegrationTestMixin {
/**
* Amount of time to give the server to respond to a shutdown request before
* forcibly terminating it.
*/
/// Amount of time to give the server to respond to a shutdown request before
/// forcibly terminating it.
static const Duration SHUTDOWN_TIMEOUT = Duration(seconds: 60);
/**
* Connection to the analysis server.
*/
/// Connection to the analysis server.
@override
final Server server = Server();
/**
* Temporary directory in which source files can be stored.
*/
/// Temporary directory in which source files can be stored.
Directory sourceDirectory;
/**
* Map from file path to the list of analysis errors which have most recently
* been received for the file.
*/
/// Map from file path to the list of analysis errors which have most recently
/// been received for the file.
Map<String, List<AnalysisError>> currentAnalysisErrors =
HashMap<String, List<AnalysisError>>();
/**
* The last list of analyzed files received.
*/
/// The last list of analyzed files received.
List<String> lastAnalyzedFiles;
/**
* True if the teardown process should skip sending a "server.shutdown"
* request (e.g. because the server is known to have already shutdown).
*/
/// True if the teardown process should skip sending a "server.shutdown"
/// request (e.g. because the server is known to have already shutdown).
bool skipShutdown = false;
/**
* True if we are currently subscribed to [SERVER_NOTIFICATION_STATUS] updates.
*/
/// True if we are currently subscribed to [SERVER_NOTIFICATION_STATUS]
/// updates.
bool _subscribedToServerStatus = false;
AbstractAnalysisServerIntegrationTest() {
initializeInttestMixin();
}
/**
* Return a future which will complete when a 'server.status' notification is
* received from the server with 'analyzing' set to false.
*
* The future will only be completed by 'server.status' notifications that are
* received after this function call. So it is safe to use this getter
* multiple times in one test; each time it is used it will wait afresh for
* analysis to finish.
*/
/// Return a future which will complete when a 'server.status' notification is
/// received from the server with 'analyzing' set to false.
///
/// The future will only be completed by 'server.status' notifications that
/// are received after this function call. So it is safe to use this getter
/// multiple times in one test; each time it is used it will wait afresh for
/// analysis to finish.
Future<ServerStatusParams> get analysisFinished {
Completer<ServerStatusParams> completer = Completer<ServerStatusParams>();
StreamSubscription<ServerStatusParams> subscription;
@ -157,10 +132,8 @@ abstract class AbstractAnalysisServerIntegrationTest
return completer.future;
}
/**
* Print out any messages exchanged with the server. If some messages have
* already been exchanged with the server, they are printed out immediately.
*/
/// Print out any messages exchanged with the server. If some messages have
/// already been exchanged with the server, they are printed out immediately.
void debugStdio() {
server.debugStdio();
}
@ -168,9 +141,7 @@ abstract class AbstractAnalysisServerIntegrationTest
List<AnalysisError> getErrors(String pathname) =>
currentAnalysisErrors[pathname];
/**
* Read a source file with the given absolute [pathname].
*/
/// Read a source file with the given absolute [pathname].
String readFile(String pathname) => File(pathname).readAsStringSync();
@override
@ -179,10 +150,8 @@ abstract class AbstractAnalysisServerIntegrationTest
return super.sendServerSetSubscriptions(subscriptions);
}
/**
* The server is automatically started before every test, and a temporary
* [sourceDirectory] is created.
*/
/// The server is automatically started before every test, and a temporary
/// [sourceDirectory] is created.
Future setUp() async {
sourceDirectory = Directory(Directory.systemTemp
.createTempSync('analysisServer')
@ -211,9 +180,7 @@ abstract class AbstractAnalysisServerIntegrationTest
return serverConnected.future;
}
/**
* If [skipShutdown] is not set, shut down the server.
*/
/// If [skipShutdown] is not set, shut down the server.
Future shutdownIfNeeded() {
if (skipShutdown) {
return Future.value();
@ -228,21 +195,17 @@ abstract class AbstractAnalysisServerIntegrationTest
});
}
/**
* Convert the given [relativePath] to an absolute path, by interpreting it
* relative to [sourceDirectory]. On Windows any forward slashes in
* [relativePath] are converted to backslashes.
*/
/// Convert the given [relativePath] to an absolute path, by interpreting it
/// relative to [sourceDirectory]. On Windows any forward slashes in
/// [relativePath] are converted to backslashes.
String sourcePath(String relativePath) {
return join(sourceDirectory.path, relativePath.replaceAll('/', separator));
}
/**
* Send the server an 'analysis.setAnalysisRoots' command directing it to
* analyze [sourceDirectory]. If [subscribeStatus] is true (the default),
* then also enable [SERVER_NOTIFICATION_STATUS] notifications so that
* [analysisFinished] can be used.
*/
/// Send the server an 'analysis.setAnalysisRoots' command directing it to
/// analyze [sourceDirectory]. If [subscribeStatus] is true (the default),
/// then also enable [SERVER_NOTIFICATION_STATUS] notifications so that
/// [analysisFinished] can be used.
Future standardAnalysisSetup({bool subscribeStatus = true}) {
List<Future> futures = <Future>[];
if (subscribeStatus) {
@ -252,9 +215,7 @@ abstract class AbstractAnalysisServerIntegrationTest
return Future.wait(futures);
}
/**
* Start [server].
*/
/// Start [server].
Future startServer({
int diagnosticPort,
int servicesPort,
@ -263,25 +224,21 @@ abstract class AbstractAnalysisServerIntegrationTest
diagnosticPort: diagnosticPort, servicesPort: servicesPort);
}
/**
* After every test, the server is stopped and [sourceDirectory] is deleted.
*/
/// After every test, the server is stopped and [sourceDirectory] is deleted.
Future tearDown() {
return shutdownIfNeeded().then((_) {
sourceDirectory.deleteSync(recursive: true);
});
}
/**
* Write a source file with the given absolute [pathname] and [contents].
*
* If the file didn't previously exist, it is created. If it did, it is
* overwritten.
*
* Parent directories are created as necessary.
*
* Return a normalized path to the file (with symbolic links resolved).
*/
/// Write a source file with the given absolute [pathname] and [contents].
///
/// If the file didn't previously exist, it is created. If it did, it is
/// overwritten.
///
/// Parent directories are created as necessary.
///
/// Return a normalized path to the file (with symbolic links resolved).
String writeFile(String pathname, String contents) {
Directory(dirname(pathname)).createSync(recursive: true);
File file = File(pathname);
@ -290,22 +247,16 @@ abstract class AbstractAnalysisServerIntegrationTest
}
}
/**
* Wrapper class for Matcher which doesn't create the underlying Matcher object
* until it is needed. This is necessary in order to create matchers that can
* refer to themselves (so that recursive data structures can be represented).
*/
/// Wrapper class for Matcher which doesn't create the underlying Matcher object
/// until it is needed. This is necessary in order to create matchers that can
/// refer to themselves (so that recursive data structures can be represented).
class LazyMatcher implements Matcher {
/**
* Callback that will be used to create the matcher the first time it is
* needed.
*/
/// Callback that will be used to create the matcher the first time it is
/// needed.
final MatcherCreator _creator;
/**
* The matcher returned by [_creator], if it has already been called.
* Otherwise null.
*/
/// The matcher returned by [_creator], if it has already been called.
/// Otherwise null.
Matcher _wrappedMatcher;
LazyMatcher(this._creator);
@ -330,26 +281,18 @@ class LazyMatcher implements Matcher {
return _wrappedMatcher.matches(item, matchState);
}
/**
* Create the wrapped matcher object, if it hasn't been created already.
*/
/// Create the wrapped matcher object, if it hasn't been created already.
void _createMatcher() {
_wrappedMatcher ??= _creator();
}
}
/**
* Matcher that matches a String drawn from a limited set.
*/
/// Matcher that matches a String drawn from a limited set.
class MatchesEnum extends Matcher {
/**
* Short description of the expected type.
*/
/// Short description of the expected type.
final String description;
/**
* The set of enum values that are allowed.
*/
/// The set of enum values that are allowed.
final List<String> allowedValues;
const MatchesEnum(this.description, this.allowedValues);
@ -364,26 +307,18 @@ class MatchesEnum extends Matcher {
}
}
/**
* Matcher that matches a JSON object, with a given set of required and
* optional fields, and their associated types (expressed as [Matcher]s).
*/
/// Matcher that matches a JSON object, with a given set of required and
/// optional fields, and their associated types (expressed as [Matcher]s).
class MatchesJsonObject extends _RecursiveMatcher {
/**
* Short description of the expected type.
*/
/// Short description of the expected type.
final String description;
/**
* Fields that are required to be in the JSON object, and [Matcher]s describing
* their expected types.
*/
/// Fields that are required to be in the JSON object, and [Matcher]s
/// describing their expected types.
final Map<String, Matcher> requiredFields;
/**
* Fields that are optional in the JSON object, and [Matcher]s describing
* their expected types.
*/
/// Fields that are optional in the JSON object, and [Matcher]s describing
/// their expected types.
final Map<String, Matcher> optionalFields;
const MatchesJsonObject(this.description, this.requiredFields,
@ -427,11 +362,9 @@ class MatchesJsonObject extends _RecursiveMatcher {
});
}
/**
* Check the type of a field called [key], having value [value], using
* [valueMatcher]. If it doesn't match, record a closure in [mismatches]
* which can describe the mismatch.
*/
/// Check the type of a field called [key], having value [value], using
/// [valueMatcher]. If it doesn't match, record a closure in [mismatches]
/// which can describe the mismatch.
void _checkField(String key, value, Matcher valueMatcher,
List<MismatchDescriber> mismatches) {
checkSubstructure(
@ -443,73 +376,49 @@ class MatchesJsonObject extends _RecursiveMatcher {
}
}
/**
* Instances of the class [Server] manage a connection to a server process, and
* facilitate communication to and from the server.
*/
/// Instances of the class [Server] manage a connection to a server process, and
/// facilitate communication to and from the server.
class Server {
/**
* Server process object, or null if server hasn't been started yet.
*/
/// Server process object, or null if server hasn't been started yet.
Process _process;
/**
* Commands that have been sent to the server but not yet acknowledged, and
* the [Completer] objects which should be completed when acknowledgement is
* received.
*/
/// Commands that have been sent to the server but not yet acknowledged, and
/// the [Completer] objects which should be completed when acknowledgement is
/// received.
final Map<String, Completer<Map<String, dynamic>>> _pendingCommands =
<String, Completer<Map<String, dynamic>>>{};
/**
* Number which should be used to compute the 'id' to send in the next command
* sent to the server.
*/
/// Number which should be used to compute the 'id' to send in the next
/// command sent to the server.
int _nextId = 0;
/**
* Messages which have been exchanged with the server; we buffer these
* up until the test finishes, so that they can be examined in the debugger
* or printed out in response to a call to [debugStdio].
*/
/// Messages which have been exchanged with the server; we buffer these
/// up until the test finishes, so that they can be examined in the debugger
/// or printed out in response to a call to [debugStdio].
final List<String> _recordedStdio = <String>[];
/**
* True if we are currently printing out messages exchanged with the server.
*/
/// True if we are currently printing out messages exchanged with the server.
bool _debuggingStdio = false;
/**
* True if we've received bad data from the server, and we are aborting the
* test.
*/
/// True if we've received bad data from the server, and we are aborting the
/// test.
bool _receivedBadDataFromServer = false;
/**
* Stopwatch that we use to generate timing information for debug output.
*/
/// Stopwatch that we use to generate timing information for debug output.
final Stopwatch _time = Stopwatch();
/**
* The [currentElapseTime] at which the last communication was received from the server
* or `null` if no communication has been received.
*/
/// The [currentElapseTime] at which the last communication was received from
/// the server or `null` if no communication has been received.
double lastCommunicationTime;
/**
* The current elapse time (seconds) since the server was started.
*/
/// The current elapse time (seconds) since the server was started.
double get currentElapseTime => _time.elapsedTicks / _time.frequency;
/**
* Future that completes when the server process exits.
*/
/// Future that completes when the server process exits.
Future<int> get exitCode => _process.exitCode;
/**
* Print out any messages exchanged with the server. If some messages have
* already been exchanged with the server, they are printed out immediately.
*/
/// Print out any messages exchanged with the server. If some messages have
/// already been exchanged with the server, they are printed out immediately.
void debugStdio() {
if (_debuggingStdio) {
return;
@ -520,10 +429,8 @@ class Server {
}
}
/**
* Find the root directory of the analysis_server package by proceeding
* upward to the 'test' dir, and then going up one more directory.
*/
/// Find the root directory of the analysis_server package by proceeding
/// upward to the 'test' dir, and then going up one more directory.
String findRoot(String pathname) {
while (!['benchmark', 'test'].contains(basename(pathname))) {
String parent = dirname(pathname);
@ -535,17 +442,13 @@ class Server {
return dirname(pathname);
}
/**
* Return a future that will complete when all commands that have been sent
* to the server so far have been flushed to the OS buffer.
*/
/// Return a future that will complete when all commands that have been sent
/// to the server so far have been flushed to the OS buffer.
Future flushCommands() {
return _process.stdin.flush();
}
/**
* Stop the server.
*/
/// Stop the server.
Future<int> kill(String reason) {
debugStdio();
_recordStdio('FORCIBLY TERMINATING PROCESS: $reason');
@ -553,10 +456,8 @@ class Server {
return _process.exitCode;
}
/**
* Start listening to output from the server, and deliver notifications to
* [notificationProcessor].
*/
/// Start listening to output from the server, and deliver notifications to
/// [notificationProcessor].
void listenToOutput(NotificationProcessor notificationProcessor) {
_process.stdout
.transform(utf8.decoder)
@ -627,14 +528,12 @@ class Server {
});
}
/**
* Send a command to the server. An 'id' will be automatically assigned.
* The returned [Future] will be completed when the server acknowledges the
* command with a response. If the server acknowledges the command with a
* normal (non-error) response, the future will be completed with the 'result'
* field from the response. If the server acknowledges the command with an
* error response, the future will be completed with an error.
*/
/// Send a command to the server. An 'id' will be automatically assigned.
/// The returned [Future] will be completed when the server acknowledges the
/// command with a response. If the server acknowledges the command with a
/// normal (non-error) response, the future will be completed with the
/// 'result' field from the response. If the server acknowledges the command
/// with an error response, the future will be completed with an error.
Future<Map<String, dynamic>> send(
String method, Map<String, dynamic> params) {
String id = '${_nextId++}';
@ -654,11 +553,9 @@ class Server {
return completer.future;
}
/**
* Start the server. If [profileServer] is `true`, the server will be started
* with "--observe" and "--pause-isolates-on-exit", allowing the observatory
* to be used.
*/
/// Start the server. If [profileServer] is `true`, the server will be started
/// with "--observe" and "--pause-isolates-on-exit", allowing the observatory
/// to be used.
Future start({
int diagnosticPort,
String instrumentationLogFile,
@ -741,9 +638,7 @@ class Server {
});
}
/**
* Deal with bad data received from the server.
*/
/// Deal with bad data received from the server.
void _badDataFromServer(String details, {bool silent = false}) {
if (!silent) {
_recordStdio('BAD DATA FROM SERVER: $details');
@ -764,10 +659,8 @@ class Server {
}));
}
/**
* Record a message that was exchanged with the server, and print it out if
* [debugStdio] has been called.
*/
/// Record a message that was exchanged with the server, and print it out if
/// [debugStdio] has been called.
void _recordStdio(String line) {
double elapsedTime = currentElapseTime;
line = '$elapsedTime: $line';
@ -778,9 +671,7 @@ class Server {
}
}
/**
* An error result from a server request.
*/
/// An error result from a server request.
class ServerErrorMessage {
final Map message;
@ -792,19 +683,13 @@ class ServerErrorMessage {
String toString() => message.toString();
}
/**
* Matcher that matches a list of objects, each of which satisfies the given
* matcher.
*/
/// Matcher that matches a list of objects, each of which satisfies the given
/// matcher.
class _ListOf extends Matcher {
/**
* Matcher which every element of the list must satisfy.
*/
/// Matcher which every element of the list must satisfy.
final Matcher elementMatcher;
/**
* Iterable matcher which we use to test the contents of the list.
*/
/// Iterable matcher which we use to test the contents of the list.
final Matcher iterableMatcher;
_ListOf(elementMatcher)
@ -836,19 +721,13 @@ class _ListOf extends Matcher {
}
}
/**
* Matcher that matches a map of objects, where each key/value pair in the
* map satisies the given key and value matchers.
*/
/// Matcher that matches a map of objects, where each key/value pair in the
/// map satisies the given key and value matchers.
class _MapOf extends _RecursiveMatcher {
/**
* Matcher which every key in the map must satisfy.
*/
/// Matcher which every key in the map must satisfy.
final Matcher keyMatcher;
/**
* Matcher which every value in the map must satisfy.
*/
/// Matcher which every value in the map must satisfy.
final Matcher valueMatcher;
_MapOf(this.keyMatcher, this.valueMatcher);
@ -883,14 +762,10 @@ class _MapOf extends _RecursiveMatcher {
}
}
/**
* Matcher that matches a union of different types, each of which is described
* by a matcher.
*/
/// Matcher that matches a union of different types, each of which is described
/// by a matcher.
class _OneOf extends Matcher {
/**
* Matchers for the individual choices.
*/
/// Matchers for the individual choices.
final List<Matcher> choiceMatchers;
_OneOf(this.choiceMatchers);
@ -925,19 +800,15 @@ class _OneOf extends Matcher {
}
}
/**
* Base class for matchers that operate by recursing through the contents of
* an object.
*/
/// Base class for matchers that operate by recursing through the contents of
/// an object.
abstract class _RecursiveMatcher extends Matcher {
const _RecursiveMatcher();
/**
* Check the type of a substructure whose value is [item], using [matcher].
* If it doesn't match, record a closure in [mismatches] which can describe
* the mismatch. [describeSubstructure] is used to describe which
* substructure did not match.
*/
/// Check the type of a substructure whose value is [item], using [matcher].
/// If it doesn't match, record a closure in [mismatches] which can describe
/// the mismatch. [describeSubstructure] is used to describe which
/// substructure did not match.
void checkSubstructure(
item,
Matcher matcher,
@ -1000,15 +871,11 @@ abstract class _RecursiveMatcher extends Matcher {
}
}
/**
* Populate [mismatches] with descriptions of all the ways in which [item]
* does not match.
*/
/// Populate [mismatches] with descriptions of all the ways in which [item]
/// does not match.
void populateMismatches(item, List<MismatchDescriber> mismatches);
/**
* Create a [MismatchDescriber] describing a mismatch with a simple string.
*/
/// Create a [MismatchDescriber] describing a mismatch with a simple string.
MismatchDescriber simpleDescription(String description) =>
(Description mismatchDescription) {
mismatchDescription.add(description);

View file

@ -309,25 +309,19 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final startOfDocPos = Position(0, 0);
final startOfDocRange = Range(Position(0, 0), Position(0, 0));
/**
* A stream of [NotificationMessage]s from the server that may be errors.
*/
/// A stream of [NotificationMessage]s from the server that may be errors.
Stream<NotificationMessage> get errorNotificationsFromServer {
return notificationsFromServer.where(_isErrorNotification);
}
/**
* A stream of [NotificationMessage]s from the server.
*/
/// A stream of [NotificationMessage]s from the server.
Stream<NotificationMessage> get notificationsFromServer {
return serverToClient
.where((m) => m is NotificationMessage)
.cast<NotificationMessage>();
}
/**
* A stream of [RequestMessage]s from the server.
*/
/// A stream of [RequestMessage]s from the server.
Stream<RequestMessage> get requestsFromServer {
return serverToClient
.where((m) => m is RequestMessage)

View file

@ -18,22 +18,16 @@ import 'package:test/test.dart';
const _jsonEncoder = JsonEncoder.withIndent(' ');
/**
* A [Matcher] that check that the given [Response] has an expected identifier
* and has an error. The error code may optionally be checked.
*/
/// A [Matcher] that check that the given [Response] has an expected identifier
/// and has an error. The error code may optionally be checked.
Matcher isResponseFailure(String id, [RequestErrorCode code]) =>
_IsResponseFailure(id, code);
/**
* A [Matcher] that check that the given [Response] has an expected identifier
* and no error.
*/
/// A [Matcher] that check that the given [Response] has an expected identifier
/// and no error.
Matcher isResponseSuccess(String id) => _IsResponseSuccess(id);
/**
* A mock [LspServerCommunicationChannel] for testing [LspAnalysisServer].
*/
/// A mock [LspServerCommunicationChannel] for testing [LspAnalysisServer].
class MockLspServerChannel implements LspServerCommunicationChannel {
final StreamController<lsp.Message> _clientToServer =
StreamController<lsp.Message>.broadcast();
@ -42,9 +36,7 @@ class MockLspServerChannel implements LspServerCommunicationChannel {
String name;
/**
* Completer that will be signalled when the input stream is closed.
*/
/// Completer that will be signalled when the input stream is closed.
final Completer _closed = Completer();
MockLspServerChannel(bool _printMessages) {
@ -56,9 +48,7 @@ class MockLspServerChannel implements LspServerCommunicationChannel {
}
}
/**
* Future that will be completed when the input stream is closed.
*/
/// Future that will be completed when the input stream is closed.
@override
Future get closed {
return _closed.future;
@ -122,11 +112,9 @@ class MockLspServerChannel implements LspServerCommunicationChannel {
_serverToClient.add(request);
}
/**
* Send the given [request] to the server and return a future that will
* complete when a response associated with the [request] has been received.
* The value of the future will be the received response.
*/
/// Send the given [request] to the server and return a future that will
/// complete when a response associated with the [request] has been received.
/// The value of the future will be the received response.
Future<lsp.ResponseMessage> sendRequestToServer(lsp.RequestMessage request) {
// No further requests should be sent after the connection is closed.
if (_closed.isCompleted) {
@ -164,15 +152,13 @@ class MockLspServerChannel implements LspServerCommunicationChannel {
_clientToServer.add(response);
}
/**
* Return a future that will complete when a response associated with the
* given [request] has been received. The value of the future will be the
* received response. The returned future will throw an exception if a server
* error is reported before the response has been received.
*
* Unlike [sendLspRequest], this method assumes that the [request] has already
* been sent to the server.
*/
/// Return a future that will complete when a response associated with the
/// given [request] has been received. The value of the future will be the
/// received response. The returned future will throw an exception if a server
/// error is reported before the response has been received.
///
/// Unlike [sendLspRequest], this method assumes that the [request] has
/// already been sent to the server.
Future<lsp.ResponseMessage> waitForResponse(
lsp.RequestMessage request, {
bool throwOnError = true,
@ -252,9 +238,7 @@ class StringTypedMock {
}
}
/**
* A [Matcher] that check that there are no `error` in a given [Response].
*/
/// A [Matcher] that check that there are no `error` in a given [Response].
class _IsResponseFailure extends Matcher {
final String _id;
final RequestErrorCode _code;
@ -300,9 +284,7 @@ class _IsResponseFailure extends Matcher {
}
}
/**
* A [Matcher] that check that there are no `error` in a given [Response].
*/
/// A [Matcher] that check that there are no `error` in a given [Response].
class _IsResponseSuccess extends Matcher {
final String _id;

View file

@ -6,9 +6,6 @@ import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'protocol_dart_test.dart' as protocol_dart_test;
/**
* Utility for manually running all tests.
*/
void main() {
defineReflectiveSuite(() {
protocol_dart_test.main();

View file

@ -243,19 +243,15 @@ class EnumTest {
}
}
/**
* Helper class for testing the correspondence between an analysis engine enum
* and an analysis server API enum.
*/
/// Helper class for testing the correspondence between an analysis engine enum
/// and an analysis server API enum.
class EnumTester<EngineEnum, ApiEnum> {
/**
* Test that the function [convert] properly converts all possible values of
* [EngineEnum] to an [ApiEnum] with the same name, with the exceptions noted
* in [exceptions]. For each key in [exceptions], if the corresponding value
* is null, then we check that converting the given key results in an error.
* If the corresponding value is an [ApiEnum], then we check that converting
* the given key results in the given value.
*/
/// Test that the function [convert] properly converts all possible values of
/// [EngineEnum] to an [ApiEnum] with the same name, with the exceptions noted
/// in [exceptions]. For each key in [exceptions], if the corresponding value
/// is null, then we check that converting the given key results in an error.
/// If the corresponding value is an [ApiEnum], then we check that converting
/// the given key results in the given value.
void run(ApiEnum Function(EngineEnum) convert,
{Map<EngineEnum, ApiEnum> exceptions = const {}}) {
ClassMirror engineClass = reflectClass(EngineEnum);

View file

@ -27,10 +27,8 @@ class ArgListContributorTest extends DartCompletionContributorTest {
}
}
/**
* Assert that there is a suggestion with the given parameter [name] that has
* the given [completion], [selectionOffset] and [selectionLength].
*/
/// Assert that there is a suggestion with the given parameter [name] that has
/// the given [completion], [selectionOffset] and [selectionLength].
void assertSuggestArgumentAndCompletion(String name,
{String completion, int selectionOffset, int selectionLength = 0}) {
CompletionSuggestion suggestion =
@ -71,10 +69,8 @@ class ArgListContributorTest extends DartCompletionContributorTest {
fail(msg.toString());
}
/**
* Assert that the specified named argument suggestions with their types are
* the only suggestions.
*/
/// Assert that the specified named argument suggestions with their types are
/// the only suggestions.
void assertSuggestArgumentsAndTypes(
{Map<String, String> namedArgumentsWithTypes,
List<int> requiredParamIndices = const <int>[],
@ -102,9 +98,7 @@ class ArgListContributorTest extends DartCompletionContributorTest {
assertNoOtherSuggestions(expected);
}
/**
* Assert that the specified suggestions are the only suggestions.
*/
/// Assert that the specified suggestions are the only suggestions.
void assertSuggestions(List<String> suggestions) {
List<CompletionSuggestion> expected = <CompletionSuggestion>[];
for (String suggestion in suggestions) {

View file

@ -104,18 +104,15 @@ abstract class _BaseDartCompletionContributorTest extends AbstractContextTest {
List<CompletionSuggestion> suggestions;
/**
* If `true` and `null` is specified as the suggestion's expected returnType
* then the actual suggestion is expected to have a `dynamic` returnType.
* Newer tests return `false` so that they can distinguish between
* `dynamic` and `null`.
* Eventually all tests should be converted and this getter removed.
*/
/// If `true` and `null` is specified as the suggestion's expected returnType
/// then the actual suggestion is expected to have a `dynamic` returnType.
/// Newer tests return `false` so that they can distinguish between
/// `dynamic` and `null`.
/// Eventually all tests should be converted and this getter removed.
bool get isNullExpectedReturnTypeConsideredDynamic => true;
/**
* Return `true` if contributors should suggest constructors in contexts where
* there is no `new` or `const` keyword.
*/
/// Return `true` if contributors should suggest constructors in contexts
/// where there is no `new` or `const` keyword.
bool get suggestConstructorsWithoutNew => true;
bool get usingFastaParser => analyzer.Parser.useFasta;

View file

@ -21,12 +21,10 @@ void main() {
@reflectiveTest
class TypeMemberContributorTest extends DartCompletionContributorTest {
/**
* Check whether a declaration of the form [shadower] in a derived class
* shadows a declaration of the form [shadowee] in a base class, for the
* purposes of what is shown during completion. [shouldBeShadowed] indicates
* whether shadowing is expected.
*/
/// Check whether a declaration of the form [shadower] in a derived class
/// shadows a declaration of the form [shadowee] in a base class, for the
/// purposes of what is shown during completion. [shouldBeShadowed] indicates
/// whether shadowing is expected.
Future check_shadowing(
String shadower, String shadowee, bool shouldBeShadowed) async {
addTestSource('''

View file

@ -35,9 +35,7 @@ int findIdentifierLength(String search) {
return length;
}
/**
* The base class for all [Refactoring] tests.
*/
/// The base class for all [Refactoring] tests.
abstract class RefactoringTest extends AbstractSingleUnitTest {
SearchEngine searchEngine;
@ -45,10 +43,8 @@ abstract class RefactoringTest extends AbstractSingleUnitTest {
Refactoring get refactoring;
/**
* Asserts that [refactoringChange] contains a [FileEdit] for the file
* with the given [path], and it results the [expectedCode].
*/
/// Asserts that [refactoringChange] contains a [FileEdit] for the file
/// with the given [path], and it results the [expectedCode].
void assertFileChangeResult(String path, String expectedCode) {
// prepare FileEdit
SourceFileEdit fileEdit = refactoringChange.getFileEdit(convertPath(path));
@ -60,18 +56,14 @@ abstract class RefactoringTest extends AbstractSingleUnitTest {
expect(actualCode, expectedCode);
}
/**
* Asserts that [refactoringChange] does not contain a [FileEdit] for the file
* with the given [path].
*/
/// Asserts that [refactoringChange] does not contain a [FileEdit] for the
/// file with the given [path].
void assertNoFileChange(String path) {
SourceFileEdit fileEdit = refactoringChange.getFileEdit(path);
expect(fileEdit, isNull);
}
/**
* Asserts that [refactoring] initial/final conditions status is OK.
*/
/// Asserts that [refactoring] initial/final conditions status is OK.
Future assertRefactoringConditionsOK() async {
RefactoringStatus status = await refactoring.checkInitialConditions();
assertRefactoringStatusOK(status);
@ -79,17 +71,13 @@ abstract class RefactoringTest extends AbstractSingleUnitTest {
assertRefactoringStatusOK(status);
}
/**
* Asserts that [refactoring] final conditions status is OK.
*/
/// Asserts that [refactoring] final conditions status is OK.
Future assertRefactoringFinalConditionsOK() async {
RefactoringStatus status = await refactoring.checkFinalConditions();
assertRefactoringStatusOK(status);
}
/**
* Asserts that [status] has expected severity and message.
*/
/// Asserts that [status] has expected severity and message.
void assertRefactoringStatus(
RefactoringStatus status, RefactoringProblemSeverity expectedSeverity,
{String expectedMessage,
@ -115,17 +103,13 @@ abstract class RefactoringTest extends AbstractSingleUnitTest {
}
}
/**
* Asserts that [refactoring] status is OK.
*/
/// Asserts that [refactoring] status is OK.
void assertRefactoringStatusOK(RefactoringStatus status) {
assertRefactoringStatus(status, null);
}
/**
* Checks that all conditions of [refactoring] are OK and the result of
* applying the [Change] to [testUnit] is [expectedCode].
*/
/// Checks that all conditions of [refactoring] are OK and the result of
/// applying the [Change] to [testUnit] is [expectedCode].
Future assertSuccessfulRefactoring(String expectedCode) async {
await assertRefactoringConditionsOK();
SourceChange change = await refactoring.createChange();
@ -133,10 +117,8 @@ abstract class RefactoringTest extends AbstractSingleUnitTest {
assertTestChangeResult(expectedCode);
}
/**
* Asserts that [refactoringChange] contains a [FileEdit] for [testFile], and
* it results the [expectedCode].
*/
/// Asserts that [refactoringChange] contains a [FileEdit] for [testFile], and
/// it results the [expectedCode].
void assertTestChangeResult(String expectedCode) {
// prepare FileEdit
SourceFileEdit fileEdit = refactoringChange.getFileEdit(testFile);

View file

@ -11,17 +11,13 @@ import 'package:test/test.dart';
import 'abstract_refactoring.dart';
/**
* The base class for all [RenameRefactoring] tests.
*/
/// The base class for all [RenameRefactoring] tests.
class RenameRefactoringTest extends RefactoringTest {
@override
RenameRefactoring refactoring;
/**
* Asserts that [refactoring] has potential edits in [testFile] at offset
* of the given [searches].
*/
/// Asserts that [refactoring] has potential edits in [testFile] at offset
/// of the given [searches].
void assertPotentialEdits(List<String> searches) {
Set<int> expectedOffsets = <int>{};
for (String search in searches) {
@ -38,10 +34,8 @@ class RenameRefactoringTest extends RefactoringTest {
expect(expectedOffsets, isEmpty);
}
/**
* Creates a new [RenameRefactoring] in [refactoring] for the [Element] of
* the [SimpleIdentifier] at the given [search] pattern.
*/
/// Creates a new [RenameRefactoring] in [refactoring] for the [Element] of
/// the [SimpleIdentifier] at the given [search] pattern.
void createRenameRefactoringAtString(String search) {
SimpleIdentifier identifier = findIdentifier(search);
Element element = identifier.staticElement;
@ -51,19 +45,15 @@ class RenameRefactoringTest extends RefactoringTest {
createRenameRefactoringForElement(element);
}
/**
* Creates a new [RenameRefactoring] in [refactoring] for [element].
* Fails if no [RenameRefactoring] can be created.
*/
/// Creates a new [RenameRefactoring] in [refactoring] for [element].
/// Fails if no [RenameRefactoring] can be created.
void createRenameRefactoringForElement(Element element) {
var workspace = RefactoringWorkspace([driver], searchEngine);
refactoring = RenameRefactoring(workspace, testAnalysisResult, element);
expect(refactoring, isNotNull, reason: "No refactoring for '$element'.");
}
/**
* Returns the [Edit] with the given [id], maybe `null`.
*/
/// Returns the [Edit] with the given [id], maybe `null`.
SourceEdit findEditById(String id) {
for (SourceFileEdit fileEdit in refactoringChange.edits) {
for (SourceEdit edit in fileEdit.edits) {

View file

@ -135,10 +135,8 @@ main() {
expectedMessage: message);
}
/**
* Checks that all conditions are OK and the result of applying [refactoring]
* change to [testUnit] is [expectedCode].
*/
/// Checks that all conditions are OK and the result of applying [refactoring]
/// change to [testUnit] is [expectedCode].
Future _assertSuccessfulRefactoring(String expectedCode) async {
await assertRefactoringConditionsOK();
SourceChange refactoringChange = await refactoring.createChange();

View file

@ -189,10 +189,8 @@ void test() {}
expectedMessage: message);
}
/**
* Checks that all conditions are OK and the result of applying the [Change]
* to [testUnit] is [expectedCode].
*/
/// Checks that all conditions are OK and the result of applying the [Change]
/// to [testUnit] is [expectedCode].
Future _assertSuccessfulRefactoring(String expectedCode) async {
await assertRefactoringConditionsOK();
SourceChange refactoringChange = await refactoring.createChange();

View file

@ -1235,11 +1235,9 @@ String foo() => '';
''');
}
/**
* Here we use knowledge how exactly `1 + 2 + 3 + 4` is parsed. We know that
* `1 + 2` will be a separate and complete binary expression, so it can be
* handled as a single expression.
*/
/// Here we use knowledge how exactly `1 + 2 + 3 + 4` is parsed. We know that
/// `1 + 2` will be a separate and complete binary expression, so it can be
/// handled as a single expression.
Future<void> test_singleExpression_partOfBinaryExpression() async {
await indexTestUnit('''
main() {
@ -1386,10 +1384,8 @@ main() {
expect(editGroups.first.toJson(), json.decode(expectedJsonString));
}
/**
* Checks that all conditions are OK and the result of applying the
* [SourceChange] to [testUnit] is [expectedCode].
*/
/// Checks that all conditions are OK and the result of applying the
/// [SourceChange] to [testUnit] is [expectedCode].
Future _assertSuccessfulRefactoring(String expectedCode) async {
await assertRefactoringConditionsOK();
SourceChange refactoringChange = await refactoring.createChange();
@ -1402,20 +1398,16 @@ main() {
refactoring.name = 'res';
}
/**
* Creates a new refactoring in [refactoring] at the offset of the given
* [search] pattern, and with the length `0`.
*/
/// Creates a new refactoring in [refactoring] at the offset of the given
/// [search] pattern, and with the length `0`.
void _createRefactoringAtString(String search) {
int offset = findOffset(search);
int length = 0;
_createRefactoring(offset, length);
}
/**
* Creates a new refactoring in [refactoring] for the selection range of the
* given [search] pattern.
*/
/// Creates a new refactoring in [refactoring] for the selection range of the
/// given [search] pattern.
void _createRefactoringForString(String search) {
int offset = findOffset(search);
int length = search.length;

View file

@ -2271,9 +2271,7 @@ res() {
''');
}
/**
* We should always add ";" when invoke method with extracted statements.
*/
/// We should always add ";" when invoke method with extracted statements.
Future<void> test_statements_endsWithBlock() async {
await indexTestUnit('''
main() {
@ -2852,10 +2850,8 @@ int res() {
''');
}
/**
* We have 3 identical statements, but select only 2.
* This should not cause problems.
*/
/// We have 3 identical statements, but select only 2.
/// This should not cause problems.
Future<void> test_statements_twoOfThree() async {
await indexTestUnit('''
main() {
@ -2915,10 +2911,8 @@ Completer<int> newCompleter() => null;
assertTestChangeResult(expectedCode);
}
/**
* Checks that all conditions are OK and the result of applying the [Change]
* to [testUnit] is [expectedCode].
*/
/// Checks that all conditions are OK and the result of applying the [Change]
/// to [testUnit] is [expectedCode].
Future _assertSuccessfulRefactoring(String expectedCode) async {
await assertRefactoringConditionsOK();
refactoring.createGetter = false;
@ -2944,20 +2938,16 @@ Completer<int> newCompleter() => null;
_createRefactoring(offset, end - offset);
}
/**
* Creates a new refactoring in [refactoring] for the selection range of the
* given [search] pattern.
*/
/// Creates a new refactoring in [refactoring] for the selection range of the
/// given [search] pattern.
void _createRefactoringForString(String search) {
int offset = findOffset(search);
int length = search.length;
_createRefactoring(offset, length);
}
/**
* Creates a new refactoring in [refactoring] at the offset of the given
* [search] pattern, and with `0` length.
*/
/// Creates a new refactoring in [refactoring] at the offset of the given
/// [search] pattern, and with `0` length.
void _createRefactoringForStringOffset(String search) {
int offset = findOffset(search);
_createRefactoring(offset, 0);
@ -2969,11 +2959,9 @@ Completer<int> newCompleter() => null;
_createRefactoring(offset, length);
}
/**
* Returns a deep copy of [refactoring] parameters.
* There was a bug masked by updating parameter instances shared between the
* refactoring and the test.
*/
/// Returns a deep copy of [refactoring] parameters.
/// There was a bug masked by updating parameter instances shared between the
/// refactoring and the test.
List<RefactoringMethodParameter> _getParametersCopy() {
return refactoring.parameters.map((p) {
return RefactoringMethodParameter(p.kind, p.type, p.name, id: p.id);

View file

@ -1225,10 +1225,8 @@ void main() {
assertTestChangeResult(expectedCode);
}
/**
* Checks that all conditions are OK and the result of applying the change
* to [testUnit] is [expectedCode].
*/
/// Checks that all conditions are OK and the result of applying the change
/// to [testUnit] is [expectedCode].
Future<void> _assertSuccessfulRefactoring(String expectedCode) async {
await assertRefactoringConditionsOK();
await _assertRefactoringChange(expectedCode);
@ -1246,10 +1244,8 @@ void main() {
_createRefactoring(offset, length);
}
/**
* Creates a new refactoring in [refactoring] at the offset of the given
* [search] pattern.
*/
/// Creates a new refactoring in [refactoring] at the offset of the given
/// [search] pattern.
void _createRefactoringForStringOffset(String search) {
int offset = findOffset(search);
_createRefactoring(offset, 0);

View file

@ -436,10 +436,7 @@ main() {
''');
}
/**
* <p>
* https://code.google.com/p/dart/issues/detail?id=18587
*/
/// https://code.google.com/p/dart/issues/detail?id=18587
Future<void> test_OK_keepNextCommentedLine() async {
await indexTestUnit('''
main() {

View file

@ -445,9 +445,7 @@ part of 'a.dart';
expectedMessage: expectedMessage);
}
/**
* Checks that all conditions are OK.
*/
/// Checks that all conditions are OK.
Future _assertSuccessfulRefactoring() async {
await assertRefactoringConditionsOK();
refactoringChange = await refactoring.createChange();

View file

@ -647,11 +647,9 @@ void main() {
offset: testCode.indexOf("test('test2_2'"));
}
/**
* Code like this caused NPE in the past.
*
* https://code.google.com/p/dart/issues/detail?id=21373
*/
/// Code like this caused NPE in the past.
///
/// https://code.google.com/p/dart/issues/detail?id=21373
Future<void> test_invalidGetterInConstructor() async {
Outline outline = await _computeOutline('''
class A {
@ -665,11 +663,9 @@ class A {
expect(outline, isNotNull);
}
/**
* Code like this caused Dart2 failure in the past.
*
* https://github.com/dart-lang/sdk/issues/33228
*/
/// Code like this caused Dart2 failure in the past.
///
/// https://github.com/dart-lang/sdk/issues/33228
Future<void> test_invocation_ofParameter() async {
Outline outline = await _computeOutline('''
main(p()) {

View file

@ -687,18 +687,14 @@ class PluginSessionTest with ResourceProviderMixin {
}
}
/**
* A class designed to be used as a superclass for test classes that define
* tests that require plugins to be created on disk.
*/
/// A class designed to be used as a superclass for test classes that define
/// tests that require plugins to be created on disk.
abstract class PluginTestSupport {
PhysicalResourceProvider resourceProvider;
TestNotificationManager notificationManager;
/**
* The content to be used for the '.packages' file, or `null` if the content
* has not yet been computed.
*/
/// The content to be used for the '.packages' file, or `null` if the content
/// has not yet been computed.
String _packagesFileContent;
void setUp() {
@ -706,22 +702,21 @@ abstract class PluginTestSupport {
notificationManager = TestNotificationManager();
}
/**
* Create a directory structure representing a plugin on disk, run the given
* [test] function, and then remove the directory. The directory will have the
* following structure:
* ```
* pluginDirectory
* .packages
* bin
* plugin.dart
* ```
* The name of the plugin directory will be the [pluginName], if one is
* provided (in order to allow more than one plugin to be created by a single
* test). The 'plugin.dart' file will contain the given [content], or default
* content that implements a minimal plugin if the contents are not given. The
* [test] function will be passed the path of the directory that was created.
*/
/// Create a directory structure representing a plugin on disk, run the given
/// [test] function, and then remove the directory. The directory will have
/// the following structure:
/// ```
/// pluginDirectory
/// .packages
/// bin
/// plugin.dart
/// ```
/// The name of the plugin directory will be the [pluginName], if one is
/// provided (in order to allow more than one plugin to be created by a single
/// test). The 'plugin.dart' file will contain the given [content], or default
/// content that implements a minimal plugin if the contents are not given.
/// The [test] function will be passed the path of the directory that was
/// created.
Future<void> withPlugin(
{String content,
String pluginName,
@ -754,22 +749,21 @@ abstract class PluginTestSupport {
}
}
/**
* Create a directory structure representing a plugin on disk, run the given
* [test] function, and then remove the directory. The directory will have the
* following structure:
* ```
* pluginDirectory
* pubspec.yaml
* bin
* plugin.dart
* ```
* The name of the plugin directory will be the [pluginName], if one is
* provided (in order to allow more than one plugin to be created by a single
* test). The 'plugin.dart' file will contain the given [content], or default
* content that implements a minimal plugin if the contents are not given. The
* [test] function will be passed the path of the directory that was created.
*/
/// Create a directory structure representing a plugin on disk, run the given
/// [test] function, and then remove the directory. The directory will have
/// the following structure:
/// ```
/// pluginDirectory
/// pubspec.yaml
/// bin
/// plugin.dart
/// ```
/// The name of the plugin directory will be the [pluginName], if one is
/// provided (in order to allow more than one plugin to be created by a single
/// test). The 'plugin.dart' file will contain the given [content], or default
/// content that implements a minimal plugin if the contents are not given.
/// The [test] function will be passed the path of the directory that was
/// created.
Future<void> withPubspecPlugin(
{String content,
String pluginName,
@ -802,10 +796,8 @@ abstract class PluginTestSupport {
}
}
/**
* Convert the [sdkPackageMap] into a plugin-specific map by applying the
* given relative path [delta] to each line.
*/
/// Convert the [sdkPackageMap] into a plugin-specific map by applying the
/// given relative path [delta] to each line.
String _convertPackageMap(String sdkDirPath, List<String> sdkPackageMap) {
StringBuffer buffer = StringBuffer();
for (String line in sdkPackageMap) {
@ -824,10 +816,8 @@ abstract class PluginTestSupport {
return buffer.toString();
}
/**
* The default content of the plugin. This is a minimal plugin that will only
* respond correctly to version checks and to shutdown requests.
*/
/// The default content of the plugin. This is a minimal plugin that will only
/// respond correctly to version checks and to shutdown requests.
String _defaultPluginContent() {
return r'''
import 'dart:async';
@ -871,9 +861,7 @@ class MinimalPlugin extends ServerPlugin {
''';
}
/**
* Return the content to be used for the '.packages' file.
*/
/// Return the content to be used for the '.packages' file.
String _getPackagesFileContent() {
if (_packagesFileContent == null) {
io.File sdkPackagesFile = io.File(_sdkPackagesPath());
@ -884,9 +872,7 @@ class MinimalPlugin extends ServerPlugin {
return _packagesFileContent;
}
/**
* Return the content to be used for the 'pubspec.yaml' file.
*/
/// Return the content to be used for the 'pubspec.yaml' file.
String _getPubspecFileContent() {
return '''
name: 'test'
@ -896,9 +882,7 @@ dependencies:
''';
}
/**
* Return the path to the '.packages' file in the root of the SDK checkout.
*/
/// Return the path to the '.packages' file in the root of the SDK checkout.
String _sdkPackagesPath() {
String packagesPath = io.Platform.script.toFilePath();
while (packagesPath.isNotEmpty &&

View file

@ -62,10 +62,8 @@ class ProtocolTestUtilities {
'bz',
];
/**
* On return, increment [stringIndex] by 3 (or 4 if no [file] name is
* provided) and [intIndex] by 4.
*/
/// On return, increment [stringIndex] by 3 (or 4 if no [file] name is
/// provided) and [intIndex] by 4.
AnalysisError analysisError(int stringIndex, int intIndex, {String file}) {
return AnalysisError(
AnalysisErrorSeverity.ERROR,
@ -77,9 +75,7 @@ class ProtocolTestUtilities {
hasFix: true);
}
/**
* On return, increment [stringIndex] by 5 and [intIndex] by 5.
*/
/// On return, increment [stringIndex] by 5 and [intIndex] by 5.
Element element(int stringIndex, int intIndex, {ElementKind kind}) =>
Element(kind ?? ElementKind.CLASS, strings[stringIndex++], intIndex++,
location: Location(fileName(stringIndex++), intIndex++, intIndex++,
@ -96,9 +92,7 @@ class ProtocolTestUtilities {
HighlightRegion highlightRegion(int offset, int length) =>
HighlightRegion(HighlightRegionType.FIELD, offset, length);
/**
* On return, increment [stringIndex] by 1 and [intIndex] by 4.
*/
/// On return, increment [stringIndex] by 1 and [intIndex] by 4.
Location location(int stringIndex, int intIndex, {String file}) => Location(
file ?? fileName(stringIndex),
intIndex++,
@ -106,18 +100,14 @@ class ProtocolTestUtilities {
intIndex++,
intIndex++);
/**
* On return, increment [stringIndex] by 5 and [intIndex] by 7.
*/
/// On return, increment [stringIndex] by 5 and [intIndex] by 7.
Occurrences occurrences(int stringIndex, int intIndex) {
Element referencedElement = element(stringIndex, intIndex);
return Occurrences(referencedElement, <int>[intIndex + 5, intIndex + 6],
referencedElement.name.length);
}
/**
* On return, increment [stringIndex] by 10 and [intIndex] by 14.
*/
/// On return, increment [stringIndex] by 10 and [intIndex] by 14.
Outline outline(int stringIndex, int intIndex) => Outline(
element(stringIndex, intIndex),
intIndex + 5,
@ -134,10 +124,8 @@ class ProtocolTestUtilities {
intIndex + 13)
]);
/**
* On return, increment [stringIndex] by 2 (or 3 if no [file] name is
* provided) and [intIndex] by 4.
*/
/// On return, increment [stringIndex] by 2 (or 3 if no [file] name is
/// provided) and [intIndex] by 4.
plugin.AnalysisNavigationParams pluginNavigationParams(
int stringIndex, int intIndex, {String file}) =>
plugin.AnalysisNavigationParams(
@ -151,19 +139,15 @@ class ProtocolTestUtilities {
strings[stringIndex++]
]);
/**
* On return, increment [stringIndex] by 2 and [intIndex] by 4.
*/
/// On return, increment [stringIndex] by 2 and [intIndex] by 4.
RefactoringProblem refactoringProblem(int stringIndex, int intIndex) {
return RefactoringProblem(
RefactoringProblemSeverity.FATAL, strings[stringIndex++],
location: location(stringIndex, intIndex));
}
/**
* On return, increment [stringIndex] by 2 (or 3 if no [file] name is
* provided) and [intIndex] by 4.
*/
/// On return, increment [stringIndex] by 2 (or 3 if no [file] name is
/// provided) and [intIndex] by 4.
server.AnalysisNavigationParams serverNavigationParams(
int stringIndex, int intIndex, {String file}) =>
server.AnalysisNavigationParams(
@ -177,9 +161,7 @@ class ProtocolTestUtilities {
strings[stringIndex++]
]);
/**
* On return, increment [stringIndex] by 6 and [intIndex] by 6.
*/
/// On return, increment [stringIndex] by 6 and [intIndex] by 6.
SourceChange sourceChange(int stringIndex, int intIndex) =>
SourceChange(strings[stringIndex++],
edits: <SourceFileEdit>[

View file

@ -8,9 +8,7 @@ import 'package:args/args.dart';
import 'completion_runner.dart';
/**
* The main entry point for the code completion stress test.
*/
/// The main entry point for the code completion stress test.
void main(List<String> args) async {
ArgParser parser = createArgParser();
ArgResults result = parser.parse(args);
@ -29,9 +27,7 @@ void main(List<String> args) async {
}
}
/**
* Create a parser that can be used to parse the command-line arguments.
*/
/// Create a parser that can be used to parse the command-line arguments.
ArgParser createArgParser() {
ArgParser parser = ArgParser();
parser.addFlag(
@ -64,9 +60,7 @@ ArgParser createArgParser() {
return parser;
}
/**
* Print usage information for this tool.
*/
/// Print usage information for this tool.
void printUsage(ArgParser parser, {String error}) {
if (error != null) {
print(error);
@ -81,10 +75,8 @@ void printUsage(ArgParser parser, {String error}) {
print(parser.usage);
}
/**
* Return `true` if the command-line arguments (represented by the [result] and
* parsed by the [parser]) are valid.
*/
/// Return `true` if the command-line arguments (represented by the [result] and
/// parsed by the [parser]) are valid.
bool validArguments(ArgParser parser, ArgResults result) {
if (result.wasParsed('help')) {
printUsage(parser);

View file

@ -19,46 +19,30 @@ import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
/**
* A runner that can request code completion at the location of each identifier
* in a Dart file.
*/
/// A runner that can request code completion at the location of each identifier
/// in a Dart file.
class CompletionRunner {
/**
* The sink to which output is to be written.
*/
/// The sink to which output is to be written.
final StringSink output;
/**
* A flag indicating whether to produce output about missing suggestions.
*/
/// A flag indicating whether to produce output about missing suggestions.
final bool printMissing;
/**
* A flag indicating whether to produce output about the quality of the sort
* order.
*/
/// A flag indicating whether to produce output about the quality of the sort
/// order.
final bool printQuality;
/**
* A flag indicating whether to produce timing information.
*/
/// A flag indicating whether to produce timing information.
final bool timing;
/**
* A flag indicating whether to produce verbose output.
*/
/// A flag indicating whether to produce verbose output.
final bool verbose;
/**
* A flag indicating whether we should delete each identifier before
* attempting to complete at that offset.
*/
/// A flag indicating whether we should delete each identifier before
/// attempting to complete at that offset.
bool deleteBeforeCompletion = false;
/**
* Initialize a newly created completion runner.
*/
/// Initialize a newly created completion runner.
CompletionRunner(
{StringSink output,
bool printMissing,
@ -71,10 +55,8 @@ class CompletionRunner {
timing = timing ?? false,
verbose = verbose ?? false;
/**
* Test the completion engine at the locations of each of the identifiers in
* each of the files in the given [analysisRoot].
*/
/// Test the completion engine at the locations of each of the identifiers in
/// each of the files in the given [analysisRoot].
Future<void> runAll(String analysisRoot) async {
OverlayResourceProvider resourceProvider =
OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
@ -228,20 +210,16 @@ class CompletionRunner {
.toList();
}
/**
* Return a list containing information about the identifiers in the given
* compilation [unit].
*/
/// Return a list containing information about the identifiers in the given
/// compilation [unit].
List<SimpleIdentifier> _identifiersIn(CompilationUnit unit) {
IdentifierCollector visitor = IdentifierCollector();
unit.accept(visitor);
return visitor.identifiers;
}
/**
* If the given list of [suggestions] includes a suggestion for the given
* [identifier], return the index of the suggestion. Otherwise, return `-1`.
*/
/// If the given list of [suggestions] includes a suggestion for the given
/// [identifier], return the index of the suggestion. Otherwise, return `-1`.
int _indexOf(List<CompletionSuggestion> suggestions, String identifier) {
for (int i = 0; i < suggestions.length; i++) {
if (suggestions[i].completion == identifier) {
@ -251,18 +229,14 @@ class CompletionRunner {
return -1;
}
/**
* Return `true` if the given [identifier] is being used as the name of a
* named expression.
*/
/// Return `true` if the given [identifier] is being used as the name of a
/// named expression.
bool _isNamedExpressionName(SimpleIdentifier identifier) {
AstNode parent = identifier.parent;
return parent is NamedExpression && parent.name.label == identifier;
}
/**
* Print information about the given [suggestions].
*/
/// Print information about the given [suggestions].
void _printSuggestions(List<CompletionSuggestion> suggestions) {
if (suggestions.isEmpty) {
output.writeln(' No suggestions');
@ -280,13 +254,9 @@ class CompletionRunner {
}
}
/**
* A visitor that will collect simple identifiers in the AST being visited.
*/
/// A visitor that will collect simple identifiers in the AST being visited.
class IdentifierCollector extends RecursiveAstVisitor<void> {
/**
* The simple identifiers that were collected.
*/
/// The simple identifiers that were collected.
final List<SimpleIdentifier> identifiers = <SimpleIdentifier>[];
@override

View file

@ -2,29 +2,19 @@
// 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.
/**
* Operations to be performed during the simulation.
*/
/// Operations to be performed during the simulation.
import '../utilities/server.dart';
/**
* An operation that will send an 'analysis.updateContent' request.
*/
/// An operation that will send an 'analysis.updateContent' request.
class Analysis_UpdateContent extends ServerOperation {
/**
* The path of the file whose content is being updated.
*/
/// The path of the file whose content is being updated.
final String filePath;
/**
* The overlay used to update the content.
*/
/// The overlay used to update the content.
final dynamic overlay;
/**
* Initialize an operation to send an 'analysis.updateContent' request with
* the given [filePath] and [overlay] as parameters.
*/
/// Initialize an operation to send an 'analysis.updateContent' request with
/// the given [filePath] and [overlay] as parameters.
Analysis_UpdateContent(this.filePath, this.overlay);
@override
@ -43,24 +33,16 @@ class Analysis_UpdateContent extends ServerOperation {
}
}
/**
* An operation that will send a 'completion.getSuggestions' request.
*/
/// An operation that will send a 'completion.getSuggestions' request.
class Completion_GetSuggestions extends ServerOperation {
/**
* The path of the file in which completions are being requested.
*/
/// The path of the file in which completions are being requested.
final String filePath;
/**
* The offset at which completions are being requested.
*/
/// The offset at which completions are being requested.
final int offset;
/**
* Initialize an operation to send a 'completion.getSuggestions' request with
* the given [filePath] and [offset] as parameters.
*/
/// Initialize an operation to send a 'completion.getSuggestions' request with
/// the given [filePath] and [offset] as parameters.
Completion_GetSuggestions(this.filePath, this.offset);
@override
@ -69,12 +51,8 @@ class Completion_GetSuggestions extends ServerOperation {
}
}
/**
* An operation to be performed during the simulation.
*/
/// An operation to be performed during the simulation.
abstract class ServerOperation {
/**
* Perform this operation by communicating with the given [server].
*/
/// Perform this operation by communicating with the given [server].
void perform(Server server);
}

View file

@ -2,9 +2,7 @@
// 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.
/**
* A stress test for the analysis server.
*/
/// A stress test for the analysis server.
import 'dart:async';
import 'dart:io';
import 'dart:math' as math;
@ -27,122 +25,80 @@ import '../utilities/logger.dart';
import '../utilities/server.dart';
import 'operation.dart';
/**
* Run the simulation based on the given command-line [arguments].
*/
/// Run the simulation based on the given command-line [arguments].
Future<void> main(List<String> arguments) async {
Driver driver = Driver();
await driver.run(arguments);
}
/**
* The driver class that runs the simulation.
*/
/// The driver class that runs the simulation.
class Driver {
/**
* The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
* to a file should be represented by an add overlay, followed by zero or more
* change overlays, followed by a remove overlay.
*/
/// The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
/// to a file should be represented by an add overlay, followed by zero or
/// more change overlays, followed by a remove overlay.
static String CHANGE_OVERLAY_STYLE = 'change';
/**
* The name of the command-line flag that will print help text.
*/
/// The name of the command-line flag that will print help text.
static String HELP_FLAG_NAME = 'help';
/**
* The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
* to a file should be represented by an add overlay, followed by zero or more
* additional add overlays, followed by a remove overlay.
*/
/// The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
/// to a file should be represented by an add overlay, followed by zero or
/// more additional add overlays, followed by a remove overlay.
static String MULTIPLE_ADD_OVERLAY_STYLE = 'multipleAdd';
/**
* The name of the command-line option used to specify the style of
* interaction to use when making `analysis.updateContent` requests.
*/
/// The name of the command-line option used to specify the style of
/// interaction to use when making `analysis.updateContent` requests.
static String OVERLAY_STYLE_OPTION_NAME = 'overlay-style';
/**
* The name of the pubspec file.
*/
/// The name of the pubspec file.
static const String PUBSPEC_FILE_NAME = 'pubspec.yaml';
/**
* The name of the branch used to clean-up after making temporary changes.
*/
/// The name of the branch used to clean-up after making temporary changes.
static const String TEMP_BRANCH_NAME = 'temp';
/**
* The name of the command-line flag that will cause verbose output to be
* produced.
*/
/// The name of the command-line flag that will cause verbose output to be
/// produced.
static String VERBOSE_FLAG_NAME = 'verbose';
/**
* The style of interaction to use for analysis.updateContent requests.
*/
/// The style of interaction to use for analysis.updateContent requests.
OverlayStyle overlayStyle;
/**
* The absolute path of the repository.
*/
/// The absolute path of the repository.
String repositoryPath;
/**
* The absolute paths to the analysis roots.
*/
/// The absolute paths to the analysis roots.
List<String> analysisRoots;
/**
* The git repository.
*/
/// The git repository.
GitRepository repository;
/**
* The connection to the analysis server.
*/
/// The connection to the analysis server.
Server server;
/**
* A list of the glob patterns used to identify the files being analyzed by
* the server.
*/
/// A list of the glob patterns used to identify the files being analyzed by
/// the server.
List<Glob> fileGlobs;
/**
* An object gathering statistics about the simulation.
*/
/// An object gathering statistics about the simulation.
Statistics statistics;
/**
* A flag indicating whether verbose output should be provided.
*/
/// A flag indicating whether verbose output should be provided.
bool verbose = false;
/**
* The logger to which verbose logging data will be written.
*/
/// The logger to which verbose logging data will be written.
Logger logger;
/**
* Initialize a newly created driver.
*/
/// Initialize a newly created driver.
Driver() {
statistics = Statistics(this);
}
/**
* Allow the output from the server to be read and processed.
*/
/// Allow the output from the server to be read and processed.
Future<void> readServerOutput() async {
await Future.delayed(Duration(milliseconds: 2));
}
/**
* Run the simulation based on the given command-line arguments ([args]).
*/
/// Run the simulation based on the given command-line arguments ([args]).
Future<void> run(List<String> args) async {
//
// Process the command-line arguments.
@ -176,10 +132,8 @@ class Driver {
return null;
}
/**
* Create and return a parser that can be used to parse the command-line
* arguments.
*/
/// Create and return a parser that can be used to parse the command-line
/// arguments.
ArgParser _createArgParser() {
ArgParser parser = ArgParser();
parser.addFlag(HELP_FLAG_NAME,
@ -204,9 +158,7 @@ class Driver {
return parser;
}
/**
* Add source edits to the given [fileEdit] based on the given [blobDiff].
*/
/// Add source edits to the given [fileEdit] based on the given [blobDiff].
void _createSourceEdits(FileEdit fileEdit, BlobDiff blobDiff) {
LineInfo info = fileEdit.lineInfo;
for (DiffHunk hunk in blobDiff.hunks) {
@ -245,10 +197,8 @@ class Driver {
}
}
/**
* Return the absolute paths of all of the pubspec files in all of the
* analysis roots.
*/
/// Return the absolute paths of all of the pubspec files in all of the
/// analysis roots.
Iterable<String> _findPubspecsInAnalysisRoots() {
List<String> pubspecFiles = <String>[];
for (String directoryPath in analysisRoots) {
@ -265,10 +215,8 @@ class Driver {
return pubspecFiles;
}
/**
* Return a list of offsets into the given [text] that represent good places
* to break the text when building edits.
*/
/// Return a list of offsets into the given [text] that represent good places
/// to break the text when building edits.
List<int> _getBreakOffsets(String text) {
List<int> breakOffsets = <int>[];
Scanner scanner = Scanner(null, CharSequenceReader(text),
@ -290,9 +238,7 @@ class Driver {
return breakOffsets;
}
/**
* Join the given [lines] into a single string.
*/
/// Join the given [lines] into a single string.
String _join(List<String> lines) {
StringBuffer buffer = StringBuffer();
for (int i = 0; i < lines.length; i++) {
@ -301,10 +247,8 @@ class Driver {
return buffer.toString();
}
/**
* Process the command-line [arguments]. Return `true` if the simulation
* should be run.
*/
/// Process the command-line [arguments]. Return `true` if the simulation
/// should be run.
bool _processCommandLine(List<String> args) {
ArgParser parser = _createArgParser();
ArgResults results;
@ -355,9 +299,7 @@ class Driver {
return true;
}
/**
* Replay the changes in each commit.
*/
/// Replay the changes in each commit.
Future<void> _replayChanges() async {
//
// Get the revision history of the repo.
@ -424,10 +366,8 @@ class Driver {
stdout.writeln();
}
/**
* Replay the changes between two commits, as represented by the given
* [commitDelta].
*/
/// Replay the changes between two commits, as represented by the given
/// [commitDelta].
Future<void> _replayDiff(CommitDelta commitDelta) async {
List<FileEdit> editList = <FileEdit>[];
for (DiffRecord record in commitDelta.diffRecords) {
@ -460,9 +400,7 @@ class Driver {
}
}
/**
* Run `pub` on the pubspec with the given [filePath].
*/
/// Run `pub` on the pubspec with the given [filePath].
void _runPub(String filePath) {
String directoryPath = path.dirname(filePath);
if (Directory(directoryPath).existsSync()) {
@ -472,9 +410,7 @@ class Driver {
}
}
/**
* Run the simulation by starting up a server and sending it requests.
*/
/// Run the simulation by starting up a server and sending it requests.
Future<void> _runSimulation() async {
server = Server(logger: logger);
Stopwatch stopwatch = Stopwatch();
@ -503,9 +439,7 @@ class Driver {
stopwatch.stop();
}
/**
* Display usage information, preceded by the [errorMessage] if one is given.
*/
/// Display usage information, preceded by the [errorMessage] if one is given.
void _showUsage(ArgParser parser, [String errorMessage]) {
if (errorMessage != null) {
stderr.writeln(errorMessage);
@ -531,45 +465,29 @@ OPTIONS:''');
}
}
/**
* A representation of the edits to be applied to a single file.
*/
/// A representation of the edits to be applied to a single file.
class FileEdit {
/**
* The style of interaction to use for analysis.updateContent requests.
*/
/// The style of interaction to use for analysis.updateContent requests.
OverlayStyle overlayStyle;
/**
* The absolute path of the file to be edited.
*/
/// The absolute path of the file to be edited.
String filePath;
/**
* The content of the file before any edits have been applied.
*/
/// The content of the file before any edits have been applied.
String content;
/**
* The line info for the file before any edits have been applied.
*/
/// The line info for the file before any edits have been applied.
LineInfo lineInfo;
/**
* The lists of source edits, one list for each hunk being edited.
*/
/// The lists of source edits, one list for each hunk being edited.
List<List<SourceEdit>> editLists = <List<SourceEdit>>[];
/**
* The current content of the file. This field is only used if the overlay
* style is [OverlayStyle.multipleAdd].
*/
/// The current content of the file. This field is only used if the overlay
/// style is [OverlayStyle.multipleAdd].
String currentContent;
/**
* Initialize a collection of edits to be associated with the file at the
* given [filePath].
*/
/// Initialize a collection of edits to be associated with the file at the
/// given [filePath].
FileEdit(this.overlayStyle, DiffRecord record) {
filePath = record.srcPath;
if (record.isAddition) {
@ -584,17 +502,13 @@ class FileEdit {
currentContent = content;
}
/**
* Add a list of source edits that, taken together, transform a single hunk in
* the file.
*/
/// Add a list of source edits that, taken together, transform a single hunk
/// in the file.
void addSourceEdits(List<SourceEdit> sourceEdits) {
editLists.add(sourceEdits);
}
/**
* Return a list of operations to be sent to the server.
*/
/// Return a list of operations to be sent to the server.
List<ServerOperation> getOperations() {
List<ServerOperation> operations = <ServerOperation>[];
void addUpdateContent(var overlay) {
@ -626,49 +540,32 @@ class FileEdit {
}
}
/**
* The possible styles of interaction to use for analysis.updateContent requests.
*/
/// The possible styles of interaction to use for analysis.updateContent
/// requests.
enum OverlayStyle { change, multipleAdd }
/**
* A set of statistics related to the execution of the simulation.
*/
/// A set of statistics related to the execution of the simulation.
class Statistics {
/**
* The driver driving the simulation.
*/
/// The driver driving the simulation.
final Driver driver;
/**
* The stopwatch being used to time the simulation.
*/
/// The stopwatch being used to time the simulation.
Stopwatch stopwatch;
/**
* The total number of commits in the repository.
*/
/// The total number of commits in the repository.
int commitCount;
/**
* The number of commits in the repository that touched one of the files in
* one of the analysis roots.
*/
/// The number of commits in the repository that touched one of the files in
/// one of the analysis roots.
int commitsWithChangeInRootCount = 0;
/**
* The total number of edits that were applied.
*/
/// The total number of edits that were applied.
int editCount = 0;
/**
* Initialize a newly created set of statistics.
*/
/// Initialize a newly created set of statistics.
Statistics(this.driver);
/**
* Print the statistics to [stdout].
*/
/// Print the statistics to [stdout].
void print() {
stdout.write('Replay commits in ');
stdout.writeln(driver.repositoryPath);
@ -684,10 +581,8 @@ class Statistics {
stdout.writeln(editCount);
}
/**
* Return a textual representation of the given duration, represented in
* [milliseconds].
*/
/// Return a textual representation of the given duration, represented in
/// [milliseconds].
String _printTime(int milliseconds) {
int seconds = milliseconds ~/ 1000;
milliseconds -= seconds * 1000;

View file

@ -2,9 +2,7 @@
// 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.
/**
* Support for interacting with a git repository.
*/
/// Support for interacting with a git repository.
import 'dart:convert';
import 'dart:io';
@ -13,43 +11,31 @@ import 'package:path/path.dart' as path;
import 'logger.dart';
/**
* A representation of the differences between two blobs.
*/
/// A representation of the differences between two blobs.
class BlobDiff {
/**
* The regular expression used to identify the beginning of a hunk.
*/
/// The regular expression used to identify the beginning of a hunk.
static final RegExp hunkHeaderRegExp =
RegExp(r'@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)(?:,[0-9]+)? @@');
/**
* A list of the hunks in the diff.
*/
/// A list of the hunks in the diff.
List<DiffHunk> hunks = <DiffHunk>[];
/**
* Initialize a newly created blob diff by parsing the result of the git diff
* command (the [input]).
*
* This is only intended to be invoked from [GitRepository.getBlobDiff].
*/
/// Initialize a newly created blob diff by parsing the result of the git diff
/// command (the [input]).
///
/// This is only intended to be invoked from [GitRepository.getBlobDiff].
BlobDiff._(List<String> input) {
_parseInput(input);
}
/**
* Parse the result of the git diff command (the [input]).
*/
/// Parse the result of the git diff command (the [input]).
void _parseInput(List<String> input) {
for (String line in input) {
_parseLine(line);
}
}
/**
* Parse a single [line] from the result of the git diff command.
*/
/// Parse a single [line] from the result of the git diff command.
void _parseLine(String line) {
DiffHunk currentHunk = hunks.isEmpty ? null : hunks.last;
if (line.startsWith('@@')) {
@ -65,71 +51,49 @@ class BlobDiff {
}
}
/**
* A representation of the differences between two commits.
*/
/// A representation of the differences between two commits.
class CommitDelta {
/**
* The length (in characters) of a SHA.
*/
/// The length (in characters) of a SHA.
static final int SHA_LENGTH = 40;
/**
* The code-point for a colon (':').
*/
/// The code-point for a colon (':').
static final int COLON = ':'.codeUnitAt(0);
/**
* The code-point for a nul character.
*/
/// The code-point for a nul character.
static final int NUL = 0;
/**
* The code-point for a tab.
*/
/// The code-point for a tab.
static final int TAB = '\t'.codeUnitAt(0);
/**
* The repository from which the commits were taken.
*/
/// The repository from which the commits were taken.
final GitRepository repository;
/**
* The records of the files that were changed.
*/
/// The records of the files that were changed.
final List<DiffRecord> diffRecords = <DiffRecord>[];
/**
* Initialize a newly created representation of the differences between two
* commits. The differences are computed by parsing the result of a git diff
* command (the [diffResults]).
*
* This is only intended to be invoked from [GitRepository.getBlobDiff].
*/
/// Initialize a newly created representation of the differences between two
/// commits. The differences are computed by parsing the result of a git diff
/// command (the [diffResults]).
///
/// This is only intended to be invoked from [GitRepository.getBlobDiff].
CommitDelta._(this.repository, String diffResults) {
_parseInput(diffResults);
}
/**
* Return `true` if there are differences.
*/
/// Return `true` if there are differences.
bool get hasDiffs => diffRecords.isNotEmpty;
/**
* Return the absolute paths of all of the files in this commit whose name
* matches the given [fileName].
*/
/// Return the absolute paths of all of the files in this commit whose name
/// matches the given [fileName].
Iterable<String> filesMatching(String fileName) {
return diffRecords
.where((DiffRecord record) => record.isFor(fileName))
.map((DiffRecord record) => record.srcPath);
}
/**
* Remove any diffs for files that are either (a) outside the given
* [inclusionPaths], or (b) are files that do not match one of the given
* [globPatterns].
*/
/// Remove any diffs for files that are either (a) outside the given
/// [inclusionPaths], or (b) are files that do not match one of the given
/// [globPatterns].
void filterDiffs(List<String> inclusionPaths, List<Glob> globPatterns) {
diffRecords.retainWhere((DiffRecord record) {
String filePath = record.srcPath ?? record.dstPath;
@ -146,10 +110,8 @@ class CommitDelta {
});
}
/**
* Return the index of the first nul character in the given [string] that is
* at or after the given [start] index.
*/
/// Return the index of the first nul character in the given [string] that is
/// at or after the given [start] index.
int _findEnd(String string, int start) {
int length = string.length;
int end = start;
@ -159,17 +121,13 @@ class CommitDelta {
return end;
}
/**
* Return the result of converting the given [relativePath] to an absolute
* path. The path is assumed to be relative to the root of the repository.
*/
/// Return the result of converting the given [relativePath] to an absolute
/// path. The path is assumed to be relative to the root of the repository.
String _makeAbsolute(String relativePath) {
return path.join(repository.path, relativePath);
}
/**
* Parse all of the diff records in the given [input].
*/
/// Parse all of the diff records in the given [input].
void _parseInput(String input) {
int length = input.length;
int start = 0;
@ -178,29 +136,27 @@ class CommitDelta {
}
}
/**
* Parse a single record from the given [input], assuming that the record
* starts at the given [startIndex].
*
* Each record is formatted as a sequence of fields. The fields are, from the
* left to the right:
*
* 1. a colon.
* 2. mode for "src"; 000000 if creation or unmerged.
* 3. a space.
* 4. mode for "dst"; 000000 if deletion or unmerged.
* 5. a space.
* 6. sha1 for "src"; 0{40} if creation or unmerged.
* 7. a space.
* 8. sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree".
* 9. a space.
* 10. status, followed by optional "score" number.
* 11. a tab or a NUL when -z option is used.
* 12. path for "src"
* 13. a tab or a NUL when -z option is used; only exists for C or R.
* 14. path for "dst"; only exists for C or R.
* 15. an LF or a NUL when -z option is used, to terminate the record.
*/
/// Parse a single record from the given [input], assuming that the record
/// starts at the given [startIndex].
///
/// Each record is formatted as a sequence of fields. The fields are, from the
/// left to the right:
///
/// 1. a colon.
/// 2. mode for "src"; 000000 if creation or unmerged.
/// 3. a space.
/// 4. mode for "dst"; 000000 if deletion or unmerged.
/// 5. a space.
/// 6. sha1 for "src"; 0{40} if creation or unmerged.
/// 7. a space.
/// 8. sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree".
/// 9. a space.
/// 10. status, followed by optional "score" number.
/// 11. a tab or a NUL when -z option is used.
/// 12. path for "src"
/// 13. a tab or a NUL when -z option is used; only exists for C or R.
/// 14. path for "dst"; only exists for C or R.
/// 15. an LF or a NUL when -z option is used, to terminate the record.
int _parseRecord(String input, int startIndex) {
// Skip the first five fields.
startIndex += 15;
@ -231,152 +187,105 @@ class CommitDelta {
}
}
/**
* Representation of a single diff hunk.
*/
/// Representation of a single diff hunk.
class DiffHunk {
/**
* The index of the first line that was changed in the src as returned by the
* diff command. The diff command numbers lines starting at 1, but it
* subtracts 1 from the line number if there are no lines on the source side
* of the hunk.
*/
/// The index of the first line that was changed in the src as returned by the
/// diff command. The diff command numbers lines starting at 1, but it
/// subtracts 1 from the line number if there are no lines on the source side
/// of the hunk.
int diffSrcLine;
/**
* The index of the first line that was changed in the dst as returned by the
* diff command. The diff command numbers lines starting at 1, but it
* subtracts 1 from the line number if there are no lines on the destination
* side of the hunk.
*/
/// The index of the first line that was changed in the dst as returned by the
/// diff command. The diff command numbers lines starting at 1, but it
/// subtracts 1 from the line number if there are no lines on the destination
/// side of the hunk.
int diffDstLine;
/**
* A list of the individual lines that were removed from the src.
*/
/// A list of the individual lines that were removed from the src.
List<String> removeLines = <String>[];
/**
* A list of the individual lines that were added to the dst.
*/
/// A list of the individual lines that were added to the dst.
List<String> addLines = <String>[];
/**
* Initialize a newly created hunk. The lines will be added after the object
* has been created.
*/
/// Initialize a newly created hunk. The lines will be added after the object
/// has been created.
DiffHunk(this.diffSrcLine, this.diffDstLine);
/**
* Return the index of the first line that was changed in the dst. Unlike the
* [diffDstLine] field, this getter adjusts the line number to be consistent
* whether or not there were any changed lines.
*/
/// Return the index of the first line that was changed in the dst. Unlike the
/// [diffDstLine] field, this getter adjusts the line number to be consistent
/// whether or not there were any changed lines.
int get dstLine {
return addLines.isEmpty ? diffDstLine : diffDstLine - 1;
}
/**
* Return the index of the first line that was changed in the src. Unlike the
* [diffDstLine] field, this getter adjusts the line number to be consistent
* whether or not there were any changed lines.
*/
/// Return the index of the first line that was changed in the src. Unlike the
/// [diffDstLine] field, this getter adjusts the line number to be consistent
/// whether or not there were any changed lines.
int get srcLine {
return removeLines.isEmpty ? diffSrcLine : diffSrcLine - 1;
}
}
/**
* A representation of a single line (record) from a raw diff.
*/
/// A representation of a single line (record) from a raw diff.
class DiffRecord {
/**
* The repository containing the file(s) that were modified.
*/
/// The repository containing the file(s) that were modified.
final GitRepository repository;
/**
* The SHA1 of the blob in the src.
*/
/// The SHA1 of the blob in the src.
final String srcBlob;
/**
* The SHA1 of the blob in the dst.
*/
/// The SHA1 of the blob in the dst.
final String dstBlob;
/**
* The status of the change. Valid values are:
* * A: addition of a file
* * C: copy of a file into a new one
* * D: deletion of a file
* * M: modification of the contents or mode of a file
* * R: renaming of a file
* * T: change in the type of the file
* * U: file is unmerged (you must complete the merge before it can be committed)
* * X: "unknown" change type (most probably a bug, please report it)
*
* Status letters C and R are always followed by a score (denoting the
* percentage of similarity between the source and target of the move or
* copy), and are the only ones to be so.
*/
/// The status of the change. Valid values are:
/// * A: addition of a file
/// * C: copy of a file into a new one
/// * D: deletion of a file
/// * M: modification of the contents or mode of a file
/// * R: renaming of a file
/// * T: change in the type of the file
/// * U: file is unmerged (you must complete the merge before it can be
/// committed)
/// * X: "unknown" change type (most probably a bug, please report it)
///
/// Status letters C and R are always followed by a score (denoting the
/// percentage of similarity between the source and target of the move or
/// copy), and are the only ones to be so.
final String status;
/**
* The path of the src.
*/
/// The path of the src.
final String srcPath;
/**
* The path of the dst if this was either a copy or a rename operation.
*/
/// The path of the dst if this was either a copy or a rename operation.
final String dstPath;
/**
* Initialize a newly created diff record.
*/
/// Initialize a newly created diff record.
DiffRecord(this.repository, this.srcBlob, this.dstBlob, this.status,
this.srcPath, this.dstPath);
/**
* Return `true` if this record represents a file that was added.
*/
/// Return `true` if this record represents a file that was added.
bool get isAddition => status == 'A';
/**
* Return `true` if this record represents a file that was copied.
*/
/// Return `true` if this record represents a file that was copied.
bool get isCopy => status.startsWith('C');
/**
* Return `true` if this record represents a file that was deleted.
*/
/// Return `true` if this record represents a file that was deleted.
bool get isDeletion => status == 'D';
/**
* Return `true` if this record represents a file that was modified.
*/
/// Return `true` if this record represents a file that was modified.
bool get isModification => status == 'M';
/**
* Return `true` if this record represents a file that was renamed.
*/
/// Return `true` if this record represents a file that was renamed.
bool get isRename => status.startsWith('R');
/**
* Return `true` if this record represents an entity whose type was changed
* (for example, from a file to a directory).
*/
/// Return `true` if this record represents an entity whose type was changed
/// (for example, from a file to a directory).
bool get isTypeChange => status == 'T';
/**
* Return a representation of the individual blobs within this diff.
*/
/// Return a representation of the individual blobs within this diff.
BlobDiff getBlobDiff() => repository.getBlobDiff(srcBlob, dstBlob);
/**
* Return `true` if this diff applies to a file with the given name.
*/
/// Return `true` if this diff applies to a file with the given name.
bool isFor(String fileName) =>
(srcPath != null && fileName == path.basename(srcPath)) ||
(dstPath != null && fileName == path.basename(dstPath));
@ -385,42 +294,30 @@ class DiffRecord {
String toString() => srcPath ?? dstPath;
}
/**
* A representation of a git repository.
*/
/// A representation of a git repository.
class GitRepository {
/**
* The absolute path of the directory containing the repository.
*/
/// The absolute path of the directory containing the repository.
final String path;
/**
* The logger to which git commands should be written, or `null` if the
* commands should not be written.
*/
/// The logger to which git commands should be written, or `null` if the
/// commands should not be written.
final Logger logger;
/**
* Initialize a newly created repository to represent the git repository at
* the given [path].
*
* If a [commandSink] is provided, any calls to git will be written to it.
*/
/// Initialize a newly created repository to represent the git repository at
/// the given [path].
///
/// If a [commandSink] is provided, any calls to git will be written to it.
GitRepository(this.path, {this.logger});
/**
* Checkout the given [commit] from the repository. This is done by running
* the command `git checkout <sha>`.
*/
/// Checkout the given [commit] from the repository. This is done by running
/// the command `git checkout <sha>`.
void checkout(String commit) {
_run(['checkout', commit]);
}
/**
* Return details about the differences between the two blobs identified by
* the SHA1 of the [srcBlob] and the SHA1 of the [dstBlob]. This is done by
* running the command `git diff <blob> <blob>`.
*/
/// Return details about the differences between the two blobs identified by
/// the SHA1 of the [srcBlob] and the SHA1 of the [dstBlob]. This is done by
/// running the command `git diff <blob> <blob>`.
BlobDiff getBlobDiff(String srcBlob, String dstBlob) {
ProcessResult result = _run(['diff', '-U0', srcBlob, dstBlob]);
List<String> diffResults =
@ -428,11 +325,9 @@ class GitRepository {
return BlobDiff._(diffResults);
}
/**
* Return details about the differences between the two commits identified by
* the [srcCommit] and [dstCommit]. This is done by running the command
* `git diff --raw --no-abbrev --no-renames -z <sha> <sha>`.
*/
/// Return details about the differences between the two commits identified by
/// the [srcCommit] and [dstCommit]. This is done by running the command
/// `git diff --raw --no-abbrev --no-renames -z <sha> <sha>`.
CommitDelta getCommitDiff(String srcCommit, String dstCommit) {
// Consider --find-renames instead of --no-renames if rename information is
// desired.
@ -448,10 +343,8 @@ class GitRepository {
return CommitDelta._(this, result.stdout as String);
}
/**
* Return a representation of the history of this repository. This is done by
* running the command `git rev-list --first-parent HEAD`.
*/
/// Return a representation of the history of this repository. This is done by
/// running the command `git rev-list --first-parent HEAD`.
LinearCommitHistory getCommitHistory() {
ProcessResult result = _run(['rev-list', '--first-parent', 'HEAD']);
List<String> commitIds =
@ -459,10 +352,8 @@ class GitRepository {
return LinearCommitHistory(this, commitIds);
}
/**
* Synchronously run the given [executable] with the given [arguments]. Return
* the result of running the process.
*/
/// Synchronously run the given [executable] with the given [arguments].
/// Return the result of running the process.
ProcessResult _run(List<String> arguments) {
logger?.log('git', 'git', arguments: arguments);
return Process.runSync('git', arguments,
@ -470,73 +361,49 @@ class GitRepository {
}
}
/**
* A representation of the history of a Git repository. This only represents a
* single linear path in the history graph.
*/
/// A representation of the history of a Git repository. This only represents a
/// single linear path in the history graph.
class LinearCommitHistory {
/**
* The repository whose history is being represented.
*/
/// The repository whose history is being represented.
final GitRepository repository;
/**
* The id's (SHA's) of the commits in the repository, with the most recent
* commit being first and the oldest commit being last.
*/
/// The id's (SHA's) of the commits in the repository, with the most recent
/// commit being first and the oldest commit being last.
final List<String> commitIds;
/**
* Initialize a commit history for the given [repository] to have the given
* [commitIds].
*/
/// Initialize a commit history for the given [repository] to have the given
/// [commitIds].
LinearCommitHistory(this.repository, this.commitIds);
/**
* Return an iterator that can be used to iterate over this commit history.
*/
/// Return an iterator that can be used to iterate over this commit history.
LinearCommitHistoryIterator iterator() {
return LinearCommitHistoryIterator(this);
}
}
/**
* An iterator over the history of a Git repository.
*/
/// An iterator over the history of a Git repository.
class LinearCommitHistoryIterator {
/**
* The commit history being iterated over.
*/
/// The commit history being iterated over.
final LinearCommitHistory history;
/**
* The index of the current commit in the list of [commitIds].
*/
/// The index of the current commit in the list of [commitIds].
int currentCommit;
/**
* Initialize a newly created iterator to iterate over the commits with the
* given [commitIds];
*/
/// Initialize a newly created iterator to iterate over the commits with the
/// given [commitIds];
LinearCommitHistoryIterator(this.history) {
currentCommit = history.commitIds.length;
}
/**
* Return the SHA1 of the commit after the current commit (the 'dst' of the
* [next] diff).
*/
/// Return the SHA1 of the commit after the current commit (the 'dst' of the
/// [next] diff).
String get dstCommit => history.commitIds[currentCommit - 1];
/**
* Return the SHA1 of the current commit (the 'src' of the [next] diff).
*/
/// Return the SHA1 of the current commit (the 'src' of the [next] diff).
String get srcCommit => history.commitIds[currentCommit];
/**
* Advance to the next commit in the history. Return `true` if it is safe to
* ask for the [next] diff.
*/
/// Advance to the next commit in the history. Return `true` if it is safe to
/// ask for the [next] diff.
bool moveNext() {
if (currentCommit <= 1) {
return false;
@ -545,9 +412,7 @@ class LinearCommitHistoryIterator {
return true;
}
/**
* Return the difference between the current commit and the commit that
* followed it.
*/
/// Return the difference between the current commit and the commit that
/// followed it.
CommitDelta next() => history.repository.getCommitDiff(srcCommit, dstCommit);
}

View file

@ -2,37 +2,25 @@
// 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.
/**
* A utility class used to write logging information during a test.
*/
/// A utility class used to write logging information during a test.
class Logger {
/**
* The width of the field in which labels are printed.
*/
/// The width of the field in which labels are printed.
static const int _labelWidth = 8;
/**
* The separator used to separate the label from the content.
*/
/// The separator used to separate the label from the content.
static const String _separator = ' : ';
/**
* The sink to which the logged information should be written.
*/
/// The sink to which the logged information should be written.
final StringSink sink;
/**
* Initialize a newly created logger to write to the given [sink].
*/
/// Initialize a newly created logger to write to the given [sink].
Logger(this.sink);
/**
* Log the given information.
*
* The [label] is used to indicate the kind of information being logged, while
* the [content] contains the actual information. If a list of [arguments] is
* provided, then they will be written after the content.
*/
/// Log the given information.
///
/// The [label] is used to indicate the kind of information being logged,
/// while the [content] contains the actual information. If a list of
/// [arguments] is provided, then they will be written after the content.
void log(String label, String content, {List<String> arguments}) {
for (int i = _labelWidth - label.length; i > 0; i--) {
sink.write(' ');

View file

@ -2,10 +2,8 @@
// 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.
/**
* Support for interacting with an analysis server that is running in a separate
* process.
*/
/// Support for interacting with an analysis server that is running in a
/// separate process.
import 'dart:async';
import 'dart:collection';
import 'dart:convert' hide JsonDecoder;
@ -19,30 +17,20 @@ import 'package:path/path.dart' as path;
import 'logger.dart';
/**
* Return the current time expressed as milliseconds since the epoch.
*/
/// Return the current time expressed as milliseconds since the epoch.
int get currentTime => DateTime.now().millisecondsSinceEpoch;
/**
* ???
*/
/// ???
class ErrorMap {
/**
* A table mapping file paths to the errors associated with that file.
*/
/// A table mapping file paths to the errors associated with that file.
final Map<String, List<AnalysisError>> pathMap =
HashMap<String, List<AnalysisError>>();
/**
* Initialize a newly created error map.
*/
/// Initialize a newly created error map.
ErrorMap();
/**
* Initialize a newly created error map to contain the same mapping as the
* given [errorMap].
*/
/// Initialize a newly created error map to contain the same mapping as the
/// given [errorMap].
ErrorMap.from(ErrorMap errorMap) {
pathMap.addAll(errorMap.pathMap);
}
@ -52,60 +40,38 @@ class ErrorMap {
}
}
/**
* Data that has been collected about a request sent to the server.
*/
/// Data that has been collected about a request sent to the server.
class RequestData {
/**
* The unique id of the request.
*/
/// The unique id of the request.
final String id;
/**
* The method that was requested.
*/
/// The method that was requested.
final String method;
/**
* The request parameters.
*/
/// The request parameters.
final Map<String, dynamic> params;
/**
* The time at which the request was sent.
*/
/// The time at which the request was sent.
final int requestTime;
/**
* The time at which the response was received, or `null` if no response has
* been received.
*/
/// The time at which the response was received, or `null` if no response has
/// been received.
int responseTime;
/**
* The response that was received.
*/
/// The response that was received.
Response _response;
/**
* The completer that will be completed when a response is received.
*/
/// The completer that will be completed when a response is received.
Completer<Response> _responseCompleter;
/**
* Initialize a newly created set of request data.
*/
/// Initialize a newly created set of request data.
RequestData(this.id, this.method, this.params, this.requestTime);
/**
* Return the number of milliseconds that elapsed between the request and the
* response. This getter assumes that the response was received.
*/
/// Return the number of milliseconds that elapsed between the request and the
/// response. This getter assumes that the response was received.
int get elapsedTime => responseTime - requestTime;
/**
* Return a future that will complete when a response is received.
*/
/// Return a future that will complete when a response is received.
Future<Response> get respondedTo {
if (_response != null) {
return Future.value(_response);
@ -114,9 +80,7 @@ class RequestData {
return _responseCompleter.future;
}
/**
* Record that the given [response] was received.
*/
/// Record that the given [response] was received.
void recordResponse(Response response) {
if (_response != null) {
stdout.writeln(
@ -132,113 +96,80 @@ class RequestData {
}
}
/**
* A utility for starting and communicating with an analysis server that is
* running in a separate process.
*/
/// A utility for starting and communicating with an analysis server that is
/// running in a separate process.
class Server {
/**
* The label used for communications from the client.
*/
/// The label used for communications from the client.
static const String fromClient = 'client';
/**
* The label used for normal communications from the server.
*/
/// The label used for normal communications from the server.
static const String fromServer = 'server';
/**
* The label used for output written by the server on [fromStderr].
*/
/// The label used for output written by the server on [fromStderr].
static const String fromStderr = 'stderr';
/**
* The logger to which the communications log should be written, or `null` if
* the log should not be written.
*/
/// The logger to which the communications log should be written, or `null` if
/// the log should not be written.
final Logger logger;
/**
* The process in which the server is running, or `null` if the server hasn't
* been started yet.
*/
/// The process in which the server is running, or `null` if the server hasn't
/// been started yet.
Process _process;
/**
* Number that should be used to compute the 'id' to send in the next command
* sent to the server.
*/
/// Number that should be used to compute the 'id' to send in the next command
/// sent to the server.
int _nextId = 0;
/**
* The analysis roots that are included.
*/
/// The analysis roots that are included.
List<String> _analysisRootIncludes = <String>[];
/**
* A list containing the paths of files for which an overlay has been created.
*/
/// A list containing the paths of files for which an overlay has been
/// created.
List<String> filesWithOverlays = <String>[];
/**
* The files that the server reported as being analyzed.
*/
/// The files that the server reported as being analyzed.
List<String> _analyzedFiles = <String>[];
/// A mapping from the absolute paths of files to the most recent set of
/// errors received for that file.
final ErrorMap _errorMap = ErrorMap();
/**
* The completer that will be completed the next time a 'server.status'
* notification is received from the server with 'analyzing' set to false.
*/
/// The completer that will be completed the next time a 'server.status'
/// notification is received from the server with 'analyzing' set to false.
Completer<void> _analysisFinishedCompleter;
/**
* The completer that will be completed the next time a 'server.connected'
* notification is received from the server.
*/
/// The completer that will be completed the next time a 'server.connected'
/// notification is received from the server.
Completer<void> _serverConnectedCompleter;
/**
* A table mapping the ids of requests that have been sent to the server to
* data about those requests.
*/
/// A table mapping the ids of requests that have been sent to the server to
/// data about those requests.
final Map<String, RequestData> _requestDataMap = <String, RequestData>{};
/**
* A table mapping the number of times a request whose 'event' is equal to the
* key was sent to the server.
*/
/// A table mapping the number of times a request whose 'event' is equal to
/// the key was sent to the server.
final Map<String, int> _notificationCountMap = <String, int>{};
/**
* Initialize a new analysis server. The analysis server is not running and
* must be started using [start].
*
* If a [logger] is provided, the communications between the client (this
* test) and the server will be written to it.
*/
/// Initialize a new analysis server. The analysis server is not running and
/// must be started using [start].
///
/// If a [logger] is provided, the communications between the client (this
/// test) and the server will be written to it.
Server({this.logger});
/**
* Return a future that will complete when a 'server.status' notification is
* received from the server with 'analyzing' set to false.
*
* The future will only be completed by 'server.status' notifications that are
* received after this function call, so it is safe to use this getter
* multiple times in one test; each time it is used it will wait afresh for
* analysis to finish.
*/
/// Return a future that will complete when a 'server.status' notification is
/// received from the server with 'analyzing' set to false.
///
/// The future will only be completed by 'server.status' notifications that
/// are received after this function call, so it is safe to use this getter
/// multiple times in one test; each time it is used it will wait afresh for
/// analysis to finish.
Future get analysisFinished {
_analysisFinishedCompleter ??= Completer<void>();
return _analysisFinishedCompleter.future;
}
/**
* Return a list of the paths of files that are currently being analyzed.
*/
/// Return a list of the paths of files that are currently being analyzed.
List<String> get analyzedDartFiles {
bool isAnalyzed(String filePath) {
// TODO(brianwilkerson) This should use the path package to determine
@ -260,17 +191,13 @@ class Server {
return analyzedFiles;
}
/**
* Return a table mapping the absolute paths of files to the most recent set
* of errors received for that file. The content of the map will not change
* when new sets of errors are received.
*/
/// Return a table mapping the absolute paths of files to the most recent set
/// of errors received for that file. The content of the map will not change
/// when new sets of errors are received.
ErrorMap get errorMap => ErrorMap.from(_errorMap);
/**
* Compute a mapping from each of the file paths in the given list of
* [filePaths] to the list of errors in the file at that path.
*/
/// Compute a mapping from each of the file paths in the given list of
/// [filePaths] to the list of errors in the file at that path.
Future<ErrorMap> computeErrorMap(List<String> filePaths) async {
ErrorMap errorMap = ErrorMap();
List<Future> futures = <Future>[];
@ -288,9 +215,7 @@ class Server {
return errorMap;
}
/**
* Print information about the communications with the server.
*/
/// Print information about the communications with the server.
void printStatistics() {
void writeSpaces(int count) {
for (int i = 0; i < count; i++) {
@ -381,9 +306,7 @@ class Server {
}
}
/**
* Remove any existing overlays.
*/
/// Remove any existing overlays.
void removeAllOverlays() {
Map<String, dynamic> files = HashMap<String, dynamic>();
for (String path in filesWithOverlays) {
@ -584,20 +507,18 @@ class Server {
_send('server.shutdown', null);
}
/**
* Start the server and listen for communications from it.
*
* If [checked] is `true`, the server's VM will be running in checked mode.
*
* If [diagnosticPort] is not `null`, the server will serve status pages to
* the specified port.
*
* If [profileServer] is `true`, the server will be started with "--observe"
* and "--pause-isolates-on-exit", allowing the observatory to be used.
*
* If [useAnalysisHighlight2] is `true`, the server will use the new highlight
* APIs.
*/
/// Start the server and listen for communications from it.
///
/// If [checked] is `true`, the server's VM will be running in checked mode.
///
/// If [diagnosticPort] is not `null`, the server will serve status pages to
/// the specified port.
///
/// If [profileServer] is `true`, the server will be started with "--observe"
/// and "--pause-isolates-on-exit", allowing the observatory to be used.
///
/// If [useAnalysisHighlight2] is `true`, the server will use the new
/// highlight APIs.
Future<void> start(
{bool checked = true,
int diagnosticPort,
@ -663,10 +584,8 @@ class Server {
return _serverConnectedCompleter.future;
}
/**
* Find the root directory of the analysis_server package by proceeding
* upward to the 'test' dir, and then going up one more directory.
*/
/// Find the root directory of the analysis_server package by proceeding
/// upward to the 'test' dir, and then going up one more directory.
String _findRoot(String pathname) {
while (!['benchmark', 'test'].contains(path.basename(pathname))) {
String parent = path.dirname(pathname);
@ -678,9 +597,7 @@ class Server {
return path.dirname(pathname);
}
/**
* Handle a [notification] received from the server.
*/
/// Handle a [notification] received from the server.
void _handleNotification(Notification notification) {
switch (notification.event) {
case 'server.connected':
@ -753,9 +670,7 @@ class Server {
}
}
/**
* Handle a [response] received from the server.
*/
/// Handle a [response] received from the server.
void _handleResponse(Response response) {
String id = response.id.toString();
RequestData requestData = _requestDataMap[id];
@ -832,23 +747,17 @@ class Server {
// }
}
/**
* Handle a [line] of input read from stderr.
*/
/// Handle a [line] of input read from stderr.
void _handleStdErr(String line) {
String trimmedLine = line.trim();
logger?.log(fromStderr, '$trimmedLine');
throw StateError('Message received on stderr: "$trimmedLine"');
}
/**
* Handle a [line] of input read from stdout.
*/
/// Handle a [line] of input read from stdout.
void _handleStdOut(String line) {
/**
* Cast the given [value] to a Map, or throw an [ArgumentError] if the value
* cannot be cast.
*/
/// Cast the given [value] to a Map, or throw an [ArgumentError] if the
/// value cannot be cast.
Map asMap(Object value) {
if (value is Map) {
return value;
@ -876,14 +785,10 @@ class Server {
}
}
/**
* Start listening to output from the server.
*/
/// Start listening to output from the server.
void _listenToOutput() {
/**
* Install the given [handler] to listen to transformed output from the
* given [stream].
*/
/// Install the given [handler] to listen to transformed output from the
/// given [stream].
void installHandler(
Stream<List<int>> stream, void Function(String) handler) {
stream
@ -896,9 +801,7 @@ class Server {
installHandler(_process.stderr, _handleStdErr);
}
/**
* Send a command to the server. An 'id' will be automatically assigned.
*/
/// Send a command to the server. An 'id' will be automatically assigned.
RequestData _send(String method, Map<String, dynamic> params,
{void Function(Response) onResponse}) {
String id = '${_nextId++}';

View file

@ -10,10 +10,8 @@ import 'package:path/path.dart';
import '../timing_framework.dart';
/**
* Perform the timing test, printing the minimum, average and maximum times, as
* well as the standard deviation to the output.
*/
/// Perform the timing test, printing the minimum, average and maximum times, as
/// well as the standard deviation to the output.
void main(List<String> args) {
SimpleTest test = SimpleTest();
test.run().then((TimingResult result) {
@ -27,35 +25,23 @@ void main(List<String> args) {
});
}
/**
* A test of how long it takes to get code completion results after making a
* minor change inside a method body.
*/
/// A test of how long it takes to get code completion results after making a
/// minor change inside a method body.
class SimpleTest extends TimingTest {
/**
* The path to the file in which code completion is to be performed.
*/
/// The path to the file in which code completion is to be performed.
String mainFilePath;
/**
* The original content of the file.
*/
/// The original content of the file.
String originalContent;
/**
* The offset of the cursor when requesting code completion.
*/
/// The offset of the cursor when requesting code completion.
int cursorOffset;
/**
* A completer that will be completed when code completion results have been
* received from the server.
*/
/// A completer that will be completed when code completion results have been
/// received from the server.
Completer completionReceived;
/**
* Initialize a newly created test.
*/
/// Initialize a newly created test.
SimpleTest();
@override

View file

@ -11,38 +11,26 @@ import 'package:path/path.dart';
import '../integration/support/integration_test_methods.dart';
import '../integration/support/integration_tests.dart';
/**
* Instances of the class [TimingResult] represent the timing information
* gathered while executing a given timing test.
*/
/// Instances of the class [TimingResult] represent the timing information
/// gathered while executing a given timing test.
class TimingResult {
/**
* The number of nanoseconds in a millisecond.
*/
/// The number of nanoseconds in a millisecond.
static int NANOSECONDS_PER_MILLISECOND = 1000000;
/**
* The amount of time spent executing each test, in nanoseconds.
*/
/// The amount of time spent executing each test, in nanoseconds.
List<int> times;
/**
* Initialize a newly created timing result.
*/
/// Initialize a newly created timing result.
TimingResult(this.times);
/**
* The average amount of time spent executing a single iteration, in
* milliseconds.
*/
/// The average amount of time spent executing a single iteration, in
/// milliseconds.
int get averageTime {
return totalTime ~/ times.length;
}
/**
* The maximum amount of time spent executing a single iteration, in
* milliseconds.
*/
/// The maximum amount of time spent executing a single iteration, in
/// milliseconds.
int get maxTime {
int maxTime = 0;
int count = times.length;
@ -52,10 +40,8 @@ class TimingResult {
return maxTime ~/ NANOSECONDS_PER_MILLISECOND;
}
/**
* The minimum amount of time spent executing a single iteration, in
* milliseconds.
*/
/// The minimum amount of time spent executing a single iteration, in
/// milliseconds.
int get minTime {
int minTime = times[0];
int count = times.length;
@ -65,16 +51,12 @@ class TimingResult {
return minTime ~/ NANOSECONDS_PER_MILLISECOND;
}
/**
* The standard deviation of the times.
*/
/// The standard deviation of the times.
double get standardDeviation {
return computeStandardDeviation(toMilliseconds(times));
}
/**
* The total amount of time spent executing the test, in milliseconds.
*/
/// The total amount of time spent executing the test, in milliseconds.
int get totalTime {
int totalTime = 0;
int count = times.length;
@ -84,9 +66,7 @@ class TimingResult {
return totalTime ~/ NANOSECONDS_PER_MILLISECOND;
}
/**
* Compute the standard deviation of the given set of [values].
*/
/// Compute the standard deviation of the given set of [values].
double computeStandardDeviation(List<int> values) {
int count = values.length;
double sumOfValues = 0;
@ -102,10 +82,8 @@ class TimingResult {
return sqrt((sumOfDiffSquared / (count - 1)));
}
/**
* Convert the given [times], expressed in nanoseconds, to times expressed in
* milliseconds.
*/
/// Convert the given [times], expressed in nanoseconds, to times expressed in
/// milliseconds.
List<int> toMilliseconds(List<int> times) {
int count = times.length;
List<int> convertedValues = <int>[];
@ -116,75 +94,50 @@ class TimingResult {
}
}
/**
* The abstract class [TimingTest] defines the behavior of objects that measure
* the time required to perform some sequence of server operations.
*/
/// The abstract class [TimingTest] defines the behavior of objects that measure
/// the time required to perform some sequence of server operations.
abstract class TimingTest extends IntegrationTestMixin {
/**
* The number of times the test will be performed in order to warm up the VM.
*/
/// The number of times the test will be performed in order to warm up the VM.
static final int DEFAULT_WARMUP_COUNT = 10;
/**
* The number of times the test will be performed in order to compute a time.
*/
/// The number of times the test will be performed in order to compute a time.
static final int DEFAULT_TIMING_COUNT = 10;
/**
* The file suffix used to identify Dart files.
*/
/// The file suffix used to identify Dart files.
static final String DART_SUFFIX = '.dart';
/**
* The file suffix used to identify HTML files.
*/
/// The file suffix used to identify HTML files.
static final String HTML_SUFFIX = '.html';
/**
* The amount of time to give the server to respond to a shutdown request
* before forcibly terminating it.
*/
/// The amount of time to give the server to respond to a shutdown request
/// before forcibly terminating it.
static const Duration SHUTDOWN_TIMEOUT = Duration(seconds: 5);
/**
* The connection to the analysis server.
*/
/// The connection to the analysis server.
@override
Server server;
/**
* The temporary directory in which source files can be stored.
*/
/// The temporary directory in which source files can be stored.
Directory sourceDirectory;
/**
* A flag indicating whether the teardown process should skip sending a
* "server.shutdown" request because the server is known to have already
* shutdown.
*/
/// A flag indicating whether the teardown process should skip sending a
/// "server.shutdown" request because the server is known to have already
/// shutdown.
bool skipShutdown = false;
/**
* Initialize a newly created test.
*/
/// Initialize a newly created test.
TimingTest();
/**
* Return the number of iterations that should be performed in order to
* compute a time.
*/
/// Return the number of iterations that should be performed in order to
/// compute a time.
int get timingCount => DEFAULT_TIMING_COUNT;
/**
* Return the number of iterations that should be performed in order to warm
* up the VM.
*/
/// Return the number of iterations that should be performed in order to warm
/// up the VM.
int get warmupCount => DEFAULT_WARMUP_COUNT;
/**
* Perform any operations that need to be performed once before any iterations.
*/
/// Perform any operations that need to be performed once before any
/// iterations.
Future oneTimeSetUp() {
initializeInttestMixin();
server = Server();
@ -203,26 +156,21 @@ abstract class TimingTest extends IntegrationTestMixin {
});
}
/**
* Perform any operations that need to be performed once after all iterations.
*/
/// Perform any operations that need to be performed once after all
/// iterations.
Future oneTimeTearDown() {
return _shutdownIfNeeded().then((_) {
sourceDirectory.deleteSync(recursive: true);
});
}
/**
* Perform any operations that part of a single iteration. It is the execution
* of this method that will be measured.
*/
/// Perform any operations that part of a single iteration. It is the
/// execution of this method that will be measured.
Future perform();
/**
* Return a future that will complete with a timing result representing the
* number of milliseconds required to perform the operation the specified
* number of times.
*/
/// Return a future that will complete with a timing result representing the
/// number of milliseconds required to perform the operation the specified
/// number of times.
Future<TimingResult> run() async {
List<int> times = <int>[];
await oneTimeSetUp();
@ -232,50 +180,38 @@ abstract class TimingTest extends IntegrationTestMixin {
return Future<TimingResult>.value(TimingResult(times));
}
/**
* Perform any operations that need to be performed before each iteration.
*/
/// Perform any operations that need to be performed before each iteration.
Future setUp();
/**
* Convert the given [relativePath] to an absolute path, by interpreting it
* relative to [sourceDirectory]. On Windows any forward slashes in
* [relativePath] are converted to backslashes.
*/
/// Convert the given [relativePath] to an absolute path, by interpreting it
/// relative to [sourceDirectory]. On Windows any forward slashes in
/// [relativePath] are converted to backslashes.
String sourcePath(String relativePath) {
return join(sourceDirectory.path, relativePath.replaceAll('/', separator));
}
/**
* Perform any operations that need to be performed after each iteration.
*/
/// Perform any operations that need to be performed after each iteration.
Future tearDown();
/**
* Write a source file with the given absolute [pathname] and [contents].
*
* If the file didn't previously exist, it is created. If it did, it is
* overwritten.
*
* Parent directories are created as necessary.
*/
/// Write a source file with the given absolute [pathname] and [contents].
///
/// If the file didn't previously exist, it is created. If it did, it is
/// overwritten.
///
/// Parent directories are created as necessary.
void writeFile(String pathname, String contents) {
Directory(dirname(pathname)).createSync(recursive: true);
File(pathname).writeAsStringSync(contents);
}
/**
* Return the number of nanoseconds that have elapsed since the given
* [stopwatch] was last stopped.
*/
/// Return the number of nanoseconds that have elapsed since the given
/// [stopwatch] was last stopped.
int _elapsedNanoseconds(Stopwatch stopwatch) {
return (stopwatch.elapsedTicks * 1000000000) ~/ stopwatch.frequency;
}
/**
* Repeatedly execute this test [count] times, adding timing information to
* the given list of [times] if it is non-`null`.
*/
/// Repeatedly execute this test [count] times, adding timing information to
/// the given list of [times] if it is non-`null`.
Future _repeat(int count, List<int> times) {
Stopwatch stopwatch = Stopwatch();
return setUp().then((_) {
@ -296,9 +232,7 @@ abstract class TimingTest extends IntegrationTestMixin {
});
}
/**
* Shut the server down unless [skipShutdown] is `true`.
*/
/// Shut the server down unless [skipShutdown] is `true`.
Future _shutdownIfNeeded() {
if (skipShutdown) {
return Future.value();