1 // Copyright (c) Microsoft. All rights reserved. 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 //----------------------------------------------------------------------- 4 // </copyright> 5 // <summary> Tool switch description class for DataDriven tasks. </summary> 6 //----------------------------------------------------------------------- 7 8 using System; 9 using System.Collections; 10 using System.Collections.Generic; 11 using System.Text; 12 using Microsoft.Build.Framework; 13 using Microsoft.Build.Shared; 14 15 namespace Microsoft.Build.Tasks.Xaml 16 { 17 /// <summary> 18 /// This enumeration specifies the different types for each switch in a tool 19 /// The types are used in the documentation 20 /// </summary> 21 public enum CommandLineToolSwitchType 22 { 23 /// <summary> 24 /// The boolean type has a boolean value, and there are types: one that can have a flag appended on the end 25 /// and one that can't 26 /// e.g. GlobalOptimizations = "true" would be /Og, and GlobalOptimizations="false" would be /Og-, but 27 /// WarnAsError = "true" would be /WX, while WarnAsError = "false" would be nothing. 28 /// </summary> 29 Boolean = 0, 30 31 /// <summary> 32 /// The integer switch is used for properties that have several different integer values, 33 /// and depending on the value the property is set to, appends an integer to the end 34 /// of a certain switch 35 /// e.g. WarningLevel = "0" is /W0, WarningLevel = "2" is /W2 36 /// </summary> 37 Integer = 1, 38 39 /// <summary> 40 /// The string switch is used for two kinds of properties. 41 /// The first is the kind that has multiple values, and has a different switch for each value 42 /// e.g. Optimization="disabled" is /Od, "Full" is /Ox 43 /// The second is the kind that has a literal string appended to the end of a switch. 44 /// This type is similar to the File type, but in this case, will never get quoted. 45 /// </summary> 46 String = 2, 47 48 /// <summary> 49 /// The stringarray switch is used for properties that may have more 50 /// than one string appended to the end of the switch 51 /// e.g. InjectPrecompiledHeaderReference = myfile is /Ylmyfile 52 /// </summary> 53 StringArray = 3, 54 55 /// <summary> 56 /// The ITaskItemArray type is used for properties that pass multiple files, but 57 /// want to keep the metadata. Otherwise, it is used in the same way as a StringArray type. 58 /// </summary> 59 ITaskItemArray = 4, 60 } 61 62 /// <summary> 63 /// The class CommandLineToolSwitch holds information about the properties 64 /// for each task 65 /// </summary> 66 public class CommandLineToolSwitch 67 { 68 #region Constant strings 69 70 /// <summary> 71 /// Boolean switch type 72 /// </summary> 73 private const string TypeBoolean = "CommandLineToolSwitchType.Boolean"; 74 75 /// <summary> 76 /// Integer switch type 77 /// </summary> 78 private const string TypeInteger = "CommandLineToolSwitchType.Integer"; 79 80 /// <summary> 81 /// ITaskItem switch type 82 /// </summary> 83 private const string TypeITaskItem = "CommandLineToolSwitchType.ITaskItem"; 84 85 /// <summary> 86 /// ITaskItemArray switch type. 87 /// </summary> 88 private const string TypeITaskItemArray = "CommandLineToolSwitchType.ITaskItemArray"; 89 90 /// <summary> 91 /// String array switch type. 92 /// </summary> 93 private const string TypeStringArray = "CommandLineToolSwitchType.StringArray"; 94 95 #endregion 96 97 /// <summary> 98 /// The name of the switch. 99 /// </summary> 100 private string _name = String.Empty; 101 102 /// <summary> 103 /// The switch type 104 /// </summary> 105 private CommandLineToolSwitchType _type; 106 107 /// <summary> 108 /// "true" if this should be emitted on the command line. 109 /// </summary> 110 private bool _includeInCommandLine; 111 112 /// <summary> 113 /// The suffix to use when the switch is false/negated. 114 /// </summary> 115 private string _falseSuffix = String.Empty; 116 117 /// <summary> 118 /// The suffix to use when the switch is true. 119 /// </summary> 120 private string _trueSuffix = String.Empty; 121 122 /// <summary> 123 /// The separator to use between the switch name and its parameters. 124 /// </summary> 125 private string _separator = String.Empty; 126 127 /// <summary> 128 /// The fallback parameter. 129 /// </summary> 130 private string _fallback = String.Empty; 131 132 /// <summary> 133 /// Flag indicating if the switch is required. 134 /// </summary> 135 private bool _required; 136 137 /// <summary> 138 /// Parents for the switch. 139 /// </summary> 140 private LinkedList<string> _parents = new LinkedList<string>(); 141 142 /// <summary> 143 /// Overrides for the switch. 144 /// </summary> 145 private LinkedList<KeyValuePair<string, string>> _overrides = new LinkedList<KeyValuePair<string, string>>(); 146 147 /// <summary> 148 /// Flag indicating if the switch is valid. 149 /// </summary> 150 private bool _isValid; 151 152 /// <summary> 153 /// Flag for boolean switches, indicating the switch is reversible. 154 /// </summary> 155 private bool _reversible; 156 157 /// <summary> 158 /// Flag indicating if the switch has multiple values. 159 /// </summary> 160 private bool _allowMultipleValues; 161 162 /// <summary> 163 /// The value for a boolean switch. 164 /// </summary> 165 private bool _booleanValue = true; 166 167 /// <summary> 168 /// The value for the integer type. 169 /// </summary> 170 private int _number; 171 172 /// <summary> 173 /// The list of strings for a string array. 174 /// </summary> 175 private string[] _stringList; 176 177 /// <summary> 178 /// The list of task items for ITaskItemArray types. 179 /// </summary> 180 private ITaskItem[] _taskItemArray; 181 182 /// <summary> 183 /// The value for a string type. 184 /// </summary> 185 private string _value = String.Empty; 186 187 /// <summary> 188 /// The switch text. 189 /// </summary> 190 private string _switchValue = String.Empty; 191 192 /// <summary> 193 /// The reverse switch text, for reversible switches. 194 /// </summary> 195 private string _reverseSwitchValue = String.Empty; 196 197 /// <summary> 198 /// The arguments from which the value should be derived. 199 /// </summary> 200 private ICollection<Tuple<string, bool>> _arguments; 201 202 /// <summary> 203 /// Thw switch description. 204 /// </summary> 205 private string _description = String.Empty; 206 207 /// <summary> 208 /// The display name for the switch. 209 /// </summary> 210 private string _displayName = String.Empty; 211 212 /// <summary> 213 /// The default constructor creates a new CommandLineToolSwitch to hold the name of 214 /// the tool, the attributes, the dependent switches, and the values (if they exist) 215 /// </summary> CommandLineToolSwitch()216 public CommandLineToolSwitch() 217 { 218 // does nothing 219 } 220 221 /// <summary> 222 /// Overloaded constructor. Takes a CommandLineToolSwitchType and sets the type. 223 /// </summary> CommandLineToolSwitch(CommandLineToolSwitchType toolType)224 public CommandLineToolSwitch(CommandLineToolSwitchType toolType) 225 { 226 _type = toolType; 227 } 228 229 #region Properties 230 231 /// <summary> 232 /// The name of the parameter 233 /// </summary> 234 public string Name 235 { 236 get 237 { 238 return _name; 239 } 240 241 set 242 { 243 _name = value; 244 } 245 } 246 247 /// <summary> 248 /// Specifies if this switch should be included on the command-line. 249 /// </summary> 250 public bool IncludeInCommandLine 251 { 252 get 253 { 254 return _includeInCommandLine; 255 } 256 257 set 258 { 259 _includeInCommandLine = value; 260 } 261 } 262 263 /// <summary> 264 /// The Value of the parameter 265 /// </summary> 266 public string Value 267 { 268 get 269 { 270 return _value; 271 } 272 273 set 274 { 275 _value = value; 276 } 277 } 278 279 /// <summary> 280 /// Flag indicating if the switch is valid. 281 /// </summary> 282 public bool IsValid 283 { 284 get 285 { 286 return _isValid; 287 } 288 289 set 290 { 291 _isValid = value; 292 } 293 } 294 295 /// <summary> 296 /// The SwitchValue of the parameter 297 /// </summary> 298 public string SwitchValue 299 { 300 get 301 { 302 return _switchValue; 303 } 304 305 set 306 { 307 _switchValue = value; 308 } 309 } 310 311 /// <summary> 312 /// The SwitchValue of the parameter 313 /// </summary> 314 public string ReverseSwitchValue 315 { 316 get 317 { 318 return _reverseSwitchValue; 319 } 320 321 set 322 { 323 _reverseSwitchValue = value; 324 } 325 } 326 327 /// <summary> 328 /// The arguments. 329 /// </summary> 330 public ICollection<Tuple<string, bool>> Arguments 331 { 332 get 333 { 334 return _arguments; 335 } 336 337 set 338 { 339 _arguments = value; 340 } 341 } 342 343 /// <summary> 344 /// The DisplayName of the parameter 345 /// </summary> 346 public string DisplayName 347 { 348 get 349 { 350 return _displayName; 351 } 352 353 set 354 { 355 _displayName = value; 356 } 357 } 358 359 /// <summary> 360 /// The Description of the parameter 361 /// </summary> 362 public string Description 363 { 364 get 365 { 366 return _description; 367 } 368 369 set 370 { 371 _description = value; 372 } 373 } 374 375 /// <summary> 376 /// The type of the switch, i.e., boolean, string, stringarray, etc. 377 /// </summary> 378 public CommandLineToolSwitchType Type 379 { 380 get 381 { 382 return _type; 383 } 384 385 set 386 { 387 _type = value; 388 } 389 } 390 391 /// <summary> 392 /// Indicates whether or not the switch is emitted with a flag when false 393 /// </summary> 394 public bool Reversible 395 { 396 get 397 { 398 return _reversible; 399 } 400 401 set 402 { 403 _reversible = value; 404 } 405 } 406 407 /// <summary> 408 /// True if multiple values are allowed. 409 /// </summary> 410 public bool AllowMultipleValues 411 { 412 get 413 { 414 return _allowMultipleValues; 415 } 416 417 set 418 { 419 _allowMultipleValues = value; 420 } 421 } 422 423 /// <summary> 424 /// The flag to append at the end of a switch when the switch is set to false 425 /// i.e., for all CL switches that are reversible, the FalseSuffix is "-" 426 /// </summary> 427 public string FalseSuffix 428 { 429 get 430 { 431 return _falseSuffix; 432 } 433 434 set 435 { 436 _falseSuffix = value; 437 } 438 } 439 440 /// <summary> 441 /// The flag to append to the end of the switch when that switch is true 442 /// i.e., In the OptimizeForWindows98, the switch is OPT, the FalseSuffix is 443 /// :NOWIN98, and the TrueSuffix is :WIN98 444 /// </summary> 445 public string TrueSuffix 446 { 447 get 448 { 449 return _trueSuffix; 450 } 451 452 set 453 { 454 _trueSuffix = value; 455 } 456 } 457 458 /// <summary> 459 /// The separator indicates the characters that go between the switch and the string 460 /// in the string typed case, the characters that go between each name for the 461 /// string array case, or the characters that go between the switch and the 462 /// appendage for the boolean case. 463 /// </summary> 464 public string Separator 465 { 466 get 467 { 468 return _separator; 469 } 470 471 set 472 { 473 _separator = value; 474 } 475 } 476 477 /// <summary> 478 /// The Fallback attribute is used to specify which property to look at in the 479 /// case that the argument property is not set, or if the file that the 480 /// argument property indicates is nonexistent. 481 /// </summary> 482 public string FallbackArgumentParameter 483 { 484 get 485 { 486 return _fallback; 487 } 488 489 set 490 { 491 _fallback = value; 492 } 493 } 494 495 /// <summary> 496 /// This attribute specifies whether or not an argument attribute is required. 497 /// </summary> 498 public bool ArgumentRequired 499 { 500 get; 501 set; 502 } 503 504 /// <summary> 505 /// This property indicates whether or not the property is required in the project file 506 /// </summary> 507 public bool Required 508 { 509 get 510 { 511 return _required; 512 } 513 514 set 515 { 516 _required = value; 517 } 518 } 519 520 /// <summary> 521 /// This property indicates the parent of the dependency 522 /// </summary> 523 public LinkedList<string> Parents 524 { 525 get 526 { 527 return _parents; 528 } 529 } 530 531 /// <summary> 532 /// This property indicates the parent of the dependency 533 /// </summary> 534 public LinkedList<KeyValuePair<string, string>> Overrides 535 { 536 get 537 { 538 return _overrides; 539 } 540 } 541 542 /// <summary> 543 /// The BooleanValue is used for the boolean switches, and are set to true 544 /// or false, depending on what you set it to. 545 /// </summary> 546 public bool BooleanValue 547 { 548 get 549 { 550 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.Boolean, "InvalidType", TypeBoolean); 551 return _booleanValue; 552 } 553 554 set 555 { 556 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.Boolean, "InvalidType", TypeBoolean); 557 _booleanValue = value; 558 } 559 } 560 561 /// <summary> 562 /// The number is the number you wish to append to the end of integer switches 563 /// </summary> 564 public int Number 565 { 566 get 567 { 568 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.Integer, "InvalidType", TypeInteger); 569 return _number; 570 } 571 572 set 573 { 574 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.Integer, "InvalidType", TypeInteger); 575 _number = value; 576 } 577 } 578 579 /// <summary> 580 /// Returns the set of inputs to a switch 581 /// </summary> 582 /// <returns></returns> 583 public string[] StringList 584 { 585 get 586 { 587 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.StringArray, "InvalidType", TypeStringArray); 588 return _stringList; 589 } 590 591 set 592 { 593 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.StringArray, "InvalidType", TypeStringArray); 594 _stringList = value; 595 } 596 } 597 598 /// <summary> 599 /// Returns the set of inputs to a switch that is a set of ITaskItems 600 /// </summary> 601 /// <returns></returns> 602 public ITaskItem[] TaskItemArray 603 { 604 get 605 { 606 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.ITaskItemArray, "InvalidType", TypeITaskItemArray); 607 return _taskItemArray; 608 } 609 610 set 611 { 612 ErrorUtilities.VerifyThrow(_type == CommandLineToolSwitchType.ITaskItemArray, "InvalidType", TypeITaskItemArray); 613 _taskItemArray = value; 614 } 615 } 616 #endregion 617 } 618 619 /// <summary> 620 /// Expresses a relationship between an argument and a property. 621 /// </summary> 622 public class PropertyRelation 623 { 624 /// <summary> 625 /// Constructor 626 /// </summary> PropertyRelation()627 public PropertyRelation() 628 { 629 } 630 631 /// <summary> 632 /// Constructor. 633 /// </summary> PropertyRelation(string argument, string value, bool required)634 public PropertyRelation(string argument, string value, bool required) 635 { 636 this.Argument = argument; 637 this.Value = value; 638 this.Required = required; 639 } 640 641 /// <summary> 642 /// The name of the argument 643 /// </summary> 644 public string Argument 645 { 646 get; 647 set; 648 } 649 650 /// <summary> 651 /// The value. 652 /// </summary> 653 public string Value 654 { 655 get; 656 set; 657 } 658 659 /// <summary> 660 /// Flag indicating if the argument is required or not. 661 /// </summary> 662 public bool Required 663 { 664 get; 665 set; 666 } 667 } 668 669 /// <summary> 670 /// Derived class indicating how to separate values from the specified argument. 671 /// </summary> 672 public class CommandLineArgumentRelation : PropertyRelation 673 { 674 /// <summary> 675 /// Constructor. 676 /// </summary> CommandLineArgumentRelation(string argument, string value, bool required, string separator)677 public CommandLineArgumentRelation(string argument, string value, bool required, string separator) 678 : base(argument, value, required) 679 { 680 this.Separator = separator; 681 } 682 683 /// <summary> 684 /// The separator. 685 /// </summary> 686 public string Separator 687 { 688 get; 689 set; 690 } 691 } 692 } 693