Skip to content

Commit 66a122a

Browse files
committed
Stop defensively copying AST structures before resolution
[email protected] Review URL: https://codereview.chromium.org/1383043002 .
1 parent 04e21a2 commit 66a122a

File tree

7 files changed

+83
-12
lines changed

7 files changed

+83
-12
lines changed

pkg/analysis_server/test/analysis/notification_implemented_test.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class AnalysisNotificationImplementedTest extends AbstractAnalysisTest {
3737
if (length == -1) {
3838
length = findIdentifierLength(search);
3939
}
40+
if (implementedClasses == null) {
41+
fail('No notification of impemented classes was received');
42+
}
4043
for (ImplementedClass clazz in implementedClasses) {
4144
if (clazz.offset == offset && clazz.length == length) {
4245
return;
@@ -57,6 +60,9 @@ class AnalysisNotificationImplementedTest extends AbstractAnalysisTest {
5760
if (length == -1) {
5861
length = findIdentifierLength(search);
5962
}
63+
if (implementedMembers == null) {
64+
fail('No notification of impemented members was received');
65+
}
6066
for (ImplementedMember member in implementedMembers) {
6167
if (member.offset == offset && member.length == length) {
6268
return;
@@ -77,6 +83,9 @@ class AnalysisNotificationImplementedTest extends AbstractAnalysisTest {
7783
if (length == -1) {
7884
length = findIdentifierLength(search);
7985
}
86+
if (implementedMembers == null) {
87+
fail('No notification of impemented members was received');
88+
}
8089
for (ImplementedMember member in implementedMembers) {
8190
if (member.offset == offset) {
8291
fail('Unexpected implemented member at $offset'

pkg/analyzer/lib/src/task/dart.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask {
537537
//
538538
// Build or reuse CompilationUnitElement.
539539
//
540-
unit = AstCloner.clone(unit);
540+
// unit = AstCloner.clone(unit);
541541
AnalysisCache analysisCache =
542542
(context as InternalAnalysisContext).analysisCache;
543543
CompilationUnitElement element =
@@ -573,7 +573,7 @@ class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask {
573573
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
574574
LibrarySpecificUnit unit = target;
575575
return <String, TaskInput>{
576-
PARSED_UNIT_INPUT_NAME: PARSED_UNIT.of(unit.unit)
576+
PARSED_UNIT_INPUT_NAME: PARSED_UNIT.of(unit.unit, flushOnAccess: true)
577577
};
578578
}
579579

@@ -4110,6 +4110,9 @@ class _SourceClosureTaskInputBuilder implements TaskInputBuilder<List<Source>> {
41104110
}
41114111
}
41124112

4113+
@override
4114+
bool get flushOnAccess => false;
4115+
41134116
@override
41144117
List<Source> get inputValue {
41154118
return _libraries.map((LibraryElement library) => library.source).toList();

pkg/analyzer/lib/src/task/driver.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,9 @@ class WorkItem {
667667
}
668668
} else {
669669
builder.currentValue = inputEntry.getValue(inputResult);
670+
if (builder.flushOnAccess) {
671+
inputEntry.setState(inputResult, CacheState.FLUSHED);
672+
}
670673
}
671674
if (!builder.moveNext()) {
672675
inputs = builder.inputValue;

pkg/analyzer/lib/src/task/inputs.dart

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class ConstantTaskInputBuilder<V> implements TaskInputBuilder<V> {
5454
throw new StateError('Only supported after moveNext() returns true');
5555
}
5656

57+
@override
58+
bool get flushOnAccess => false;
59+
5760
@override
5861
V get inputValue => input.value;
5962

@@ -78,7 +81,7 @@ class ListTaskInputImpl<E> extends SimpleTaskInput<List<E>>
7881
* the given [result] associated with the given [target].
7982
*/
8083
ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result)
81-
: super(target, result);
84+
: super._unflushable(target, result);
8285
}
8386

8487
/**
@@ -288,6 +291,9 @@ class MapToFlattenListTaskInputBuilder<K, V, E>
288291
currentBuilder.currentValue = value;
289292
}
290293

294+
@override
295+
bool get flushOnAccess => currentBuilder.flushOnAccess;
296+
291297
@override
292298
void currentValueNotAvailable() {
293299
if (currentBuilder == null) {
@@ -439,6 +445,9 @@ class ObjectToListTaskInputBuilder<E> implements TaskInputBuilder<List<E>> {
439445
builder.currentValue = value;
440446
}
441447

448+
@override
449+
bool get flushOnAccess => builder.flushOnAccess;
450+
442451
@override
443452
List<E> get inputValue {
444453
if (builder != null) {
@@ -490,11 +499,24 @@ class SimpleTaskInput<V> extends TaskInputImpl<V> {
490499
*/
491500
final ResultDescriptor<V> result;
492501

502+
/**
503+
* Return `true` if the value accessed by this input builder should be flushed
504+
* from the cache at the time it is retrieved.
505+
*/
506+
final bool flushOnAccess;
507+
508+
/**
509+
* Initialize a newly created task input that computes the input by accessing
510+
* the given [result] associated with the given [target].
511+
*/
512+
SimpleTaskInput(this.target, this.result, {this.flushOnAccess: false});
513+
493514
/**
494515
* Initialize a newly created task input that computes the input by accessing
495516
* the given [result] associated with the given [target].
496517
*/
497-
SimpleTaskInput(this.target, this.result);
518+
SimpleTaskInput._unflushable(this.target, this.result)
519+
: flushOnAccess = false;
498520

499521
@override
500522
TaskInputBuilder<V> createBuilder() => new SimpleTaskInputBuilder<V>(this);
@@ -565,6 +587,9 @@ class SimpleTaskInputBuilder<V> implements TaskInputBuilder<V> {
565587
_resultSet = true;
566588
}
567589

590+
@override
591+
bool get flushOnAccess => input.flushOnAccess;
592+
568593
@override
569594
V get inputValue {
570595
if (_state != _AFTER) {
@@ -673,6 +698,9 @@ class TopLevelTaskInputBuilder
673698
currentBuilder.currentValue = value;
674699
}
675700

701+
@override
702+
bool get flushOnAccess => currentBuilder.flushOnAccess;
703+
676704
@override
677705
Map<String, Object> get inputValue {
678706
if (nameIndex < inputNames.length) {
@@ -826,6 +854,9 @@ abstract class _ListToCollectionTaskInputBuilder<B, E, C>
826854
currentBuilder.currentValue = value;
827855
}
828856

857+
@override
858+
bool get flushOnAccess => currentBuilder.flushOnAccess;
859+
829860
@override
830861
C get inputValue {
831862
if (currentBuilder != null || _resultValue == null) {

pkg/analyzer/lib/src/task/model.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ class ListResultDescriptorImpl<E> extends ResultDescriptorImpl<List<E>>
2929
: super(name, defaultValue, cachingPolicy: cachingPolicy);
3030

3131
@override
32-
ListTaskInput<E> of(AnalysisTarget target) =>
33-
new ListTaskInputImpl<E>(target, this);
32+
ListTaskInput<E> of(AnalysisTarget target, {bool flushOnAccess: false}) {
33+
if (flushOnAccess) {
34+
throw new StateError('Cannot flush a list of values');
35+
}
36+
return new ListTaskInputImpl<E>(target, this);
37+
}
3438
}
3539

3640
/**
@@ -71,8 +75,8 @@ class ResultDescriptorImpl<V> implements ResultDescriptor<V> {
7175
}
7276

7377
@override
74-
TaskInput<V> of(AnalysisTarget target) =>
75-
new SimpleTaskInput<V>(target, this);
78+
TaskInput<V> of(AnalysisTarget target, {bool flushOnAccess: false}) =>
79+
new SimpleTaskInput<V>(target, this, flushOnAccess: flushOnAccess);
7680

7781
@override
7882
String toString() => name;

pkg/analyzer/lib/task/model.dart

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
library analyzer.task.model;
66

77
import 'dart:collection';
8+
import 'dart:developer';
89

910
import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
1011
import 'package:analyzer/src/generated/error.dart' show AnalysisError;
@@ -83,6 +84,12 @@ abstract class AnalysisTask {
8384
*/
8485
static final Map<Type, int> countMap = new HashMap<Type, int>();
8586

87+
/**
88+
* A table mapping the types of analysis tasks to user tags used to collect
89+
* timing data for the Observatory.
90+
*/
91+
static Map<Type, UserTag> tagMap = new HashMap<Type, UserTag>();
92+
8693
/**
8794
* A table mapping the types of analysis tasks to stopwatches used to compute
8895
* how much time was spent executing each kind of task.
@@ -228,11 +235,15 @@ abstract class AnalysisTask {
228235
//
229236
int count = countMap[runtimeType];
230237
countMap[runtimeType] = count == null ? 1 : count + 1;
238+
// UserTag tag = tagMap.putIfAbsent(
239+
// runtimeType, () => new UserTag(runtimeType.toString()));
231240
Stopwatch stopwatch = stopwatchMap[runtimeType];
232241
if (stopwatch == null) {
233242
stopwatch = new Stopwatch();
234243
stopwatchMap[runtimeType] = stopwatch;
235244
}
245+
// UserTag previousTag = tag.makeCurrent();
246+
// try {
236247
stopwatch.start();
237248
//
238249
// Actually perform the task.
@@ -245,6 +256,9 @@ abstract class AnalysisTask {
245256
} finally {
246257
stopwatch.stop();
247258
}
259+
// } finally {
260+
// previousTag.makeCurrent();
261+
// }
248262
} on AnalysisException {
249263
rethrow;
250264
} catch (exception, stackTrace) {
@@ -272,7 +286,7 @@ abstract class ListResultDescriptor<E> implements ResultDescriptor<List<E>> {
272286
E>;
273287

274288
@override
275-
ListTaskInput<E> of(AnalysisTarget target);
289+
ListTaskInput<E> of(AnalysisTarget target, {bool flushOnAccess: false});
276290
}
277291

278292
/**
@@ -387,9 +401,10 @@ abstract class ResultDescriptor<V> {
387401

388402
/**
389403
* Return a task input that can be used to compute this result for the given
390-
* [target].
404+
* [target]. If [flushOnAccess] is `true` then the value of this result that
405+
* is associated with the [target] will be flushed when it is accessed.
391406
*/
392-
TaskInput<V> of(AnalysisTarget target);
407+
TaskInput<V> of(AnalysisTarget target, {bool flushOnAccess: false});
393408
}
394409

395410
/**
@@ -529,6 +544,12 @@ abstract class TaskInputBuilder<V> {
529544
*/
530545
void set currentValue(Object value);
531546

547+
/**
548+
* Return `true` if the value accessed by this input builder should be flushed
549+
* from the cache at the time it is retrieved.
550+
*/
551+
bool get flushOnAccess;
552+
532553
/**
533554
* Return the [value] that was computed by this builder.
534555
*

pkg/analyzer/test/src/context/context_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1500,7 +1500,7 @@ part of lib;
15001500
reason: "part changed 3");
15011501
_analyzeAll_assertFinished();
15021502
expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
1503-
reason: "library resolved 2");
1503+
reason: "library resolved 3");
15041504
expect(
15051505
context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
15061506
reason: "part resolved 3");

0 commit comments

Comments
 (0)