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

Side by Side Diff: pkg/observe/lib/transform.dart

Issue 29823005: fixes to polymer, gets tests back to a stable state (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
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 /** 5 /**
6 * Code transform for @observable. The core transformation is relatively 6 * Code transform for @observable. The core transformation is relatively
7 * straightforward, and essentially like an editor refactoring. 7 * straightforward, and essentially like an editor refactoring.
8 */ 8 */
9 library observe.transform; 9 library observe.transform;
10 10
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 if (_hasObservable(cls)) { 128 if (_hasObservable(cls)) {
129 logger.warning('@observable on a class no longer has any effect. ' 129 logger.warning('@observable on a class no longer has any effect. '
130 'It should be placed on individual fields.', 130 'It should be placed on individual fields.',
131 span: _getSpan(file, cls)); 131 span: _getSpan(file, cls));
132 } 132 }
133 133
134 // We'd like to track whether observable was declared explicitly, otherwise 134 // We'd like to track whether observable was declared explicitly, otherwise
135 // report a warning later below. Because we don't have type analysis (only 135 // report a warning later below. Because we don't have type analysis (only
136 // syntactic understanding of the code), we only report warnings that are 136 // syntactic understanding of the code), we only report warnings that are
137 // known to be true. 137 // known to be true.
138 var declaresObservable = false; 138 var explicitObservable = false;
139 var implicitObservable = false;
139 if (cls.extendsClause != null) { 140 if (cls.extendsClause != null) {
140 var id = _getSimpleIdentifier(cls.extendsClause.superclass.name); 141 var id = _getSimpleIdentifier(cls.extendsClause.superclass.name);
141 if (id.name == 'Observable') { 142 if (id.name == 'Observable') {
142 code.edit(id.offset, id.end, 'ChangeNotifier'); 143 code.edit(id.offset, id.end, 'ChangeNotifier');
143 declaresObservable = true; 144 explicitObservable = true;
144 } else if (id.name == 'ChangeNotifier') { 145 } else if (id.name == 'ChangeNotifier') {
145 declaresObservable = true; 146 explicitObservable = true;
146 } else if (id.name != 'HtmlElement' && id.name != 'CustomElement' 147 } else if (id.name != 'HtmlElement' && id.name != 'CustomElement'
147 && id.name != 'Object') { 148 && id.name != 'Object') {
148 // TODO(sigmund): this is conservative, consider using type-resolution to 149 // TODO(sigmund): this is conservative, consider using type-resolution to
149 // improve this check. 150 // improve this check.
150 declaresObservable = true; 151 implicitObservable = true;
151 } 152 }
152 } 153 }
153 154
154 if (cls.withClause != null) { 155 if (cls.withClause != null) {
155 for (var type in cls.withClause.mixinTypes) { 156 for (var type in cls.withClause.mixinTypes) {
156 var id = _getSimpleIdentifier(type.name); 157 var id = _getSimpleIdentifier(type.name);
157 if (id.name == 'Observable') { 158 if (id.name == 'Observable') {
158 code.edit(id.offset, id.end, 'ChangeNotifier'); 159 code.edit(id.offset, id.end, 'ChangeNotifier');
159 declaresObservable = true; 160 explicitObservable = true;
160 break; 161 break;
161 } else if (id.name == 'ChangeNotifier') { 162 } else if (id.name == 'ChangeNotifier') {
162 declaresObservable = true; 163 explicitObservable = true;
163 break; 164 break;
164 } else { 165 } else {
165 // TODO(sigmund): this is conservative, consider using type-resolution 166 // TODO(sigmund): this is conservative, consider using type-resolution
166 // to improve this check. 167 // to improve this check.
167 declaresObservable = true; 168 implicitObservable = true;
168 } 169 }
169 } 170 }
170 } 171 }
171 172
172 if (!declaresObservable && cls.implementsClause != null) { 173 if (cls.implementsClause != null) {
173 // TODO(sigmund): consider adding type-resolution to give a more precise 174 // TODO(sigmund): consider adding type-resolution to give a more precise
174 // answer. 175 // answer.
175 declaresObservable = true; 176 implicitObservable = true;
176 } 177 }
177 178
179 var declaresObservable = explicitObservable || implicitObservable;
180
178 // Track fields that were transformed. 181 // Track fields that were transformed.
179 var instanceFields = new Set<String>(); 182 var instanceFields = new Set<String>();
180 var getters = new List<String>(); 183 var getters = new List<String>();
181 var setters = new List<String>(); 184 var setters = new List<String>();
182 185
183 for (var member in cls.members) { 186 for (var member in cls.members) {
184 if (member is FieldDeclaration) { 187 if (member is FieldDeclaration) {
185 if (member.isStatic) { 188 if (member.isStatic) {
186 if (_hasObservable(member)){ 189 if (_hasObservable(member)){
187 logger.warning('Static fields can no longer be observable. ' 190 logger.warning('Static fields can no longer be observable. '
(...skipping 28 matching lines...) Expand all
216 getters.add(member.name.name); 219 getters.add(member.name.name);
217 } else if (_hasKeyword(member.propertyKeyword, Keyword.SET)) { 220 } else if (_hasKeyword(member.propertyKeyword, Keyword.SET)) {
218 setters.add(member.name.name); 221 setters.add(member.name.name);
219 } 222 }
220 } 223 }
221 } 224 }
222 225
223 // If nothing was @observable, bail. 226 // If nothing was @observable, bail.
224 if (instanceFields.length == 0) return; 227 if (instanceFields.length == 0) return;
225 228
229 if (!explicitObservable) _mixinObservable(cls, code);
230
226 // Fix initializers, because they aren't allowed to call the setter. 231 // Fix initializers, because they aren't allowed to call the setter.
227 for (var member in cls.members) { 232 for (var member in cls.members) {
228 if (member is ConstructorDeclaration) { 233 if (member is ConstructorDeclaration) {
229 _fixConstructor(member, code, instanceFields); 234 _fixConstructor(member, code, instanceFields);
230 } 235 }
231 } 236 }
232 } 237 }
233 238
239 /** Adds "with ChangeNotifier" and associated implementation. */
240 void _mixinObservable(ClassDeclaration cls, TextEditTransaction code) {
241 // Note: we need to be careful to put the with clause after extends, but
242 // before implements clause.
243 if (cls.withClause != null) {
244 var pos = cls.withClause.end;
245 code.edit(pos, pos, ', ChangeNotifier');
246 } else if (cls.extendsClause != null) {
247 var pos = cls.extendsClause.end;
248 code.edit(pos, pos, ' with ChangeNotifier ');
249 } else {
250 var params = cls.typeParameters;
251 var pos = params != null ? params.end : cls.name.end;
252 code.edit(pos, pos, ' extends ChangeNotifier ');
253 }
254 }
255
234 SimpleIdentifier _getSimpleIdentifier(Identifier id) => 256 SimpleIdentifier _getSimpleIdentifier(Identifier id) =>
235 id is PrefixedIdentifier ? (id as PrefixedIdentifier).identifier : id; 257 id is PrefixedIdentifier ? (id as PrefixedIdentifier).identifier : id;
236 258
237 259
238 bool _hasKeyword(Token token, Keyword keyword) => 260 bool _hasKeyword(Token token, Keyword keyword) =>
239 token is KeywordToken && (token as KeywordToken).keyword == keyword; 261 token is KeywordToken && (token as KeywordToken).keyword == keyword;
240 262
241 String _getOriginalCode(TextEditTransaction code, ASTNode node) => 263 String _getOriginalCode(TextEditTransaction code, ASTNode node) =>
242 code.original.substring(node.offset, node.end); 264 code.original.substring(node.offset, node.end);
243 265
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 404
383 Token _findFieldSeperator(Token token) { 405 Token _findFieldSeperator(Token token) {
384 while (token != null) { 406 while (token != null) {
385 if (token.type == TokenType.COMMA || token.type == TokenType.SEMICOLON) { 407 if (token.type == TokenType.COMMA || token.type == TokenType.SEMICOLON) {
386 break; 408 break;
387 } 409 }
388 token = token.next; 410 token = token.next;
389 } 411 }
390 return token; 412 return token;
391 } 413 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698