Skip to content

Commit 0b2b0fe

Browse files
committed
Version 0.6.19.0 .
svn merge -r 26167:26292 https://dart.googlecode.com/svn/branches/bleeding_edge trunk git-svn-id: http://dart.googlecode.com/svn/trunk@26296 260f80e4-7a28-3924-810f-c04153c831b5
2 parents a23944b + bdc173d commit 0b2b0fe

File tree

266 files changed

+11034
-5636
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

266 files changed

+11034
-5636
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ pubspec.lock
5757
# Generated files.
5858
tools/out
5959
tools/xcodebuild
60+
pkg/shadow_dom/tool/node_modules
61+
62+
63+

PRESUBMIT.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ def CheckChangeOnCommit(input_api, output_api):
1414
input_api,
1515
output_api,
1616
json_url='http://dart-status.appspot.com/current?format=json')
17-
results.extend(status_check)
17+
# TODO(ricow): reenable when status page is back in shape
18+
# results.extend(status_check)
1819
return results

WATCHLISTS

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2+
# for details. All rights reserved. Use of this source code is governed by a
3+
# BSD-style license that can be found in the LICENSE file.
4+
5+
# Watchlist Rules
6+
# Refer: http://dev.chromium.org/developers/contributing-code/watchlists
7+
8+
{
9+
'WATCHLIST_DEFINITIONS': {
10+
'runtime': {
11+
'filepath': 'runtime/',
12+
},
13+
},
14+
15+
'WATCHLISTS': {
16+
'runtime': ['[email protected]'],
17+
},
18+
}
19+

