Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: lib/transformer.dart

Issue 1838473002: fix observe package to be strong mode clean (Closed) Base URL: git@github.com:dart-lang/observe.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Code transform for @observable. The core transformation is relatively 5 /// Code transform for @observable. The core transformation is relatively
6 /// straightforward, and essentially like an editor refactoring. 6 /// straightforward, and essentially like an editor refactoring.
7 library observe.transformer; 7 library observe.transformer;
8 8
9 import 'dart:async'; 9 import 'dart:async';
10 10
11 import 'package:analyzer/analyzer.dart'; 11 import 'package:analyzer/analyzer.dart';
12 import 'package:analyzer/dart/ast/token.dart';
12 import 'package:analyzer/src/generated/ast.dart'; 13 import 'package:analyzer/src/generated/ast.dart';
13 import 'package:analyzer/src/generated/scanner.dart';
14 import 'package:barback/barback.dart'; 14 import 'package:barback/barback.dart';
15 import 'package:code_transformers/messages/build_logger.dart'; 15 import 'package:code_transformers/messages/build_logger.dart';
16 import 'package:source_maps/refactor.dart'; 16 import 'package:source_maps/refactor.dart';
17 import 'package:source_span/source_span.dart'; 17 import 'package:source_span/source_span.dart';
18 18
19 import 'src/messages.dart'; 19 import 'src/messages.dart';
20 20
21 /// A [Transformer] that replaces observables based on dirty-checking with an 21 /// A [Transformer] that replaces observables based on dirty-checking with an
22 /// implementation based on change notifications. 22 /// implementation based on change notifications.
23 /// 23 ///
24 /// The transformation adds hooks for field setters and notifies the observation 24 /// The transformation adds hooks for field setters and notifies the observation
25 /// system of the change. 25 /// system of the change.
26 class ObservableTransformer extends Transformer { 26 class ObservableTransformer extends Transformer {
27 final bool releaseMode; 27 final bool releaseMode;
28 final bool injectBuildLogsInOutput; 28 final bool injectBuildLogsInOutput;
29 final List<String> _files; 29 final List<String> _files;
30
30 ObservableTransformer( 31 ObservableTransformer(
31 {List<String> files, bool releaseMode, bool injectBuildLogsInOutput}) 32 {List<String> files, bool releaseMode, bool injectBuildLogsInOutput})
32 : _files = files, 33 : _files = files,
33 releaseMode = releaseMode == true, 34 releaseMode = releaseMode == true,
34 injectBuildLogsInOutput = injectBuildLogsInOutput == null 35 injectBuildLogsInOutput = injectBuildLogsInOutput == null
35 ? releaseMode != true 36 ? releaseMode != true
36 : injectBuildLogsInOutput; 37 : injectBuildLogsInOutput;
38
37 ObservableTransformer.asPlugin(BarbackSettings settings) 39 ObservableTransformer.asPlugin(BarbackSettings settings)
38 : _files = _readFiles(settings.configuration['files']), 40 : _files = _readFiles(settings.configuration['files']),
39 releaseMode = settings.mode == BarbackMode.RELEASE, 41 releaseMode = settings.mode == BarbackMode.RELEASE,
40 injectBuildLogsInOutput = settings.mode != BarbackMode.RELEASE; 42 injectBuildLogsInOutput = settings.mode != BarbackMode.RELEASE;
41 43
42 static List<String> _readFiles(value) { 44 static List<String> _readFiles(value) {
43 if (value == null) return null; 45 if (value == null) return null;
44 var files = []; 46 var files = <String>[];
45 bool error; 47 bool error;
46 if (value is List) { 48 if (value is List) {
47 files = value; 49 files = new List<String>.from(value);
Siggi Cherem (dart-lang) 2016/03/25 17:36:29 consider adding a TODO referring to https://github
Jennifer Messerly 2016/03/25 18:23:22 IMO it's not really worth it. `new List.from` is a
48 error = value.any((e) => e is! String); 50 error = value.any((e) => e is! String);
49 } else if (value is String) { 51 } else if (value is String) {
50 files = [value]; 52 files = [value];
51 error = false; 53 error = false;
52 } else { 54 } else {
53 error = true; 55 error = true;
54 } 56 }
55 if (error) print('Invalid value for "files" in the observe transformer.'); 57 if (error) print('Invalid value for "files" in the observe transformer.');
56 return files; 58 return files;
57 } 59 }
58 60
59 // TODO(nweiz): This should just take an AssetId when barback <0.13.0 support 61 // TODO(nweiz): This should just take an AssetId when barback <0.13.0 support
60 // is dropped. 62 // is dropped.
61 Future<bool> isPrimary(idOrAsset) { 63 Future<bool> isPrimary(Object idOrAsset) {
62 var id = idOrAsset is AssetId ? idOrAsset : idOrAsset.id; 64 var id = idOrAsset is AssetId ? idOrAsset : (idOrAsset as Asset).id;
63 return new Future.value(id.extension == '.dart' && 65 return new Future.value(id.extension == '.dart' &&
64 (_files == null || _files.contains(id.path))); 66 (_files == null || _files.contains(id.path)));
65 } 67 }
66 68
67 Future apply(Transform transform) { 69 Future apply(Transform transform) {
68 return transform.primaryInput.readAsString().then((content) { 70 return transform.primaryInput.readAsString().then((content) {
69 // Do a quick string check to determine if this is this file even 71 // Do a quick string check to determine if this is this file even
70 // plausibly might need to be transformed. If not, we can avoid an 72 // plausibly might need to be transformed. If not, we can avoid an
71 // expensive parse. 73 // expensive parse.
72 if (!observableMatcher.hasMatch(content)) return null; 74 if (!observableMatcher.hasMatch(content)) return null;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 var params = cls.typeParameters; 251 var params = cls.typeParameters;
250 var pos = params != null ? params.end : cls.name.end; 252 var pos = params != null ? params.end : cls.name.end;
251 code.edit(pos, pos, ' extends ChangeNotifier '); 253 code.edit(pos, pos, ' extends ChangeNotifier ');
252 } 254 }
253 } 255 }
254 256
255 SimpleIdentifier _getSimpleIdentifier(Identifier id) => 257 SimpleIdentifier _getSimpleIdentifier(Identifier id) =>
256 id is PrefixedIdentifier ? id.identifier : id; 258 id is PrefixedIdentifier ? id.identifier : id;
257 259
258 bool _hasKeyword(Token token, Keyword keyword) => 260 bool _hasKeyword(Token token, Keyword keyword) =>
259 token is KeywordToken && token.keyword == keyword; 261 token?.type == TokenType.KEYWORD && token.lexeme == keyword.syntax;
Siggi Cherem (dart-lang) 2016/03/25 17:36:29 was this broken?
Jennifer Messerly 2016/03/25 18:23:22 no, but KeywordToken is private.
260 262
261 String _getOriginalCode(TextEditTransaction code, AstNode node) => 263 String _getOriginalCode(TextEditTransaction code, AstNode node) =>
262 code.original.substring(node.offset, node.end); 264 code.original.substring(node.offset, node.end);
263 265
264 void _fixConstructor(ConstructorDeclaration ctor, TextEditTransaction code, 266 void _fixConstructor(ConstructorDeclaration ctor, TextEditTransaction code,
265 Set<String> changedFields) { 267 Set<String> changedFields) {
266 // Fix normal initializers 268 // Fix normal initializers
267 for (var initializer in ctor.initializers) { 269 for (var initializer in ctor.initializers) {
268 if (initializer is ConstructorFieldInitializer) { 270 if (initializer is ConstructorFieldInitializer) {
269 var field = initializer.fieldName; 271 var field = initializer.fieldName;
270 if (changedFields.contains(field.name)) { 272 if (changedFields.contains(field.name)) {
271 code.edit(field.offset, field.end, '__\$${field.name}'); 273 code.edit(field.offset, field.end, '__\$${field.name}');
272 } 274 }
273 } 275 }
274 } 276 }
275 277
276 // Fix "this." initializer in parameter list. These are tricky: 278 // Fix "this." initializer in parameter list. These are tricky:
277 // we need to preserve the name and add an initializer. 279 // we need to preserve the name and add an initializer.
278 // Preserving the name is important for named args, and for dartdoc. 280 // Preserving the name is important for named args, and for dartdoc.
279 // BEFORE: Foo(this.bar, this.baz) { ... } 281 // BEFORE: Foo(this.bar, this.baz) { ... }
280 // AFTER: Foo(bar, baz) : __$bar = bar, __$baz = baz { ... } 282 // AFTER: Foo(bar, baz) : __$bar = bar, __$baz = baz { ... }
281 283
282 var thisInit = []; 284 var thisInit = [];
283 for (var param in ctor.parameters.parameters) { 285 for (var param in ctor.parameters.parameters) {
284 if (param is DefaultFormalParameter) { 286 if (param is DefaultFormalParameter) {
285 param = param.parameter; 287 param = (param as DefaultFormalParameter).parameter;
286 } 288 }
287 if (param is FieldFormalParameter) { 289 if (param is FieldFormalParameter) {
288 var name = param.identifier.name; 290 var name = param.identifier.name;
289 if (changedFields.contains(name)) { 291 if (changedFields.contains(name)) {
290 thisInit.add(name); 292 thisInit.add(name);
291 // Remove "this." but keep everything else. 293 // Remove "this." but keep everything else.
292 code.edit(param.thisKeyword.offset, param.period.end, ''); 294 code.edit(param.thisKeyword.offset, param.period.end, '');
293 } 295 }
294 } 296 }
295 } 297 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 token = token.next; 409 token = token.next;
408 } 410 }
409 return token; 411 return token;
410 } 412 }
411 413
412 // TODO(sigmund): remove hard coded Polymer support (@published). The proper way 414 // TODO(sigmund): remove hard coded Polymer support (@published). The proper way
413 // to do this would be to switch to use the analyzer to resolve whether 415 // to do this would be to switch to use the analyzer to resolve whether
414 // annotations are subtypes of ObservableProperty. 416 // annotations are subtypes of ObservableProperty.
415 final observableMatcher = 417 final observableMatcher =
416 new RegExp("@(published|observable|PublishedProperty|ObservableProperty)"); 418 new RegExp("@(published|observable|PublishedProperty|ObservableProperty)");
OLDNEW
« no previous file with comments | « lib/src/bind_property.dart ('k') | pubspec.yaml » ('j') | pubspec.yaml » ('J')

Powered by Google App Engine
This is Rietveld 408576698