| OLD | NEW |
| 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] |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 import 'package:analyzer_experimental/src/generated/error.dart'; | 25 import 'package:analyzer_experimental/src/generated/error.dart'; |
| 26 import 'package:analyzer_experimental/src/generated/java_core.dart'; | 26 import 'package:analyzer_experimental/src/generated/java_core.dart'; |
| 27 import 'package:analyzer_experimental/src/generated/parser.dart'; | 27 import 'package:analyzer_experimental/src/generated/parser.dart'; |
| 28 import 'package:analyzer_experimental/src/generated/scanner.dart'; | 28 import 'package:analyzer_experimental/src/generated/scanner.dart'; |
| 29 import 'package:analyzer_experimental/src/generated/source.dart'; | 29 import 'package:analyzer_experimental/src/generated/source.dart'; |
| 30 import 'package:analyzer_experimental/src/generated/utilities_dart.dart'; | 30 import 'package:analyzer_experimental/src/generated/utilities_dart.dart'; |
| 31 import 'dart:io'; | 31 import 'dart:io'; |
| 32 import 'package:intl/src/intl_message.dart'; | 32 import 'package:intl/src/intl_message.dart'; |
| 33 | 33 |
| 34 /** | 34 /** |
| 35 * If this is true, print warnings for skipped messages. Otherwise, warnings |
| 36 * are suppressed. |
| 37 */ |
| 38 bool suppressWarnings = false; |
| 39 |
| 40 /** |
| 35 * Parse the dart program represented in [sourceCode] and return a Map from | 41 * Parse the dart program represented in [sourceCode] and return a Map from |
| 36 * message names to [IntlMessage] instances. The [origin] is a string | 42 * message names to [IntlMessage] instances. The [origin] is a string |
| 37 * describing where the source came from, and is used in error messages. | 43 * describing where the source came from, and is used in error messages. |
| 38 */ | 44 */ |
| 39 Map<String, IntlMessage> parseString(String sourceCode, [String origin]) { | 45 Map<String, IntlMessage> parseString(String sourceCode, [String origin]) { |
| 40 var errorListener = new _ErrorCollector(); | 46 var errorListener = new _ErrorCollector(); |
| 41 var scanner = new StringScanner(null, sourceCode, errorListener); | 47 var scanner = new StringScanner(null, sourceCode, errorListener); |
| 42 var token = scanner.tokenize(); | 48 var token = scanner.tokenize(); |
| 43 var parser = new Parser(null, errorListener); | 49 var parser = new Parser(null, errorListener); |
| 44 var unit = parser.parseCompilationUnit(token); | 50 var unit = parser.parseCompilationUnit(token); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 return super.visitNode(node); | 194 return super.visitNode(node); |
| 189 } | 195 } |
| 190 | 196 |
| 191 /** | 197 /** |
| 192 * Check that the node looks like an Intl.message invocation, and create | 198 * Check that the node looks like an Intl.message invocation, and create |
| 193 * the [IntlMessage] object from it and store it in [messages]. | 199 * the [IntlMessage] object from it and store it in [messages]. |
| 194 */ | 200 */ |
| 195 void addIntlMessage(MethodInvocation node) { | 201 void addIntlMessage(MethodInvocation node) { |
| 196 if (!looksLikeIntlMessage(node)) return; | 202 if (!looksLikeIntlMessage(node)) return; |
| 197 var reason = checkValidity(node); | 203 var reason = checkValidity(node); |
| 198 if (!(reason == null)) { | 204 if (reason != null && !suppressWarnings) { |
| 199 print("Skipping invalid Intl.message invocation\n <$node>"); | 205 print("Skipping invalid Intl.message invocation\n <$node>"); |
| 200 print(" reason: $reason"); | 206 print(" reason: $reason"); |
| 201 reportErrorLocation(node); | 207 reportErrorLocation(node); |
| 202 return; | 208 return; |
| 203 } | 209 } |
| 204 var message = messageFromMethodInvocation(node); | 210 var message = messageFromMethodInvocation(node); |
| 205 if (message != null) messages[message.name] = message; | 211 if (message != null) messages[message.name] = message; |
| 206 } | 212 } |
| 207 | 213 |
| 208 /** | 214 /** |
| 209 * Create an IntlMessage from [node] using the name and | 215 * Create an IntlMessage from [node] using the name and |
| 210 * parameters of the last function/method declaration we encountered | 216 * parameters of the last function/method declaration we encountered |
| 211 * and the parameters to the Intl.message call. | 217 * and the parameters to the Intl.message call. |
| 212 */ | 218 */ |
| 213 IntlMessage messageFromMethodInvocation(MethodInvocation node) { | 219 IntlMessage messageFromMethodInvocation(MethodInvocation node) { |
| 214 var message = new IntlMessage(); | 220 var message = new IntlMessage(); |
| 215 message.name = name; | 221 message.name = name; |
| 216 message.arguments = parameters.parameters.elements.map( | 222 message.arguments = parameters.parameters.elements.map( |
| 217 (x) => x.identifier.name).toList(); | 223 (x) => x.identifier.name).toList(); |
| 218 try { | 224 try { |
| 219 node.accept(new MessageVisitor(message)); | 225 node.accept(new MessageVisitor(message)); |
| 220 } on IntlMessageExtractionException catch (e) { | 226 } on IntlMessageExtractionException catch (e) { |
| 221 message = null; | 227 message = null; |
| 222 print("Error $e"); | 228 print("Error $e"); |
| 223 print("Processing <$node>"); | 229 print("Processing <$node>"); |
| 224 reportErrorLocation(node); | 230 reportErrorLocation(node); |
| 225 } | 231 } |
| 226 return message; | 232 return message; |
| 227 } | 233 } |
| 228 | 234 |
| 229 void reportErrorLocation(ASTNode node) { | 235 void reportErrorLocation(ASTNode node) { |
| 230 if (origin != null) print("from $origin"); | 236 if (origin != null) print(" from $origin"); |
| 231 LineInfo info = root.lineInfo; | 237 LineInfo info = root.lineInfo; |
| 232 if (info != null) { | 238 if (info != null) { |
| 233 LineInfo_Location line = info.getLocation(node.offset); | 239 LineInfo_Location line = info.getLocation(node.offset); |
| 234 print("line: ${line.lineNumber}, column: ${line.columnNumber}"); | 240 print(" line: ${line.lineNumber}, column: ${line.columnNumber}"); |
| 235 } | 241 } |
| 236 } | 242 } |
| 237 } | 243 } |
| 238 | 244 |
| 239 /** | 245 /** |
| 240 * Given a node that looks like an invocation of Intl.message, extract out | 246 * Given a node that looks like an invocation of Intl.message, extract out |
| 241 * the message and the parameters and store them in [target]. | 247 * the message and the parameters and store them in [target]. |
| 242 */ | 248 */ |
| 243 class MessageVisitor extends GeneralizingASTVisitor { | 249 class MessageVisitor extends GeneralizingASTVisitor { |
| 244 IntlMessage target; | 250 IntlMessage target; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 */ | 329 */ |
| 324 final String message; | 330 final String message; |
| 325 | 331 |
| 326 /** | 332 /** |
| 327 * Creates a new exception with an optional error [message]. | 333 * Creates a new exception with an optional error [message]. |
| 328 */ | 334 */ |
| 329 const IntlMessageExtractionException([this.message = ""]); | 335 const IntlMessageExtractionException([this.message = ""]); |
| 330 | 336 |
| 331 String toString() => "IntlMessageExtractionException: $message"; | 337 String toString() => "IntlMessageExtractionException: $message"; |
| 332 } | 338 } |
| OLD | NEW |