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

Side by Side Diff: pkg/intl/lib/extract_messages.dart

Issue 14998006: Add some user-friendly utility functions to pkg/analyzer_experimental. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 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 * This is for use in extracting messages from a Dart program 6 * This is for use in extracting messages from a Dart program
7 * using the Intl.message() mechanism and writing them to a file for 7 * using the Intl.message() mechanism and writing them to a file for
8 * translation. This provides only the stub of a mechanism, because it 8 * translation. This provides only the stub of a mechanism, because it
9 * doesn't define how the file should be written. It provides an 9 * doesn't define how the file should be written. It provides an
10 * [IntlMessage] class that holds the extracted data and [parseString] 10 * [IntlMessage] class that holds the extracted data and [parseString]
11 * and [parseFile] methods which 11 * and [parseFile] methods which
12 * can extract messages that conform to the expected pattern: 12 * can extract messages that conform to the expected pattern:
13 * (parameters) => Intl.message("Message $parameters", desc: ...); 13 * (parameters) => Intl.message("Message $parameters", desc: ...);
14 * It uses the analyzer_experimental package to do the parsing, so may 14 * It uses the analyzer_experimental package to do the parsing, so may
15 * break if there are changes to the API that it provides. 15 * break if there are changes to the API that it provides.
16 * An example can be found in test/message_extraction/extract_to_json.dart 16 * An example can be found in test/message_extraction/extract_to_json.dart
17 * 17 *
18 * Note that this does not understand how to follow part directives, so it 18 * Note that this does not understand how to follow part directives, so it
19 * has to explicitly be given all the files that it needs. A typical use case 19 * has to explicitly be given all the files that it needs. A typical use case
20 * is to run it on all .dart files in a directory. 20 * is to run it on all .dart files in a directory.
21 */ 21 */
22 library extract_messages; 22 library extract_messages;
23 23
24 import 'package:analyzer_experimental/src/generated/ast.dart';
25 import 'package:analyzer_experimental/src/generated/error.dart';
26 import 'package:analyzer_experimental/src/generated/java_core.dart';
27 import 'package:analyzer_experimental/src/generated/parser.dart';
28 import 'package:analyzer_experimental/src/generated/scanner.dart';
29 import 'package:analyzer_experimental/src/generated/source.dart';
30 import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
31 import 'dart:io'; 24 import 'dart:io';
25
26 import 'package:analyzer_experimental/analyzer.dart';
32 import 'package:intl/src/intl_message.dart'; 27 import 'package:intl/src/intl_message.dart';
33 28
34 /** 29 /**
35 * If this is true, print warnings for skipped messages. Otherwise, warnings 30 * If this is true, print warnings for skipped messages. Otherwise, warnings
36 * are suppressed. 31 * are suppressed.
37 */ 32 */
38 bool suppressWarnings = false; 33 bool suppressWarnings = false;
39 34
40 /** 35 /**
41 * Parse the dart program represented in [sourceCode] and return a Map from
42 * message names to [IntlMessage] instances. The [origin] is a string
43 * describing where the source came from, and is used in error messages.
44 */
45 Map<String, IntlMessage> parseString(String sourceCode, [String origin]) {
46 var errorListener = new _ErrorCollector();
47 var scanner = new StringScanner(null, sourceCode, errorListener);
48 var token = scanner.tokenize();
49 var parser = new Parser(null, errorListener);
50 var unit = parser.parseCompilationUnit(token);
51 unit.lineInfo = new LineInfo(scanner.lineStarts);
52
53 var visitor = new MessageFindingVisitor(unit, origin);
54 unit.accept(visitor);
55 for (var error in errorListener.errors) {
56 print(error);
57 }
58 return visitor.messages;
59 }
60
61 /**
62 * Parse the source of the Dart program file [file] and return a Map from 36 * Parse the source of the Dart program file [file] and return a Map from
63 * message names to [IntlMessage] instances. 37 * message names to [IntlMessage] instances.
64 */ 38 */
65 Map<String, IntlMessage> parseFile(File file) { 39 Map<String, IntlMessage> parseFile(File file) {
66 var sourceCode = file.readAsStringSync(); 40 var unit = parseDartFile(file.path);
67 return parseString(sourceCode, file.path); 41 var visitor = new MessageFindingVisitor(unit, file.path);
42 unit.accept(visitor);
43 return visitor.messages;
68 } 44 }
69 45
70 /** 46 /**
71 * An error handler for parsing. Error handling is currently very primitive.
72 */
73 class _ErrorCollector extends AnalysisErrorListener {
74 List<AnalysisError> errors;
75 _ErrorCollector() : errors = new List<AnalysisError>();
76 onError(error) => errors.add(error);
77 }
78
79 /**
80 * This visits the program source nodes looking for Intl.message uses 47 * This visits the program source nodes looking for Intl.message uses
81 * that conform to its pattern and then finding the 48 * that conform to its pattern and then finding the
82 */ 49 */
83 class MessageFindingVisitor extends GeneralizingASTVisitor { 50 class MessageFindingVisitor extends GeneralizingASTVisitor {
84 51
85 /** 52 /**
86 * The root of the compilation unit, and the first node we visit. We hold 53 * The root of the compilation unit, and the first node we visit. We hold
87 * on to this for error reporting, as it can give us line numbers of other 54 * on to this for error reporting, as it can give us line numbers of other
88 * nodes. 55 * nodes.
89 */ 56 */
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 */ 296 */
330 final String message; 297 final String message;
331 298
332 /** 299 /**
333 * Creates a new exception with an optional error [message]. 300 * Creates a new exception with an optional error [message].
334 */ 301 */
335 const IntlMessageExtractionException([this.message = ""]); 302 const IntlMessageExtractionException([this.message = ""]);
336 303
337 String toString() => "IntlMessageExtractionException: $message"; 304 String toString() => "IntlMessageExtractionException: $message";
338 } 305 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698