| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | |
| 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.md file. | |
| 4 | |
| 5 library fletchc.messages; | |
| 6 | |
| 7 import 'diagnostic.dart' show | |
| 8 Diagnostic, // For documentation only. | |
| 9 DiagnosticParameter; | |
| 10 | |
| 11 enum DiagnosticKind { | |
| 12 agentVersionMismatch, | |
| 13 busySession, | |
| 14 cantPerformVerbIn, | |
| 15 cantPerformVerbTo, | |
| 16 cantPerformVerbWith, | |
| 17 compilerVersionMismatch, | |
| 18 duplicatedIn, | |
| 19 duplicatedTo, | |
| 20 duplicatedWith, | |
| 21 expectedAPortNumber, | |
| 22 expectedTargetButGot, | |
| 23 extraArguments, | |
| 24 handShakeFailed, | |
| 25 illegalDefine, | |
| 26 internalError, | |
| 27 missingRequiredArgument, | |
| 28 missingSessionName, | |
| 29 missingToFile, | |
| 30 noAgentFound, | |
| 31 noFileTarget, | |
| 32 noSuchSession, | |
| 33 noTcpSocketTarget, | |
| 34 quitTakesNoArguments, | |
| 35 sessionAlreadyExists, | |
| 36 sessionInvalidState, | |
| 37 settingsCompileTimeConstantAsOption, | |
| 38 settingsConstantsNotAMap, | |
| 39 settingsDeviceAddressNotAString, | |
| 40 settingsDeviceTypeNotAString, | |
| 41 settingsDeviceTypeUnrecognized, | |
| 42 settingsIncrementalModeNotAString, | |
| 43 settingsIncrementalModeUnrecognized, | |
| 44 settingsNotAMap, | |
| 45 settingsNotJson, | |
| 46 settingsOptionNotAString, | |
| 47 settingsOptionsNotAList, | |
| 48 settingsPackagesNotAString, | |
| 49 settingsUnrecognizedConstantValue, | |
| 50 settingsUnrecognizedKey, | |
| 51 socketAgentConnectError, | |
| 52 socketAgentReplyError, | |
| 53 socketVmConnectError, | |
| 54 socketVmReplyError, | |
| 55 terminatedSession, | |
| 56 unexpectedArgument, | |
| 57 unknownAction, | |
| 58 unknownOption, | |
| 59 unsupportedPlatform, | |
| 60 upgradeInvalidPackageName, | |
| 61 verbDoesNotSupportTarget, | |
| 62 verbDoesntSupportTarget, | |
| 63 verbRequiresFileTarget, | |
| 64 verbRequiresNoSession, | |
| 65 verbRequiresNoToFile, | |
| 66 verbRequiresNoWithFile, | |
| 67 verbRequiresSessionTarget, | |
| 68 verbRequiresSocketTarget, | |
| 69 verbRequiresSpecificTarget, | |
| 70 verbRequiresSpecificTargetButGot, | |
| 71 verbRequiresTarget, | |
| 72 versionMismatch, | |
| 73 | |
| 74 // TODO(ahe): Remove when debug attach implicitly. | |
| 75 attachToVmBeforeRun, | |
| 76 | |
| 77 // TODO(ahe): Remove when debug compile implicitly. | |
| 78 compileBeforeRun, | |
| 79 } | |
| 80 | |
| 81 /// Returns the diagnostic message template for [kind]. A diagnostic message | |
| 82 /// should contain three pieces of information: | |
| 83 /// | |
| 84 /// 1. What is wrong? | |
| 85 /// 2. Why is it wrong? | |
| 86 /// 3. How do you fix it? | |
| 87 /// | |
| 88 /// Where appropriate, we follow the [Google design guidelines](https://www.goog
le.com/design/spec/style/writing.html) | |
| 89 /// for writing messages to the user. With respect to punctuation, we interpret | |
| 90 /// error messages as parallel labels, meaning they should use full sentences, | |
| 91 /// that is, starting with a capital letter and terminated with punctuation | |
| 92 /// (see [Capitalization & punctuation](https://www.google.com/design/spec/style
/writing.html#writing-capitalization-punctuation)). | |
| 93 /// | |
| 94 /// In addition, make sure to get a review from a UX expert before adding new | |
| 95 /// diagnostics, or when updating existing diagnostics. | |
| 96 /// | |
| 97 /// A diagnostic message template is a string which includes special markers | |
| 98 /// (`"#{parameterName}"`). To produce a human-readable error message, one can | |
| 99 /// use [Diagnostic.formatMessage]. | |
| 100 String getMessage(DiagnosticKind kind) { | |
| 101 // Implementation note: Instead of directly writing `"#{parameterName}"` in | |
| 102 // templates, use DiagnosticParameter to help reduce the chance of typos, and | |
| 103 // to ensure all diagnostics can be processed by a third-party. | |
| 104 | |
| 105 const DiagnosticParameter message = DiagnosticParameter.message; | |
| 106 const DiagnosticParameter verb = DiagnosticParameter.verb; | |
| 107 const DiagnosticParameter sessionName = DiagnosticParameter.sessionName; | |
| 108 const DiagnosticParameter target = DiagnosticParameter.target; | |
| 109 const DiagnosticParameter requiredTarget = DiagnosticParameter.requiredTarget; | |
| 110 const DiagnosticParameter userInput = DiagnosticParameter.userInput; | |
| 111 const DiagnosticParameter additionalUserInput = | |
| 112 DiagnosticParameter.additionalUserInput; | |
| 113 const DiagnosticParameter address = DiagnosticParameter.address; | |
| 114 const DiagnosticParameter preposition = DiagnosticParameter.preposition; | |
| 115 const DiagnosticParameter uri = DiagnosticParameter.uri; | |
| 116 const DiagnosticParameter fixit = DiagnosticParameter.fixit; | |
| 117 | |
| 118 switch (kind) { | |
| 119 case DiagnosticKind.internalError: | |
| 120 return "Internal error: $message"; | |
| 121 | |
| 122 case DiagnosticKind.verbRequiresNoSession: | |
| 123 return "Can't perform '$verb' in a session. " | |
| 124 "Try removing 'in session $sessionName'."; | |
| 125 | |
| 126 case DiagnosticKind.cantPerformVerbIn: | |
| 127 return "Can't perform '$verb' in '$target'."; | |
| 128 | |
| 129 case DiagnosticKind.cantPerformVerbTo: | |
| 130 return "Can't perform '$verb' to '$target'."; | |
| 131 | |
| 132 case DiagnosticKind.cantPerformVerbWith: | |
| 133 return "Can't perform '$verb' with '$target'."; | |
| 134 | |
| 135 case DiagnosticKind.verbRequiresSessionTarget: | |
| 136 return "Can't perform '$verb' without a session " | |
| 137 "target. Try adding 'session <SESSION_NAME>' to the commmand line."; | |
| 138 | |
| 139 case DiagnosticKind.verbRequiresFileTarget: | |
| 140 // TODO(ahe): Be more explicit about what is wrong with the target. | |
| 141 return "Can't perform '$verb' without a file, but got '$target', which " | |
| 142 "is not a file target. Try adding 'file' in front."; | |
| 143 | |
| 144 case DiagnosticKind.verbRequiresSocketTarget: | |
| 145 // TODO(ahe): Be more explicit about what is wrong with the target. | |
| 146 return "Can't perform '$verb' without a socket, but got '$target', " | |
| 147 "which is not a socket. Try adding 'tcp_socket' in front."; | |
| 148 | |
| 149 case DiagnosticKind.verbDoesNotSupportTarget: | |
| 150 return "'$verb' can't be performed on '$target'."; | |
| 151 | |
| 152 case DiagnosticKind.noSuchSession: | |
| 153 return "Couldn't find a session called '$sessionName'. " | |
| 154 "Try running 'fletch create session $sessionName'."; | |
| 155 | |
| 156 case DiagnosticKind.sessionAlreadyExists: | |
| 157 return "Couldn't create session named '$sessionName'; " | |
| 158 "A session called $sessionName already exists."; | |
| 159 | |
| 160 case DiagnosticKind.sessionInvalidState: | |
| 161 return "Session '$sessionName' not in a valid state; " | |
| 162 "Please stop attached vm, run 'fletch quit' and retry."; | |
| 163 | |
| 164 case DiagnosticKind.noFileTarget: | |
| 165 return "No file provided. Try adding <FILE_NAME> to the command line."; | |
| 166 | |
| 167 case DiagnosticKind.noTcpSocketTarget: | |
| 168 return "No TCP socket provided. " | |
| 169 "Try adding 'tcp_socket HOST:PORT' to the command line."; | |
| 170 | |
| 171 case DiagnosticKind.expectedAPortNumber: | |
| 172 return "Expected a port number, but got '$userInput'."; | |
| 173 | |
| 174 case DiagnosticKind.noAgentFound: | |
| 175 return "No agent found in this session."; | |
| 176 | |
| 177 case DiagnosticKind.upgradeInvalidPackageName: | |
| 178 return "A dartino-agent package must have a name of the form\n" | |
| 179 " dartino-agent_<version>_<platform>.deb.\n" | |
| 180 "Try renaming the file to match this pattern."; | |
| 181 | |
| 182 case DiagnosticKind.socketAgentConnectError: | |
| 183 return "Unable to establish connection to Dartino Agent on " | |
| 184 "$address: $message."; | |
| 185 | |
| 186 case DiagnosticKind.socketVmConnectError: | |
| 187 return | |
| 188 "Unable to establish connection to Fletch VM on $address: $message."; | |
| 189 | |
| 190 case DiagnosticKind.socketAgentReplyError: | |
| 191 return "Received invalid reply from Dartino Agent on $address: $message."; | |
| 192 | |
| 193 case DiagnosticKind.socketVmReplyError: | |
| 194 return "Received invalid reply from Fletch VM on $address: $message."; | |
| 195 | |
| 196 case DiagnosticKind.attachToVmBeforeRun: | |
| 197 return "Unable to run program without being attached to a VM. " | |
| 198 "Try running 'fletch attach'."; | |
| 199 | |
| 200 case DiagnosticKind.compileBeforeRun: | |
| 201 return "No program to run. Try running 'fletch compile'"; | |
| 202 | |
| 203 case DiagnosticKind.missingToFile: | |
| 204 return "No destination file provided. " | |
| 205 "Try adding 'to <FILE_NAME>' to the command line"; | |
| 206 | |
| 207 case DiagnosticKind.unknownOption: | |
| 208 // TODO(lukechurch): Review UX. | |
| 209 return "Unknown option: '$userInput'."; | |
| 210 | |
| 211 case DiagnosticKind.unsupportedPlatform: | |
| 212 // TODO(lukechurch): Review UX. | |
| 213 return "Unsupported platform: $message."; | |
| 214 | |
| 215 case DiagnosticKind.missingRequiredArgument: | |
| 216 // TODO(lukechurch): Consider a correction message. | |
| 217 return "Option '${DiagnosticParameter.userInput}' needs an argument."; | |
| 218 | |
| 219 case DiagnosticKind.missingSessionName: | |
| 220 // TODO(karlklose,ahe): provide support to list choices here. | |
| 221 return "Session name missing. Try adding a name after 'session'."; | |
| 222 | |
| 223 case DiagnosticKind.unexpectedArgument: | |
| 224 // TODO(lukechurch): Review UX | |
| 225 return "Option '${DiagnosticParameter.userInput}' doesn't take an " | |
| 226 "argument. Try removing '=' from the command line."; | |
| 227 | |
| 228 case DiagnosticKind.settingsNotAMap: | |
| 229 return "$uri: isn't a map."; | |
| 230 | |
| 231 case DiagnosticKind.settingsNotJson: | |
| 232 return "$uri: unable to decode as JSON: $message."; | |
| 233 | |
| 234 case DiagnosticKind.settingsPackagesNotAString: | |
| 235 return "$uri: 'packages' value '$userInput' isn't a String."; | |
| 236 | |
| 237 case DiagnosticKind.settingsOptionsNotAList: | |
| 238 return "$uri: 'options' value '$userInput' isn't a List."; | |
| 239 | |
| 240 case DiagnosticKind.settingsDeviceTypeNotAString: | |
| 241 return "$uri: 'device_type' value '$userInput' isn't a String."; | |
| 242 | |
| 243 case DiagnosticKind.settingsIncrementalModeNotAString: | |
| 244 return "$uri: 'incremental_mode' value '$userInput' isn't a String."; | |
| 245 | |
| 246 case DiagnosticKind.settingsOptionNotAString: | |
| 247 return "$uri: found 'options' entry '$userInput' which isn't a String."; | |
| 248 | |
| 249 case DiagnosticKind.settingsDeviceTypeNotAString: | |
| 250 return | |
| 251 "$uri: found 'device_type' entry '$userInput' which isn't a String."; | |
| 252 | |
| 253 case DiagnosticKind.settingsDeviceTypeUnrecognized: | |
| 254 return "$uri: found 'device_type' entry '$userInput' which is not one of " | |
| 255 "the recognized device types 'embedded', 'mobile'."; | |
| 256 | |
| 257 case DiagnosticKind.settingsIncrementalModeUnrecognized: | |
| 258 return "$uri: found 'incremental_mode' entry '$userInput' which is not " | |
| 259 "one of the recognized modes 'none', 'production', or " | |
| 260 "'experimental'."; | |
| 261 | |
| 262 case DiagnosticKind.settingsCompileTimeConstantAsOption: | |
| 263 return "$uri: compile-time constants should be in " | |
| 264 "the 'constants' map, not in 'options': '$userInput'."; | |
| 265 | |
| 266 case DiagnosticKind.settingsConstantsNotAMap: | |
| 267 return "$uri: 'constants' value isn't a Map"; | |
| 268 | |
| 269 case DiagnosticKind.settingsUnrecognizedConstantValue: | |
| 270 return "$uri: found 'constant[$userInput]' value '$additionalUserInput' " | |
| 271 "isn't a bool, int, or String."; | |
| 272 | |
| 273 case DiagnosticKind.settingsUnrecognizedKey: | |
| 274 return "$uri: unexpected key '$userInput'."; | |
| 275 | |
| 276 case DiagnosticKind.settingsDeviceAddressNotAString: | |
| 277 return "$uri: 'device_address' value '$userInput' isn't a String."; | |
| 278 | |
| 279 case DiagnosticKind.unknownAction: | |
| 280 return "'$userInput' isn't a supported action. " | |
| 281 "Try running 'fletch help'."; | |
| 282 | |
| 283 case DiagnosticKind.extraArguments: | |
| 284 return "Unrecognized arguments: $userInput."; | |
| 285 | |
| 286 case DiagnosticKind.duplicatedIn: | |
| 287 return "More than one 'in' clause: $preposition."; | |
| 288 | |
| 289 case DiagnosticKind.duplicatedTo: | |
| 290 // TODO(ahe): This is getting a bit tedious by now. We really need to | |
| 291 // figure out if we need to require exact prepostions. | |
| 292 return "More than one 'to' clause: $preposition."; | |
| 293 | |
| 294 case DiagnosticKind.duplicatedWith: | |
| 295 return "More than one 'with' clause: $preposition."; | |
| 296 | |
| 297 case DiagnosticKind.verbDoesntSupportTarget: | |
| 298 return "Can't perform '$verb' with '$target'."; | |
| 299 | |
| 300 case DiagnosticKind.verbRequiresNoToFile: | |
| 301 return "Can't perform '$verb' to '$userInput'."; | |
| 302 | |
| 303 case DiagnosticKind.verbRequiresNoWithFile: | |
| 304 return "Can't perform '$verb' with '$userInput'."; | |
| 305 | |
| 306 case DiagnosticKind.verbRequiresSpecificTarget: | |
| 307 return "Can't perform '$verb' without a '$requiredTarget'."; | |
| 308 | |
| 309 case DiagnosticKind.verbRequiresTarget: | |
| 310 return "Can't perform '$verb' without a target."; | |
| 311 | |
| 312 case DiagnosticKind.verbRequiresSpecificTargetButGot: | |
| 313 return "Can't perform '$verb' without a '$requiredTarget', " | |
| 314 "but got: '$target'."; | |
| 315 | |
| 316 case DiagnosticKind.expectedTargetButGot: | |
| 317 return "Expected 'session(s)', 'class(s)', 'method(s)', 'file(s)', " | |
| 318 "or 'all', but got: '$userInput'. Did you mean 'file $userInput'?"; | |
| 319 | |
| 320 case DiagnosticKind.quitTakesNoArguments: | |
| 321 return "Unexpected arguments. Try running 'fletch quit'."; | |
| 322 | |
| 323 case DiagnosticKind.busySession: | |
| 324 return "Session '$sessionName' is in use, please try again shortly."; | |
| 325 | |
| 326 case DiagnosticKind.terminatedSession: | |
| 327 return "Session '$sessionName' was terminated."; | |
| 328 | |
| 329 case DiagnosticKind.handShakeFailed: | |
| 330 // TODO(ager): lukechurch: Should this ever happen during normal usage? | |
| 331 // Should they report this to us as a bug? | |
| 332 return "Connection rejected because of invalid handshake reply from " | |
| 333 "VM on $address."; | |
| 334 | |
| 335 case DiagnosticKind.versionMismatch: | |
| 336 // TODO(ager): lukechurch: Is there advice we can give here? | |
| 337 // E.g. Consider upgrading your compiler? Do we have an easy place they | |
| 338 // can go to do that? Are we considering adding a tool to auto-upgrade? | |
| 339 return "Connection rejected because compiler and VM on $address " | |
| 340 "have different versions. Compiler version: '$userInput' " | |
| 341 "VM version: '$additionalUserInput'."; | |
| 342 | |
| 343 case DiagnosticKind.agentVersionMismatch: | |
| 344 // TODO(wibling): lukechurch: Is there advice we can give here? | |
| 345 // E.g. Consider upgrading your compiler? Do we have an easy place they | |
| 346 // can go to do that? Are we considering adding a tool to auto-upgrade? | |
| 347 return """ | |
| 348 Could not start vm on device because the compiler and the | |
| 349 session's remote device have different versions. | |
| 350 Compiler version: '$userInput' | |
| 351 Device version: '$additionalUserInput'. | |
| 352 $fixit"""; | |
| 353 | |
| 354 case DiagnosticKind.compilerVersionMismatch: | |
| 355 return "Command failed because the running compiler and the " | |
| 356 "Fletch Command Line Interface (CLI) have " | |
| 357 "different versions.\nCompiler version: '$userInput'\n" | |
| 358 "CLI version: '$additionalUserInput'.\n" | |
| 359 "This can happen if you have recently updated you Fletch SDK. " | |
| 360 "Try running 'fletch quit' and retry the command."; | |
| 361 | |
| 362 case DiagnosticKind.illegalDefine: | |
| 363 return "The define $userInput has an illegal value part: " | |
| 364 "$additionalUserInput."; | |
| 365 } | |
| 366 } | |
| OLD | NEW |