pkg/analyzer_experimental/lib/analyzer.dart

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'package:path/path.dart' as pathos;
1111
import 'src/error.dart';
1212
import 'src/generated/ast.dart';
1313
import 'src/generated/error.dart';
14-
import 'src/generated/java_io.dart';
1514
import 'src/generated/parser.dart';
1615
import 'src/generated/scanner.dart';
1716
import 'src/generated/source_io.dart';
@@ -49,13 +48,7 @@ CompilationUnit parseDartFile(String path) {
4948

5049
/// Converts an AST node representing a string literal into a [String].
5150
String stringLiteralToString(StringLiteral literal) {
52-
if (literal is AdjacentStrings) {
53-
return literal.strings.map(stringLiteralToString).join();
54-
} else if (literal is SimpleStringLiteral) {
55-
return literal.value;
56-
} else {
57-
throw new ArgumentError("Can't convert $literal to a Dart string.");
58-
}
51+
return literal.stringValue;
5952
}
6053

6154
/// A simple error listener that collects errors into an [AnalysisErrorGroup].

pkg/analyzer_experimental/lib/options.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
library options;
66

77
import 'package:args/args.dart';
8+
import 'package:path/path.dart';
89

910
import 'dart:io';
1011

@@ -153,9 +154,8 @@ class CommandLineOptions {
153154

154155
static String _getVersion() {
155156
try {
156-
Path path = new Path(Platform.script);
157-
Path versionPath = path.directoryPath.append('..').append('version');
158-
File versionFile = new File.fromPath(versionPath);
157+
String versionPath = join(dirname(Platform.script), '..', 'version');;
158+
File versionFile = new File(versionPath);
159159
return versionFile.readAsStringSync().trim();
160160
} catch (_) {
161161
// This happens when the script is not running in the context of an SDK.

pkg/barback/lib/src/asset_cascade.dart

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ class AssetCascade {
113113
/// Gets the asset identified by [id].
114114
///
115115
/// If [id] is for a generated or transformed asset, this will wait until it
116-
/// has been created and return it. If the asset cannot be found, returns
117-
/// null.
116+
/// has been created and return it. This means that the returned asset will
117+
/// always be [AssetState.AVAILABLE].
118+
///
119+
/// If the asset cannot be found, returns null.
118120
Future<AssetNode> getAssetNode(AssetId id) {
119121
assert(id.package == package);
120122

@@ -126,11 +128,9 @@ class AssetCascade {
126128
// * If [id] has never been generated and all active transformers provide
127129
// metadata about the file names of assets it can emit, we can prove that
128130
// none of them can emit [id] and fail early.
129-
return newFuture(() {
130-
var node = _getAssetNode(id);
131-
131+
return _phases.last.getInput(id).then((node) {
132132
// If the requested asset is available, we can just return it.
133-
if (node != null) return node;
133+
if (node != null && node.state.isAvailable) return node;
134134

135135
// If there's a build running, that build might generate the asset, so we
136136
// wait for it to complete and then try again.
@@ -144,24 +144,6 @@ class AssetCascade {
144144
});
145145
}
146146

147-
// Returns the post-transformation asset node for [id], if one is available.
148-
//
149-
// This will only return a node that has an asset available, and only if that
150-
// node is guaranteed not to be consumed by any transforms. If the phase is
151-
// still working to figure out if a node will be consumed by a transformer,
152-
// that node won't be returned.
153-
AssetNode _getAssetNode(AssetId id) {
154-
// Each phase's inputs are the outputs of the previous phase. Find the last
155-
// phase that contains the asset. Since the last phase has no transformers,
156-
// this will find the latest output for that id.
157-
for (var i = _phases.length - 1; i >= 0; i--) {
158-
var node = _phases[i].getUnconsumedInput(id);
159-
if (node != null) return node;
160-
}
161-
162-
return null;
163-
}
164-
165147
/// Adds [sources] to the graph's known set of source assets.
166148
///
167149
/// Begins applying any transforms that can consume any of the sources. If a

pkg/barback/lib/src/barback.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class Barback {
7373
Future<Asset> getAssetById(AssetId id) {
7474
return _graph.getAssetNode(id).then((node) {
7575
if (node == null) throw new AssetNotFoundException(id);
76-
return node.whenAvailable;
76+
return node.asset;
7777
});
7878
}
7979

pkg/barback/lib/src/errors.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ abstract class BarbackException implements Exception {}
2929
/// Error thrown when two or more transformers both output an asset with [id].
3030
class AssetCollisionException implements BarbackException {
3131
/// All the transforms that output an asset with [id].
32+
///
33+
/// If this only contains a single transform, that indicates that a
34+
/// transformer produced an output that collides with a source asset or an
35+
/// asset from a previous phase.
3236
final Set<TransformInfo> transforms;
3337
final AssetId id;
3438

pkg/barback/lib/src/package_graph.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ class PackageGraph {
8585
/// Gets the asset node identified by [id].
8686
///
8787
/// If [id] is for a generated or transformed asset, this will wait until it
88-
/// has been created and return it. If the asset cannot be found, returns
89-
/// null.
88+
/// has been created and return it. This means that the returned asset will
89+
/// always be [AssetState.AVAILABLE].
90+
///
91+
/// If the asset cannot be found, returns null.
9092
Future<AssetNode> getAssetNode(AssetId id) {
9193
var cascade = _cascades[id.package];
9294
if (cascade != null) return cascade.getAssetNode(id);

pkg/barback/lib/src/phase.dart

Lines changed: 81 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ class Phase {
5656
/// is a transformer. "dart2js on web/main.dart" is a transform.
5757
final _transforms = new Map<AssetId, Set<TransformNode>>();
5858

59+
/// Controllers for assets that aren't consumed by transforms in this phase.
60+
///
61+
/// These assets are passed to the next phase unmodified. They need
62+
/// intervening controllers to ensure that the outputs can be marked dirty
63+
/// when determining whether transforms apply, and removed if they do.
64+
final _passThroughControllers = new Map<AssetId, AssetNodeController>();
65+
5966
/// Futures that will complete once the transformers that can consume a given
6067
/// asset are determined.
6168
///
@@ -73,10 +80,10 @@ class Phase {
7380
/// transforms that produced those asset nodes.
7481
///
7582
/// Usually there's only one node for a given output id. However, it's
76-
/// possible for multiple transformers in this phase to output an asset with
77-
/// the same id. In that case, the chronologically first output emitted is
78-
/// passed forward. We keep track of the other nodes so that if that output is
79-
/// removed, we know which asset to replace it with.
83+
/// possible for multiple transformers to output an asset with the same id. In
84+
/// that case, the chronologically first output emitted is passed forward. We
85+
/// keep track of the other nodes so that if that output is removed, we know
86+
/// which asset to replace it with.
8087
final _outputs = new Map<AssetId, Queue<AssetNode>>();
8188

8289
/// A stream that emits an event whenever this phase becomes dirty and needs
@@ -163,36 +170,11 @@ class Phase {
163170
});
164171
}
165172

166-
/// Returns the input for this phase with the given [id], but only if that
167-
/// input is known not to be consumed as a transformer's primary input.
168-
///
169-
/// If the input is unavailable, or if the phase hasn't determined whether or
170-
/// not any transformers will consume it as a primary input, null will be
171-
/// returned instead. This means that the return value is guaranteed to always
172-
/// be [AssetState.AVAILABLE].
173-
AssetNode getUnconsumedInput(AssetId id) {
174-
if (!_inputs.containsKey(id)) return null;
175-
176-
// If the asset has transforms, it's not unconsumed.
177-
if (!_transforms[id].isEmpty) return null;
178-
179-
// If we're working on figuring out if the asset has transforms, we can't
180-
// prove that it's unconsumed.
181-
if (_adjustTransformersFutures.containsKey(id)) return null;
182-
183-
// The asset should be available. If it were removed, it wouldn't be in
184-
// _inputs, and if it were dirty, it'd be in _adjustTransformersFutures.
185-
assert(_inputs[id].state.isAvailable);
186-
return _inputs[id];
187-
}
188-
189173
/// Gets the asset node for an input [id].
190174
///
191175
/// If an input with that ID cannot be found, returns null.
192176
Future<AssetNode> getInput(AssetId id) {
193177
return newFuture(() {
194-
// TODO(rnystrom): Need to handle passthrough where an asset from a
195-
// previous phase can be found.
196178
if (id.package == cascade.package) return _inputs[id];
197179
return cascade.graph.getAssetNode(id);
198180
});
@@ -210,6 +192,11 @@ class Phase {
210192
// kick off a build, even if that build does nothing.
211193
_onDirtyController.add(null);
212194

195+
// If there's a pass-through for this node, mark it dirty while we figure
196+
// out whether we need to add any transforms for it.
197+
var controller = _passThroughControllers[node.id];
198+
if (controller != null) controller.setDirty();
199+
213200
// Once the input is available, hook up transformers for it. If it changes
214201
// while that's happening, try again.
215202
_adjustTransformersFutures[node.id] = node.tryUntilStable((asset) {
@@ -219,13 +206,17 @@ class Phase {
219206
return _removeStaleTransforms(asset)
220207
.then((_) => _addFreshTransforms(node, oldTransformers));
221208
}).then((_) {
209+
_adjustPassThrough(node);
210+
222211
// Now all the transforms are set up correctly and the asset is available
223212
// for the time being. Set up handlers for when the asset changes in the
224213
// future.
225214
node.onStateChange.first.then((state) {
226215
if (state.isRemoved) {
227216
_onDirtyController.add(null);
228217
_transforms.remove(node.id);
218+
var passThrough = _passThroughControllers.remove(node.id);
219+
if (passThrough != null) passThrough.setRemoved();
229220
} else {
230221
_adjustTransformers(node);
231222
}
@@ -237,8 +228,10 @@ class Phase {
237228

238229
// If the asset is removed, [tryUntilStable] will throw an
239230
// [AssetNotFoundException]. In that case, just remove all transforms for
240-
// the node.
231+
// the node, and its pass-through.
241232
_transforms.remove(node.id);
233+
var passThrough = _passThroughControllers.remove(node.id);
234+
if (passThrough != null) passThrough.setRemoved();
242235
}).whenComplete(() {
243236
_adjustTransformersFutures.remove(node.id);
244237
});
@@ -291,6 +284,28 @@ class Phase {
291284
}));
292285
}
293286

287+
/// Adjust whether [node] is passed through the phase unmodified, based on
288+
/// whether it's consumed by other transforms in this phase.
289+
///
290+
/// If [node] was already passed-through, this will update the passed-through
291+
/// value.
292+
void _adjustPassThrough(AssetNode node) {
293+
assert(node.state.isAvailable);
294+
295+
if (_transforms[node.id].isEmpty) {
296+
var controller = _passThroughControllers[node.id];
297+
if (controller != null) {
298+
controller.setAvailable(node.asset);
299+
} else {
300+
_passThroughControllers[node.id] =
301+
new AssetNodeController.available(node.asset, node.transform);
302+
}
303+
} else {
304+
var controller = _passThroughControllers.remove(node.id);
305+
if (controller != null) controller.setRemoved();
306+
}
307+
}
308+
294309
/// Processes this phase.
295310
///
296311
/// Returns a future that completes when processing is done. If there is
@@ -308,14 +323,24 @@ class Phase {
308323

309324
/// Applies all currently wired up and dirty transforms.
310325
Future _processTransforms() {
326+
if (_next == null) return;
327+
328+
var newPassThroughs = _passThroughControllers.values
329+
.map((controller) => controller.node)
330+
.where((output) {
331+
return !_outputs.containsKey(output.id) ||
332+
!_outputs[output.id].contains(output);
333+
}).toSet();
334+
311335
// Convert this to a list so we can safely modify _transforms while
312336
// iterating over it.
313337
var dirtyTransforms =
314338
flatten(_transforms.values.map((transforms) => transforms.toList()))
315339
.where((transform) => transform.isDirty).toList();
316-
if (dirtyTransforms.isEmpty) return null;
317340

318-
var collisions = new Set<AssetId>();
341+
if (dirtyTransforms.isEmpty && newPassThroughs.isEmpty) return null;
342+
343+
var collisions = _passAssetsThrough(newPassThroughs);
319344
return Future.wait(dirtyTransforms.map((transform) {
320345
return transform.apply().then((outputs) {
321346
for (var output in outputs) {
@@ -346,6 +371,30 @@ class Phase {
346371
});
347372
}
348373

374+
/// Pass all new assets that aren't consumed by transforms through to the next
375+
/// phase.
376+
///
377+
/// Returns a set of asset ids that have collisions between new passed-through
378+
/// assets and pre-existing transform outputs.
379+
Set<AssetId> _passAssetsThrough(Set<AssetId> newPassThroughs) {
380+
var collisions = new Set<AssetId>();
381+
for (var output in newPassThroughs) {
382+
if (_outputs.containsKey(output.id)) {
383+
// There shouldn't be another pass-through asset with the same id.
384+
assert(!_outputs[output.id].any((asset) => asset.transform == null));
385+
386+
_outputs[output.id].add(output);
387+
collisions.add(output.id);
388+
} else {
389+
_outputs[output.id] = new Queue<AssetNode>.from([output]);
390+
_next.addInput(output);
391+
}
392+
393+
_handleOutputRemoval(output);
394+
}
395+
return collisions;
396+
}
397+
349398
/// Properly resolve collisions when [output] is removed.
350399
void _handleOutputRemoval(AssetNode output) {
351400
output.whenRemoved.then((_) {

0 commit comments

Comments
 (0)