-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Only currently adds a single region around Directives. Bug: #33033 Change-Id: Ibde0400c5815c00b1f94bf592d8cc9eb7cb592cf Reviewed-on: https://dart-review.googlesource.com/54232 Commit-Queue: Danny Tuppeny <dantup@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
- Loading branch information
Showing
7 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
pkg/analysis_server/lib/src/computer/computer_folding.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/ast/visitor.dart'; | ||
import 'package:analyzer_plugin/protocol/protocol_common.dart'; | ||
|
||
/** | ||
* A computer for [CompilationUnit] folding. | ||
*/ | ||
class DartUnitFoldingComputer { | ||
final CompilationUnit _unit; | ||
|
||
Directive _firstDirective, _lastDirective; | ||
final List<FoldingRegion> _foldingRegions = []; | ||
|
||
DartUnitFoldingComputer(this._unit); | ||
|
||
/** | ||
* Returns a list of folding regions, not `null`. | ||
*/ | ||
List<FoldingRegion> compute() { | ||
_unit.accept(new _DartUnitFoldingComputerVisitor(this)); | ||
|
||
if (_firstDirective != null && | ||
_lastDirective != null && | ||
_firstDirective != _lastDirective) { | ||
_foldingRegions.add(new FoldingRegion(FoldingKind.DIRECTIVES, | ||
_firstDirective.offset, _lastDirective.end - _firstDirective.offset)); | ||
} | ||
|
||
return _foldingRegions; | ||
} | ||
} | ||
|
||
/** | ||
* An AST visitor for [DartUnitFoldingComputer]. | ||
*/ | ||
class _DartUnitFoldingComputerVisitor extends RecursiveAstVisitor<Object> { | ||
final DartUnitFoldingComputer _computer; | ||
_DartUnitFoldingComputerVisitor(this._computer); | ||
|
||
@override | ||
visitImportDirective(ImportDirective node) { | ||
if (_computer._firstDirective == null) { | ||
_computer._firstDirective = node; | ||
} | ||
_computer._lastDirective = node; | ||
return super.visitImportDirective(node); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
pkg/analysis_server/test/analysis/notification_folding_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'dart:async'; | ||
|
||
import 'package:analysis_server/protocol/protocol.dart'; | ||
import 'package:analysis_server/protocol/protocol_constants.dart'; | ||
import 'package:analysis_server/protocol/protocol_generated.dart'; | ||
import 'package:analysis_server/src/protocol_server.dart'; | ||
import 'package:test/test.dart'; | ||
import 'package:test_reflective_loader/test_reflective_loader.dart'; | ||
|
||
import '../analysis_abstract.dart'; | ||
|
||
main() { | ||
defineReflectiveSuite(() { | ||
// TODO(dantup): Uncomment once implementation is complete. | ||
// Cannot just mark the tests as @failingTest as they time out | ||
// (no FOLDING notification ever) and failingTest doesn't seem | ||
// to cover that. | ||
// defineReflectiveTests(_AnalysisNotificationFoldingTest); | ||
}); | ||
} | ||
|
||
@reflectiveTest | ||
class _AnalysisNotificationFoldingTest extends AbstractAnalysisTest { | ||
static const sampleCode = ''' | ||
import 'dart:async'; | ||
import 'dart:core'; | ||
main async() {} | ||
'''; | ||
|
||
static final expectedResults = [ | ||
new FoldingRegion(FoldingKind.DIRECTIVES, 0, 40) | ||
]; | ||
|
||
List<FoldingRegion> lastRegions; | ||
|
||
Completer _regionsReceived; | ||
|
||
void processNotification(Notification notification) { | ||
if (notification.event == ANALYSIS_NOTIFICATION_FOLDING) { | ||
var params = new AnalysisFoldingParams.fromNotification(notification); | ||
if (params.file == testFile) { | ||
lastRegions = params.regions; | ||
_regionsReceived.complete(null); | ||
} | ||
} else if (notification.event == SERVER_NOTIFICATION_ERROR) { | ||
var params = new ServerErrorParams.fromNotification(notification); | ||
throw "${params.message}\n${params.stackTrace}"; | ||
} | ||
} | ||
|
||
@override | ||
void setUp() { | ||
super.setUp(); | ||
createProject(); | ||
} | ||
|
||
void subscribeForFolding() { | ||
addAnalysisSubscription(AnalysisService.FOLDING, testFile); | ||
} | ||
|
||
test_afterAnalysis() async { | ||
addTestFile(sampleCode); | ||
await waitForTasksFinished(); | ||
expect(lastRegions, isNull); | ||
|
||
await waitForFolding(() => subscribeForFolding()); | ||
|
||
expect(lastRegions, expectedResults); | ||
} | ||
|
||
test_afterUpdate() async { | ||
addTestFile(''); | ||
// Currently required to get notifications on updates | ||
setPriorityFiles([testFile]); | ||
|
||
// Before subscribing, we shouldn't have had any folding regions. | ||
await waitForTasksFinished(); | ||
expect(lastRegions, isNull); | ||
|
||
// With no content, there should be zero regions. | ||
await waitForFolding(() => subscribeForFolding()); | ||
expect(lastRegions, hasLength(0)); | ||
|
||
// With sample code there will be folding regions. | ||
await waitForFolding(() => modifyTestFile(sampleCode)); | ||
|
||
expect(lastRegions, expectedResults); | ||
} | ||
|
||
Future waitForFolding(action()) { | ||
_regionsReceived = new Completer(); | ||
action(); | ||
return _regionsReceived.future; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
pkg/analysis_server/test/src/computer/folding_computer_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'dart:async'; | ||
|
||
import 'package:analysis_server/src/computer/computer_folding.dart'; | ||
import 'package:analysis_server/src/protocol_server.dart'; | ||
import 'package:analyzer/dart/analysis/results.dart'; | ||
import 'package:test/test.dart'; | ||
import 'package:test_reflective_loader/test_reflective_loader.dart'; | ||
|
||
import '../../abstract_context.dart'; | ||
|
||
main() { | ||
defineReflectiveSuite(() { | ||
defineReflectiveTests(FoldingComputerTest); | ||
}); | ||
} | ||
|
||
@reflectiveTest | ||
class FoldingComputerTest extends AbstractContextTest { | ||
String sourcePath; | ||
|
||
setUp() { | ||
super.setUp(); | ||
sourcePath = resourceProvider.convertPath('/p/lib/source.dart'); | ||
} | ||
|
||
test_single_import_directives() async { | ||
String content = """ | ||
import 'dart:async'; | ||
main() {} | ||
"""; | ||
|
||
// Since there are no region comment markers above | ||
final regions = await _computeRegions(content); | ||
expect(regions, hasLength(0)); | ||
} | ||
|
||
test_multiple_import_directives() async { | ||
String content = """ | ||
/*1*/import 'dart:async'; | ||
// We can have comments | ||
import 'package:a/b.dart'; | ||
import 'package:b/c.dart'; | ||
import '../a.dart';/*1:DIRECTIVES*/ | ||
main() {} | ||
"""; | ||
|
||
final regions = await _computeRegions(content); | ||
_compareRegions(regions, content); | ||
} | ||
|
||
/// Compares provided folding regions with expected | ||
/// regions extracted from the comments in the provided content. | ||
void _compareRegions(List<FoldingRegion> regions, String content) { | ||
// Find all numeric markers for region starts. | ||
final regex = new RegExp(r'/\*(\d+)\*/'); | ||
final expectedRegions = regex.allMatches(content); | ||
|
||
// Check we didn't get more than expected, since the loop below only | ||
// checks for the presence of matches, not absence. | ||
expect(regions, hasLength(expectedRegions.length)); | ||
|
||
// Go through each marker, find the expected region start/end and | ||
// ensure it's in the results. | ||
expectedRegions.forEach((m) { | ||
final i = m.group(1); | ||
// Find the end marker. | ||
final endMatch = new RegExp('/\\*$i:(.+?)\\*/').firstMatch(content); | ||
|
||
final expectedStart = m.end; | ||
final expectedLength = endMatch.start - expectedStart; | ||
final expectedKindString = endMatch.group(1); | ||
final expectedKind = FoldingKind.VALUES | ||
.firstWhere((f) => f.toString() == 'FoldingKind.$expectedKindString'); | ||
|
||
expect( | ||
regions, | ||
contains( | ||
new FoldingRegion(expectedKind, expectedStart, expectedLength))); | ||
}); | ||
} | ||
|
||
Future<List<FoldingRegion>> _computeRegions(String sourceContent) async { | ||
newFile(sourcePath, content: sourceContent); | ||
ResolveResult result = await driver.getResult(sourcePath); | ||
DartUnitFoldingComputer computer = new DartUnitFoldingComputer(result.unit); | ||
return computer.compute(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters