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

Side by Side Diff: modules/angular2/src/transform/codegen.dart

Issue 927373004: Initial commit of Dart transformer to generate constructor stubs, see https://github.com/angular/an… (Closed) Base URL: https://github.com/kegluneq/angular.git@master
Patch Set: Fixing review comments Created 5 years, 10 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 library angular2.transformer; 1 library angular2.src.transform;
2 2
3 import 'package:analyzer/src/generated/ast.dart'; 3 import 'package:analyzer/src/generated/ast.dart';
4 import 'package:analyzer/src/generated/element.dart'; 4 import 'package:analyzer/src/generated/element.dart';
5 import 'package:analyzer/src/generated/java_core.dart'; 5 import 'package:analyzer/src/generated/java_core.dart';
6 import 'package:barback/barback.dart' show AssetId, TransformLogger; 6 import 'package:barback/barback.dart' show AssetId, TransformLogger;
7 import 'package:dart_style/dart_style.dart'; 7 import 'package:dart_style/dart_style.dart';
8 import 'package:path/path.dart' as path; 8 import 'package:path/path.dart' as path;
9 9
10 import 'annotation_processor.dart'; 10 import 'annotation_processor.dart';
11 11
12 /// Base class that maintains codegen state. 12 /// Base class that maintains codegen state.
13 class Context { 13 class Context {
14 final TransformLogger _logger; 14 final TransformLogger _logger;
15 /// Maps libraries to the import prefixes we will use in the newly 15 /// Maps libraries to the import prefixes we will use in the newly
16 /// generated code. 16 /// generated code.
17 final Map<LibraryElement, String> _libraryPrefixes; 17 final Map<LibraryElement, String> _libraryPrefixes;
18 18
19 DirectiveRegistry _directiveRegistry; 19 DirectiveRegistry _directiveRegistry;
20 /// Generates [registerType] calls for all [register]ed [AnnotationMatch]
21 /// objects.
20 DirectiveRegistry get directiveRegistry => _directiveRegistry; 22 DirectiveRegistry get directiveRegistry => _directiveRegistry;
21 23
22 Context({TransformLogger logger}) 24 Context({TransformLogger logger})
23 : _logger = logger, 25 : _logger = logger,
24 _libraryPrefixes = {} { 26 _libraryPrefixes = {} {
25 _directiveRegistry = new _DirectiveRegistryImpl(this); 27 _directiveRegistry = new _DirectiveRegistryImpl(this);
26 } 28 }
27 29
28 void error(String errorString) { 30 void error(String errorString) {
29 if (_logger != null) { 31 if (_logger == null) throw new Error(errorString);
30 _logger.error(errorString); 32 _logger.error(errorString);
31 } else {
32 throw new Error(errorString);
33 }
34 } 33 }
35 34
36 /// If elements in [lib] should be prefixed in our generated code, returns 35 /// If elements in [lib] should be prefixed in our generated code, returns
37 /// the appropriate prefix followed by a `.`. Future items from the same 36 /// the appropriate prefix followed by a `.`. Future items from the same
38 /// library will use the same prefix. 37 /// library will use the same prefix.
39 /// If [lib] does not need a prefix, returns the empty string. 38 /// If [lib] does not need a prefix, returns the empty string.
40 String _getPrefixDot(LibraryElement lib) { 39 String _getPrefixDot(LibraryElement lib) {
41 var prefix = lib != null && !lib.isInSdk 40 if (lib == null || lib.isInSdk) return '';
42 ? _libraryPrefixes.putIfAbsent(lib, () => 'i${_libraryPrefixes.length}') 41 var prefix =
43 : null; 42 _libraryPrefixes.putIfAbsent(lib, () => 'i${_libraryPrefixes.length}');
44 return prefix == null ? '' : '${prefix}.'; 43 return '${prefix}.';
45 } 44 }
46 } 45 }
47 46
47 /// Object which [register]s [AnnotationMatch] objects for code generation.
48 abstract class DirectiveRegistry { 48 abstract class DirectiveRegistry {
49 // Adds [entry] to the `registerType` calls which will be generated. 49 // Adds [entry] to the `registerType` calls which will be generated.
50 void register(AnnotationMatch entry); 50 void register(AnnotationMatch entry);
51 } 51 }
52 52
53 const _reflectorImport = 53 const _reflectorImport = '''
54 'import \'package:angular2/src/reflection/reflection.dart\' ' 54 import 'package:angular2/src/reflection/reflection.dart' show reflector;
55 'show reflector;'; 55 ''';
56 56
57 /// Default implementation to map from [LibraryElement] to [AssetId]. This 57 /// Default implementation to map from [LibraryElement] to [AssetId]. This
58 /// assumes that [el.source] has a getter called [assetId]. 58 /// assumes that [el.source] has a getter called [assetId].
59 AssetId _assetIdFromLibraryElement(LibraryElement el) { 59 AssetId _assetIdFromLibraryElement(LibraryElement el) {
60 return (el.source as dynamic).assetId; 60 return (el.source as dynamic).assetId;
61 } 61 }
62 62
63 String codegenEntryPoint(Context context, 63 String codegenEntryPoint(Context context,
64 {LibraryElement entryPoint, AssetId newEntryPoint}) { 64 {LibraryElement entryPoint, AssetId newEntryPoint}) {
65 // This must be called prior to [codegenImports] or the entry point 65 // This must be called prior to [codegenImports] or the entry point
(...skipping 29 matching lines...) Expand all
95 } else if (path.url.split(libraryId.path)[0] == 95 } else if (path.url.split(libraryId.path)[0] ==
96 path.url.split(entryPoint.path)[0]) { 96 path.url.split(entryPoint.path)[0]) {
97 var relativePath = 97 var relativePath =
98 path.relative(libraryId.path, from: path.dirname(entryPoint.path)); 98 path.relative(libraryId.path, from: path.dirname(entryPoint.path));
99 return "import '${relativePath}'"; 99 return "import '${relativePath}'";
100 } else { 100 } else {
101 context._error("Can't import `${libraryId}` from `${entryPoint}`"); 101 context._error("Can't import `${libraryId}` from `${entryPoint}`");
102 } 102 }
103 } 103 }
104 104
105 // TODO(https://github.com/kegluneq/angular/issues/4): Remove calls to
106 // Element#node.
105 class _DirectiveRegistryImpl implements DirectiveRegistry { 107 class _DirectiveRegistryImpl implements DirectiveRegistry {
106 final Context _context; 108 final Context _context;
107 final StringBuffer _buffer = new StringBuffer(); 109 final StringBuffer _buffer = new StringBuffer();
108 110
109 _DirectiveRegistryImpl(this._context); 111 _DirectiveRegistryImpl(this._context);
110 112
111 @override 113 @override
112 String toString() { 114 String toString() {
113 return _buffer.isEmpty ? '' : 'reflector${_buffer};'; 115 return _buffer.isEmpty ? '' : 'reflector${_buffer};';
114 } 116 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 192
191 /// Visitor providing common methods for concrete implementations. 193 /// Visitor providing common methods for concrete implementations.
192 abstract class _TransformVisitor extends ToSourceVisitor { 194 abstract class _TransformVisitor extends ToSourceVisitor {
193 final Context _context; 195 final Context _context;
194 final PrintWriter _writer; 196 final PrintWriter _writer;
195 197
196 _TransformVisitor(PrintWriter writer, this._context) 198 _TransformVisitor(PrintWriter writer, this._context)
197 : this._writer = writer, 199 : this._writer = writer,
198 super(writer); 200 super(writer);
199 201
200 /// Safely visit the given node. 202 /// Safely visit [node].
201 /// @param node the node to be visited
202 void _visitNode(AstNode node) { 203 void _visitNode(AstNode node) {
203 if (node != null) { 204 if (node != null) {
204 node.accept(this); 205 node.accept(this);
205 } 206 }
206 } 207 }
207 208
208 /** 209 /// If [node] is null does nothing. Otherwise, prints [prefix], then
209 * Safely visit the given node, printing the prefix before the node if it is n on-`null`. 210 /// visits [node].
210 *
211 * @param prefix the prefix to be printed if there is a node to visit
212 * @param node the node to be visited
213 */
214 void _visitNodeWithPrefix(String prefix, AstNode node) { 211 void _visitNodeWithPrefix(String prefix, AstNode node) {
215 if (node != null) { 212 if (node != null) {
216 _writer.print(prefix); 213 _writer.print(prefix);
217 node.accept(this); 214 node.accept(this);
218 } 215 }
219 } 216 }
220 217
221 /** 218 /// If [node] is null does nothing. Otherwise, visits [node], then prints
222 * Safely visit the given node, printing the suffix after the node if it is no n-`null`. 219 /// [suffix].
223 *
224 * @param suffix the suffix to be printed if there is a node to visit
225 * @param node the node to be visited
226 */
227 void _visitNodeWithSuffix(AstNode node, String suffix) { 220 void _visitNodeWithSuffix(AstNode node, String suffix) {
228 if (node != null) { 221 if (node != null) {
229 node.accept(this); 222 node.accept(this);
230 _writer.print(suffix); 223 _writer.print(suffix);
231 } 224 }
232 } 225 }
233 226
234 @override 227 @override
235 Object visitSimpleIdentifier(SimpleIdentifier node) { 228 Object visitSimpleIdentifier(SimpleIdentifier node) {
236 // Make sure the identifier is prefixed if necessary. 229 // Make sure the identifier is prefixed if necessary.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 @override 374 @override
382 Object visitAnnotation(Annotation node) { 375 Object visitAnnotation(Annotation node) {
383 _writer.print('const '); 376 _writer.print('const ');
384 _visitNode(node.name); 377 _visitNode(node.name);
385 // TODO(tjblasi): Do we need to handle named constructors for annotations? 378 // TODO(tjblasi): Do we need to handle named constructors for annotations?
386 // _visitNodeWithPrefix(".", node.constructorName); 379 // _visitNodeWithPrefix(".", node.constructorName);
387 _visitNode(node.arguments); 380 _visitNode(node.arguments);
388 return null; 381 return null;
389 } 382 }
390 } 383 }
OLDNEW
« no previous file with comments | « modules/angular2/src/transform/annotation_processor.dart ('k') | modules/angular2/src/transform/html_transform.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698