You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1999 lines
51 KiB

3 years ago
3 years ago
5 years ago
  1. // Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.ComponentModel;
  20. using System.Runtime.CompilerServices;
  21. using ICSharpCode.Decompiler.CSharp.OutputVisitor;
  22. namespace ICSharpCode.Decompiler
  23. {
  24. /// <summary>
  25. /// Settings for the decompiler.
  26. /// </summary>
  27. public class DecompilerSettings : INotifyPropertyChanged
  28. {
  29. /// <summary>
  30. /// Equivalent to <c>new DecompilerSettings(LanguageVersion.Latest)</c>
  31. /// </summary>
  32. public DecompilerSettings()
  33. {
  34. }
  35. /// <summary>
  36. /// Creates a new DecompilerSettings instance with initial settings
  37. /// appropriate for the specified language version.
  38. /// </summary>
  39. /// <remarks>
  40. /// This does not imply that the resulting code strictly uses only language features from
  41. /// that version. Language constructs like generics or ref locals cannot be removed from
  42. /// the compiled code.
  43. /// </remarks>
  44. public DecompilerSettings(CSharp.LanguageVersion languageVersion)
  45. {
  46. SetLanguageVersion(languageVersion);
  47. }
  48. /// <summary>
  49. /// Deactivates all language features from versions newer than <paramref name="languageVersion"/>.
  50. /// </summary>
  51. public void SetLanguageVersion(CSharp.LanguageVersion languageVersion)
  52. {
  53. // By default, all decompiler features are enabled.
  54. // Disable some of them based on language version:
  55. if (languageVersion < CSharp.LanguageVersion.CSharp2)
  56. {
  57. anonymousMethods = false;
  58. liftNullables = false;
  59. yieldReturn = false;
  60. useImplicitMethodGroupConversion = false;
  61. }
  62. if (languageVersion < CSharp.LanguageVersion.CSharp3)
  63. {
  64. anonymousTypes = false;
  65. useLambdaSyntax = false;
  66. objectCollectionInitializers = false;
  67. automaticProperties = false;
  68. extensionMethods = false;
  69. queryExpressions = false;
  70. expressionTrees = false;
  71. }
  72. if (languageVersion < CSharp.LanguageVersion.CSharp4)
  73. {
  74. dynamic = false;
  75. namedArguments = false;
  76. optionalArguments = false;
  77. }
  78. if (languageVersion < CSharp.LanguageVersion.CSharp5)
  79. {
  80. asyncAwait = false;
  81. }
  82. if (languageVersion < CSharp.LanguageVersion.CSharp6)
  83. {
  84. awaitInCatchFinally = false;
  85. useExpressionBodyForCalculatedGetterOnlyProperties = false;
  86. nullPropagation = false;
  87. stringInterpolation = false;
  88. dictionaryInitializers = false;
  89. extensionMethodsInCollectionInitializers = false;
  90. useRefLocalsForAccurateOrderOfEvaluation = false;
  91. getterOnlyAutomaticProperties = false;
  92. }
  93. if (languageVersion < CSharp.LanguageVersion.CSharp7)
  94. {
  95. outVariables = false;
  96. throwExpressions = false;
  97. tupleTypes = false;
  98. tupleConversions = false;
  99. discards = false;
  100. localFunctions = false;
  101. deconstruction = false;
  102. patternMatching = false;
  103. }
  104. if (languageVersion < CSharp.LanguageVersion.CSharp7_2)
  105. {
  106. introduceReadonlyAndInModifiers = false;
  107. introduceRefModifiersOnStructs = false;
  108. nonTrailingNamedArguments = false;
  109. refExtensionMethods = false;
  110. }
  111. if (languageVersion < CSharp.LanguageVersion.CSharp7_3)
  112. {
  113. introduceUnmanagedConstraint = false;
  114. stackAllocInitializers = false;
  115. tupleComparisons = false;
  116. patternBasedFixedStatement = false;
  117. }
  118. if (languageVersion < CSharp.LanguageVersion.CSharp8_0)
  119. {
  120. nullableReferenceTypes = false;
  121. readOnlyMethods = false;
  122. asyncUsingAndForEachStatement = false;
  123. asyncEnumerator = false;
  124. useEnhancedUsing = false;
  125. staticLocalFunctions = false;
  126. ranges = false;
  127. switchExpressions = false;
  128. }
  129. if (languageVersion < CSharp.LanguageVersion.CSharp9_0)
  130. {
  131. nativeIntegers = false;
  132. initAccessors = false;
  133. functionPointers = false;
  134. forEachWithGetEnumeratorExtension = false;
  135. recordClasses = false;
  136. withExpressions = false;
  137. usePrimaryConstructorSyntax = false;
  138. covariantReturns = false;
  139. }
  140. if (languageVersion < CSharp.LanguageVersion.CSharp10_0)
  141. {
  142. fileScopedNamespaces = false;
  143. recordStructs = false;
  144. }
  145. if (languageVersion < CSharp.LanguageVersion.CSharp11_0)
  146. {
  147. parameterNullCheck = false;
  148. lifetimeAnnotations = false;
  149. requiredMembers = false;
  150. }
  151. }
  152. public CSharp.LanguageVersion GetMinimumRequiredVersion()
  153. {
  154. if (parameterNullCheck || lifetimeAnnotations || requiredMembers)
  155. return CSharp.LanguageVersion.CSharp11_0;
  156. if (fileScopedNamespaces || recordStructs)
  157. return CSharp.LanguageVersion.CSharp10_0;
  158. if (nativeIntegers || initAccessors || functionPointers || forEachWithGetEnumeratorExtension
  159. || recordClasses || withExpressions || usePrimaryConstructorSyntax || covariantReturns)
  160. return CSharp.LanguageVersion.CSharp9_0;
  161. if (nullableReferenceTypes || readOnlyMethods || asyncEnumerator || asyncUsingAndForEachStatement
  162. || staticLocalFunctions || ranges || switchExpressions)
  163. return CSharp.LanguageVersion.CSharp8_0;
  164. if (introduceUnmanagedConstraint || tupleComparisons || stackAllocInitializers
  165. || patternBasedFixedStatement)
  166. return CSharp.LanguageVersion.CSharp7_3;
  167. if (introduceRefModifiersOnStructs || introduceReadonlyAndInModifiers
  168. || nonTrailingNamedArguments || refExtensionMethods)
  169. return CSharp.LanguageVersion.CSharp7_2;
  170. // C# 7.1 missing
  171. if (outVariables || throwExpressions || tupleTypes || tupleConversions
  172. || discards || localFunctions || deconstruction || patternMatching)
  173. return CSharp.LanguageVersion.CSharp7;
  174. if (awaitInCatchFinally || useExpressionBodyForCalculatedGetterOnlyProperties || nullPropagation
  175. || stringInterpolation || dictionaryInitializers || extensionMethodsInCollectionInitializers
  176. || useRefLocalsForAccurateOrderOfEvaluation || getterOnlyAutomaticProperties)
  177. return CSharp.LanguageVersion.CSharp6;
  178. if (asyncAwait)
  179. return CSharp.LanguageVersion.CSharp5;
  180. if (dynamic || namedArguments || optionalArguments)
  181. return CSharp.LanguageVersion.CSharp4;
  182. if (anonymousTypes || objectCollectionInitializers || automaticProperties
  183. || queryExpressions || expressionTrees)
  184. return CSharp.LanguageVersion.CSharp3;
  185. if (anonymousMethods || liftNullables || yieldReturn || useImplicitMethodGroupConversion)
  186. return CSharp.LanguageVersion.CSharp2;
  187. return CSharp.LanguageVersion.CSharp1;
  188. }
  189. bool nativeIntegers = true;
  190. /// <summary>
  191. /// Use C# 9 <c>nint</c>/<c>nuint</c> types.
  192. /// </summary>
  193. [Category("C# 9.0 / VS 2019.8")]
  194. [Description("DecompilerSettings.NativeIntegers")]
  195. public bool NativeIntegers {
  196. get { return nativeIntegers; }
  197. set {
  198. if (nativeIntegers != value)
  199. {
  200. nativeIntegers = value;
  201. OnPropertyChanged();
  202. }
  203. }
  204. }
  205. bool covariantReturns = true;
  206. /// <summary>
  207. /// Decompile C# 9 covariant return types.
  208. /// </summary>
  209. [Category("C# 9.0 / VS 2019.8")]
  210. [Description("DecompilerSettings.CovariantReturns")]
  211. public bool CovariantReturns {
  212. get { return covariantReturns; }
  213. set {
  214. if (covariantReturns != value)
  215. {
  216. covariantReturns = value;
  217. OnPropertyChanged();
  218. }
  219. }
  220. }
  221. bool initAccessors = true;
  222. /// <summary>
  223. /// Use C# 9 <c>init;</c> property accessors.
  224. /// </summary>
  225. [Category("C# 9.0 / VS 2019.8")]
  226. [Description("DecompilerSettings.InitAccessors")]
  227. public bool InitAccessors {
  228. get { return initAccessors; }
  229. set {
  230. if (initAccessors != value)
  231. {
  232. initAccessors = value;
  233. OnPropertyChanged();
  234. }
  235. }
  236. }
  237. bool recordClasses = true;
  238. /// <summary>
  239. /// Use C# 9 <c>record</c> classes.
  240. /// </summary>
  241. [Category("C# 9.0 / VS 2019.8")]
  242. [Description("DecompilerSettings.RecordClasses")]
  243. public bool RecordClasses {
  244. get { return recordClasses; }
  245. set {
  246. if (recordClasses != value)
  247. {
  248. recordClasses = value;
  249. OnPropertyChanged();
  250. }
  251. }
  252. }
  253. bool recordStructs = true;
  254. /// <summary>
  255. /// Use C# 10 <c>record</c> structs.
  256. /// </summary>
  257. [Category("C# 10.0 / VS 2022")]
  258. [Description("DecompilerSettings.RecordStructs")]
  259. public bool RecordStructs {
  260. get { return recordStructs; }
  261. set {
  262. if (recordStructs != value)
  263. {
  264. recordStructs = value;
  265. OnPropertyChanged();
  266. }
  267. }
  268. }
  269. bool withExpressions = true;
  270. /// <summary>
  271. /// Use C# 9 <c>with</c> initializer expressions.
  272. /// </summary>
  273. [Category("C# 9.0 / VS 2019.8")]
  274. [Description("DecompilerSettings.WithExpressions")]
  275. public bool WithExpressions {
  276. get { return withExpressions; }
  277. set {
  278. if (withExpressions != value)
  279. {
  280. withExpressions = value;
  281. OnPropertyChanged();
  282. }
  283. }
  284. }
  285. bool usePrimaryConstructorSyntax = true;
  286. /// <summary>
  287. /// Use primary constructor syntax with records.
  288. /// </summary>
  289. [Category("C# 9.0 / VS 2019.8")]
  290. [Description("DecompilerSettings.UsePrimaryConstructorSyntax")]
  291. public bool UsePrimaryConstructorSyntax {
  292. get { return usePrimaryConstructorSyntax; }
  293. set {
  294. if (usePrimaryConstructorSyntax != value)
  295. {
  296. usePrimaryConstructorSyntax = value;
  297. OnPropertyChanged();
  298. }
  299. }
  300. }
  301. bool functionPointers = true;
  302. /// <summary>
  303. /// Use C# 9 <c>delegate* unmanaged</c> types.
  304. /// If this option is disabled, function pointers will instead be decompiled with type `IntPtr`.
  305. /// </summary>
  306. [Category("C# 9.0 / VS 2019.8")]
  307. [Description("DecompilerSettings.FunctionPointers")]
  308. public bool FunctionPointers {
  309. get { return functionPointers; }
  310. set {
  311. if (functionPointers != value)
  312. {
  313. functionPointers = value;
  314. OnPropertyChanged();
  315. }
  316. }
  317. }
  318. bool lifetimeAnnotations = true;
  319. /// <summary>
  320. /// Use C# 9 <c>delegate* unmanaged</c> types.
  321. /// If this option is disabled, function pointers will instead be decompiled with type `IntPtr`.
  322. /// </summary>
  323. [Category("C# 11.0 / VS 2022.4")]
  324. [Description("DecompilerSettings.LifetimeAnnotations")]
  325. public bool LifetimeAnnotations {
  326. get { return lifetimeAnnotations; }
  327. set {
  328. if (lifetimeAnnotations != value)
  329. {
  330. lifetimeAnnotations = value;
  331. OnPropertyChanged();
  332. }
  333. }
  334. }
  335. bool requiredMembers = true;
  336. /// <summary>
  337. /// Use C# 11 <c>required</c> modifier.
  338. /// </summary>
  339. [Category("C# 11.0 / VS 2022.4")]
  340. [Description("DecompilerSettings.RequiredMembers")]
  341. public bool RequiredMembers {
  342. get { return requiredMembers; }
  343. set {
  344. if (requiredMembers != value)
  345. {
  346. requiredMembers = value;
  347. OnPropertyChanged();
  348. }
  349. }
  350. }
  351. bool switchExpressions = true;
  352. /// <summary>
  353. /// Use C# 8 switch expressions.
  354. /// </summary>
  355. [Category("C# 8.0 / VS 2019")]
  356. [Description("DecompilerSettings.SwitchExpressions")]
  357. public bool SwitchExpressions {
  358. get { return switchExpressions; }
  359. set {
  360. if (switchExpressions != value)
  361. {
  362. switchExpressions = value;
  363. OnPropertyChanged();
  364. }
  365. }
  366. }
  367. bool fileScopedNamespaces = true;
  368. /// <summary>
  369. /// Use C# 10 file-scoped namespaces.
  370. /// </summary>
  371. [Category("C# 10.0 / VS 2022")]
  372. [Description("DecompilerSettings.FileScopedNamespaces")]
  373. public bool FileScopedNamespaces {
  374. get { return fileScopedNamespaces; }
  375. set {
  376. if (fileScopedNamespaces != value)
  377. {
  378. fileScopedNamespaces = value;
  379. OnPropertyChanged();
  380. }
  381. }
  382. }
  383. bool parameterNullCheck = false;
  384. /// <summary>
  385. /// Use C# 11 preview parameter null-checking (<code>string param!!</code>).
  386. /// </summary>
  387. [Category("C# 11.0 / VS 2022.1")]
  388. [Description("DecompilerSettings.ParameterNullCheck")]
  389. [Browsable(false)]
  390. public bool ParameterNullCheck {
  391. get { return parameterNullCheck; }
  392. set {
  393. if (parameterNullCheck != value)
  394. {
  395. parameterNullCheck = value;
  396. OnPropertyChanged();
  397. }
  398. }
  399. }
  400. bool anonymousMethods = true;
  401. /// <summary>
  402. /// Decompile anonymous methods/lambdas.
  403. /// </summary>
  404. [Category("C# 2.0 / VS 2005")]
  405. [Description("DecompilerSettings.DecompileAnonymousMethodsLambdas")]
  406. public bool AnonymousMethods {
  407. get { return anonymousMethods; }
  408. set {
  409. if (anonymousMethods != value)
  410. {
  411. anonymousMethods = value;
  412. OnPropertyChanged();
  413. }
  414. }
  415. }
  416. bool anonymousTypes = true;
  417. /// <summary>
  418. /// Decompile anonymous types.
  419. /// </summary>
  420. [Category("C# 3.0 / VS 2008")]
  421. [Description("DecompilerSettings.DecompileAnonymousTypes")]
  422. public bool AnonymousTypes {
  423. get { return anonymousTypes; }
  424. set {
  425. if (anonymousTypes != value)
  426. {
  427. anonymousTypes = value;
  428. OnPropertyChanged();
  429. }
  430. }
  431. }
  432. bool useLambdaSyntax = true;
  433. /// <summary>
  434. /// Use C# 3 lambda syntax if possible.
  435. /// </summary>
  436. [Category("C# 3.0 / VS 2008")]
  437. [Description("DecompilerSettings.UseLambdaSyntaxIfPossible")]
  438. public bool UseLambdaSyntax {
  439. get { return useLambdaSyntax; }
  440. set {
  441. if (useLambdaSyntax != value)
  442. {
  443. useLambdaSyntax = value;
  444. OnPropertyChanged();
  445. }
  446. }
  447. }
  448. bool expressionTrees = true;
  449. /// <summary>
  450. /// Decompile expression trees.
  451. /// </summary>
  452. [Category("C# 3.0 / VS 2008")]
  453. [Description("DecompilerSettings.DecompileExpressionTrees")]
  454. public bool ExpressionTrees {
  455. get { return expressionTrees; }
  456. set {
  457. if (expressionTrees != value)
  458. {
  459. expressionTrees = value;
  460. OnPropertyChanged();
  461. }
  462. }
  463. }
  464. bool yieldReturn = true;
  465. /// <summary>
  466. /// Decompile enumerators.
  467. /// </summary>
  468. [Category("C# 2.0 / VS 2005")]
  469. [Description("DecompilerSettings.DecompileEnumeratorsYieldReturn")]
  470. public bool YieldReturn {
  471. get { return yieldReturn; }
  472. set {
  473. if (yieldReturn != value)
  474. {
  475. yieldReturn = value;
  476. OnPropertyChanged();
  477. }
  478. }
  479. }
  480. bool dynamic = true;
  481. /// <summary>
  482. /// Decompile use of the 'dynamic' type.
  483. /// </summary>
  484. [Category("C# 4.0 / VS 2010")]
  485. [Description("DecompilerSettings.DecompileUseOfTheDynamicType")]
  486. public bool Dynamic {
  487. get { return dynamic; }
  488. set {
  489. if (dynamic != value)
  490. {
  491. dynamic = value;
  492. OnPropertyChanged();
  493. }
  494. }
  495. }
  496. bool asyncAwait = true;
  497. /// <summary>
  498. /// Decompile async methods.
  499. /// </summary>
  500. [Category("C# 5.0 / VS 2012")]
  501. [Description("DecompilerSettings.DecompileAsyncMethods")]
  502. public bool AsyncAwait {
  503. get { return asyncAwait; }
  504. set {
  505. if (asyncAwait != value)
  506. {
  507. asyncAwait = value;
  508. OnPropertyChanged();
  509. }
  510. }
  511. }
  512. bool awaitInCatchFinally = true;
  513. /// <summary>
  514. /// Decompile await in catch/finally blocks.
  515. /// Only has an effect if <see cref="AsyncAwait"/> is enabled.
  516. /// </summary>
  517. [Category("C# 6.0 / VS 2015")]
  518. [Description("DecompilerSettings.DecompileAwaitInCatchFinallyBlocks")]
  519. public bool AwaitInCatchFinally {
  520. get { return awaitInCatchFinally; }
  521. set {
  522. if (awaitInCatchFinally != value)
  523. {
  524. awaitInCatchFinally = value;
  525. OnPropertyChanged();
  526. }
  527. }
  528. }
  529. bool asyncEnumerator = true;
  530. /// <summary>
  531. /// Decompile IAsyncEnumerator/IAsyncEnumerable.
  532. /// Only has an effect if <see cref="AsyncAwait"/> is enabled.
  533. /// </summary>
  534. [Category("C# 8.0 / VS 2019")]
  535. [Description("DecompilerSettings.AsyncEnumerator")]
  536. public bool AsyncEnumerator {
  537. get { return asyncEnumerator; }
  538. set {
  539. if (asyncEnumerator != value)
  540. {
  541. asyncEnumerator = value;
  542. OnPropertyChanged();
  543. }
  544. }
  545. }
  546. bool decimalConstants = true;
  547. /// <summary>
  548. /// Decompile [DecimalConstant(...)] as simple literal values.
  549. /// </summary>
  550. [Category("C# 1.0 / VS .NET")]
  551. [Description("DecompilerSettings.DecompileDecimalConstantAsSimpleLiteralValues")]
  552. public bool DecimalConstants {
  553. get { return decimalConstants; }
  554. set {
  555. if (decimalConstants != value)
  556. {
  557. decimalConstants = value;
  558. OnPropertyChanged();
  559. }
  560. }
  561. }
  562. bool fixedBuffers = true;
  563. /// <summary>
  564. /// Decompile C# 1.0 'public unsafe fixed int arr[10];' members.
  565. /// </summary>
  566. [Category("C# 1.0 / VS .NET")]
  567. [Description("DecompilerSettings.DecompileC10PublicUnsafeFixedIntArr10Members")]
  568. public bool FixedBuffers {
  569. get { return fixedBuffers; }
  570. set {
  571. if (fixedBuffers != value)
  572. {
  573. fixedBuffers = value;
  574. OnPropertyChanged();
  575. }
  576. }
  577. }
  578. bool stringConcat = true;
  579. /// <summary>
  580. /// Decompile 'string.Concat(a, b)' calls into 'a + b'.
  581. /// </summary>
  582. [Category("C# 1.0 / VS .NET")]
  583. [Description("DecompilerSettings.StringConcat")]
  584. public bool StringConcat {
  585. get { return stringConcat; }
  586. set {
  587. if (stringConcat != value)
  588. {
  589. stringConcat = value;
  590. OnPropertyChanged();
  591. }
  592. }
  593. }
  594. bool liftNullables = true;
  595. /// <summary>
  596. /// Use lifted operators for nullables.
  597. /// </summary>
  598. [Category("C# 2.0 / VS 2005")]
  599. [Description("DecompilerSettings.UseLiftedOperatorsForNullables")]
  600. public bool LiftNullables {
  601. get { return liftNullables; }
  602. set {
  603. if (liftNullables != value)
  604. {
  605. liftNullables = value;
  606. OnPropertyChanged();
  607. }
  608. }
  609. }
  610. bool nullPropagation = true;
  611. /// <summary>
  612. /// Decompile C# 6 ?. and ?[] operators.
  613. /// </summary>
  614. [Category("C# 6.0 / VS 2015")]
  615. [Description("DecompilerSettings.NullPropagation")]
  616. public bool NullPropagation {
  617. get { return nullPropagation; }
  618. set {
  619. if (nullPropagation != value)
  620. {
  621. nullPropagation = value;
  622. OnPropertyChanged();
  623. }
  624. }
  625. }
  626. bool automaticProperties = true;
  627. /// <summary>
  628. /// Decompile automatic properties
  629. /// </summary>
  630. [Category("C# 3.0 / VS 2008")]
  631. [Description("DecompilerSettings.DecompileAutomaticProperties")]
  632. public bool AutomaticProperties {
  633. get { return automaticProperties; }
  634. set {
  635. if (automaticProperties != value)
  636. {
  637. automaticProperties = value;
  638. OnPropertyChanged();
  639. }
  640. }
  641. }
  642. bool getterOnlyAutomaticProperties = true;
  643. /// <summary>
  644. /// Decompile getter-only automatic properties
  645. /// </summary>
  646. [Category("C# 6.0 / VS 2015")]
  647. [Description("DecompilerSettings.GetterOnlyAutomaticProperties")]
  648. public bool GetterOnlyAutomaticProperties {
  649. get { return getterOnlyAutomaticProperties; }
  650. set {
  651. if (getterOnlyAutomaticProperties != value)
  652. {
  653. getterOnlyAutomaticProperties = value;
  654. OnPropertyChanged();
  655. }
  656. }
  657. }
  658. bool automaticEvents = true;
  659. /// <summary>
  660. /// Decompile automatic events
  661. /// </summary>
  662. [Category("C# 1.0 / VS .NET")]
  663. [Description("DecompilerSettings.DecompileAutomaticEvents")]
  664. public bool AutomaticEvents {
  665. get { return automaticEvents; }
  666. set {
  667. if (automaticEvents != value)
  668. {
  669. automaticEvents = value;
  670. OnPropertyChanged();
  671. }
  672. }
  673. }
  674. bool usingStatement = true;
  675. /// <summary>
  676. /// Decompile using statements.
  677. /// </summary>
  678. [Category("C# 1.0 / VS .NET")]
  679. [Description("DecompilerSettings.DetectUsingStatements")]
  680. public bool UsingStatement {
  681. get { return usingStatement; }
  682. set {
  683. if (usingStatement != value)
  684. {
  685. usingStatement = value;
  686. OnPropertyChanged();
  687. }
  688. }
  689. }
  690. bool useEnhancedUsing = true;
  691. /// <summary>
  692. /// Use enhanced using statements.
  693. /// </summary>
  694. [Category("C# 8.0 / VS 2019")]
  695. [Description("DecompilerSettings.UseEnhancedUsing")]
  696. public bool UseEnhancedUsing {
  697. get { return useEnhancedUsing; }
  698. set {
  699. if (useEnhancedUsing != value)
  700. {
  701. useEnhancedUsing = value;
  702. OnPropertyChanged();
  703. }
  704. }
  705. }
  706. bool alwaysUseBraces = true;
  707. /// <summary>
  708. /// Gets/Sets whether to use braces for single-statement-blocks.
  709. /// </summary>
  710. [Category("DecompilerSettings.Other")]
  711. [Description("DecompilerSettings.AlwaysUseBraces")]
  712. public bool AlwaysUseBraces {
  713. get { return alwaysUseBraces; }
  714. set {
  715. if (alwaysUseBraces != value)
  716. {
  717. alwaysUseBraces = value;
  718. OnPropertyChanged();
  719. }
  720. }
  721. }
  722. bool forEachStatement = true;
  723. /// <summary>
  724. /// Decompile foreach statements.
  725. /// </summary>
  726. [Category("C# 1.0 / VS .NET")]
  727. [Description("DecompilerSettings.DetectForeachStatements")]
  728. public bool ForEachStatement {
  729. get { return forEachStatement; }
  730. set {
  731. if (forEachStatement != value)
  732. {
  733. forEachStatement = value;
  734. OnPropertyChanged();
  735. }
  736. }
  737. }
  738. bool forEachWithGetEnumeratorExtension = true;
  739. /// <summary>
  740. /// Support GetEnumerator extension methods in foreach.
  741. /// </summary>
  742. [Category("C# 9.0 / VS 2019.8")]
  743. [Description("DecompilerSettings.DecompileForEachWithGetEnumeratorExtension")]
  744. public bool ForEachWithGetEnumeratorExtension {
  745. get { return forEachWithGetEnumeratorExtension; }
  746. set {
  747. if (forEachWithGetEnumeratorExtension != value)
  748. {
  749. forEachWithGetEnumeratorExtension = value;
  750. OnPropertyChanged();
  751. }
  752. }
  753. }
  754. bool lockStatement = true;
  755. /// <summary>
  756. /// Decompile lock statements.
  757. /// </summary>
  758. [Category("C# 1.0 / VS .NET")]
  759. [Description("DecompilerSettings.DetectLockStatements")]
  760. public bool LockStatement {
  761. get { return lockStatement; }
  762. set {
  763. if (lockStatement != value)
  764. {
  765. lockStatement = value;
  766. OnPropertyChanged();
  767. }
  768. }
  769. }
  770. bool switchStatementOnString = true;
  771. [Category("C# 1.0 / VS .NET")]
  772. [Description("DecompilerSettings.DetectSwitchOnString")]
  773. public bool SwitchStatementOnString {
  774. get { return switchStatementOnString; }
  775. set {
  776. if (switchStatementOnString != value)
  777. {
  778. switchStatementOnString = value;
  779. OnPropertyChanged();
  780. }
  781. }
  782. }
  783. bool sparseIntegerSwitch = true;
  784. [Category("C# 1.0 / VS .NET")]
  785. [Description("DecompilerSettings.SparseIntegerSwitch")]
  786. public bool SparseIntegerSwitch {
  787. get { return sparseIntegerSwitch; }
  788. set {
  789. if (sparseIntegerSwitch != value)
  790. {
  791. sparseIntegerSwitch = value;
  792. OnPropertyChanged();
  793. }
  794. }
  795. }
  796. bool usingDeclarations = true;
  797. [Category("C# 1.0 / VS .NET")]
  798. [Description("DecompilerSettings.InsertUsingDeclarations")]
  799. public bool UsingDeclarations {
  800. get { return usingDeclarations; }
  801. set {
  802. if (usingDeclarations != value)
  803. {
  804. usingDeclarations = value;
  805. OnPropertyChanged();
  806. }
  807. }
  808. }
  809. bool extensionMethods = true;
  810. [Category("C# 3.0 / VS 2008")]
  811. [Description("DecompilerSettings.UseExtensionMethodSyntax")]
  812. public bool ExtensionMethods {
  813. get { return extensionMethods; }
  814. set {
  815. if (extensionMethods != value)
  816. {
  817. extensionMethods = value;
  818. OnPropertyChanged();
  819. }
  820. }
  821. }
  822. bool queryExpressions = true;
  823. [Category("C# 3.0 / VS 2008")]
  824. [Description("DecompilerSettings.UseLINQExpressionSyntax")]
  825. public bool QueryExpressions {
  826. get { return queryExpressions; }
  827. set {
  828. if (queryExpressions != value)
  829. {
  830. queryExpressions = value;
  831. OnPropertyChanged();
  832. }
  833. }
  834. }
  835. bool useImplicitMethodGroupConversion = true;
  836. /// <summary>
  837. /// Gets/Sets whether to use C# 2.0 method group conversions.
  838. /// true: <c>EventHandler h = this.OnClick;</c>
  839. /// false: <c>EventHandler h = new EventHandler(this.OnClick);</c>
  840. /// </summary>
  841. [Category("C# 2.0 / VS 2005")]
  842. [Description("DecompilerSettings.UseImplicitMethodGroupConversions")]
  843. public bool UseImplicitMethodGroupConversion {
  844. get { return useImplicitMethodGroupConversion; }
  845. set {
  846. if (useImplicitMethodGroupConversion != value)
  847. {
  848. useImplicitMethodGroupConversion = value;
  849. OnPropertyChanged();
  850. }
  851. }
  852. }
  853. bool alwaysCastTargetsOfExplicitInterfaceImplementationCalls = false;
  854. /// <summary>
  855. /// Gets/Sets whether to always cast targets to explicitly implemented methods.
  856. /// true: <c>((ISupportInitialize)pictureBox1).BeginInit();</c>
  857. /// false: <c>pictureBox1.BeginInit();</c>
  858. /// default: false
  859. /// </summary>
  860. [Category("Other")]
  861. [Description("DecompilerSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls")]
  862. public bool AlwaysCastTargetsOfExplicitInterfaceImplementationCalls {
  863. get { return alwaysCastTargetsOfExplicitInterfaceImplementationCalls; }
  864. set {
  865. if (alwaysCastTargetsOfExplicitInterfaceImplementationCalls != value)
  866. {
  867. alwaysCastTargetsOfExplicitInterfaceImplementationCalls = value;
  868. OnPropertyChanged();
  869. }
  870. }
  871. }
  872. bool alwaysQualifyMemberReferences = false;
  873. /// <summary>
  874. /// Gets/Sets whether to always qualify member references.
  875. /// true: <c>this.DoSomething();</c>
  876. /// false: <c>DoSomething();</c>
  877. /// default: false
  878. /// </summary>
  879. [Category("Other")]
  880. [Description("DecompilerSettings.AlwaysQualifyMemberReferences")]
  881. public bool AlwaysQualifyMemberReferences {
  882. get { return alwaysQualifyMemberReferences; }
  883. set {
  884. if (alwaysQualifyMemberReferences != value)
  885. {
  886. alwaysQualifyMemberReferences = value;
  887. OnPropertyChanged();
  888. }
  889. }
  890. }
  891. bool alwaysShowEnumMemberValues = false;
  892. /// <summary>
  893. /// Gets/Sets whether to always show enum member values.
  894. /// true: <c>enum Kind { A = 0, B = 1, C = 5 }</c>
  895. /// false: <c>enum Kind { A, B, C = 5 }</c>
  896. /// default: false
  897. /// </summary>
  898. [Category("Other")]
  899. [Description("DecompilerSettings.AlwaysShowEnumMemberValues")]
  900. public bool AlwaysShowEnumMemberValues {
  901. get { return alwaysShowEnumMemberValues; }
  902. set {
  903. if (alwaysShowEnumMemberValues != value)
  904. {
  905. alwaysShowEnumMemberValues = value;
  906. OnPropertyChanged();
  907. }
  908. }
  909. }
  910. bool useDebugSymbols = true;
  911. /// <summary>
  912. /// Gets/Sets whether to use variable names from debug symbols, if available.
  913. /// </summary>
  914. [Category("Other")]
  915. [Description("DecompilerSettings.UseVariableNamesFromDebugSymbolsIfAvailable")]
  916. public bool UseDebugSymbols {
  917. get { return useDebugSymbols; }
  918. set {
  919. if (useDebugSymbols != value)
  920. {
  921. useDebugSymbols = value;
  922. OnPropertyChanged();
  923. }
  924. }
  925. }
  926. bool arrayInitializers = true;
  927. /// <summary>
  928. /// Gets/Sets whether to use array initializers.
  929. /// If set to false, might produce non-compilable code.
  930. /// </summary>
  931. [Category("C# 1.0 / VS .NET")]
  932. [Description("DecompilerSettings.ArrayInitializerExpressions")]
  933. public bool ArrayInitializers {
  934. get { return arrayInitializers; }
  935. set {
  936. if (arrayInitializers != value)
  937. {
  938. arrayInitializers = value;
  939. OnPropertyChanged();
  940. }
  941. }
  942. }
  943. bool objectCollectionInitializers = true;
  944. /// <summary>
  945. /// Gets/Sets whether to use C# 3.0 object/collection initializers.
  946. /// </summary>
  947. [Category("C# 3.0 / VS 2008")]
  948. [Description("DecompilerSettings.ObjectCollectionInitializerExpressions")]
  949. public bool ObjectOrCollectionInitializers {
  950. get { return objectCollectionInitializers; }
  951. set {
  952. if (objectCollectionInitializers != value)
  953. {
  954. objectCollectionInitializers = value;
  955. OnPropertyChanged();
  956. }
  957. }
  958. }
  959. bool dictionaryInitializers = true;
  960. /// <summary>
  961. /// Gets/Sets whether to use C# 6.0 dictionary initializers.
  962. /// Only has an effect if ObjectOrCollectionInitializers is enabled.
  963. /// </summary>
  964. [Category("C# 6.0 / VS 2015")]
  965. [Description("DecompilerSettings.DictionaryInitializerExpressions")]
  966. public bool DictionaryInitializers {
  967. get { return dictionaryInitializers; }
  968. set {
  969. if (dictionaryInitializers != value)
  970. {
  971. dictionaryInitializers = value;
  972. OnPropertyChanged();
  973. }
  974. }
  975. }
  976. bool extensionMethodsInCollectionInitializers = true;
  977. /// <summary>
  978. /// Gets/Sets whether to use C# 6.0 Extension Add methods in collection initializers.
  979. /// Only has an effect if ObjectOrCollectionInitializers is enabled.
  980. /// </summary>
  981. [Category("C# 6.0 / VS 2015")]
  982. [Description("DecompilerSettings.AllowExtensionAddMethodsInCollectionInitializerExpressions")]
  983. public bool ExtensionMethodsInCollectionInitializers {
  984. get { return extensionMethodsInCollectionInitializers; }
  985. set {
  986. if (extensionMethodsInCollectionInitializers != value)
  987. {
  988. extensionMethodsInCollectionInitializers = value;
  989. OnPropertyChanged();
  990. }
  991. }
  992. }
  993. bool useRefLocalsForAccurateOrderOfEvaluation = true;
  994. /// <summary>
  995. /// Gets/Sets whether to use local ref variables in cases where this is necessary
  996. /// for re-compilation with a modern C# compiler to reproduce the same behavior
  997. /// as the original assembly produced with an old C# compiler that used an incorrect
  998. /// order of evaluation.
  999. /// See https://github.com/icsharpcode/ILSpy/issues/2050
  1000. /// </summary>
  1001. [Category("C# 6.0 / VS 2015")]
  1002. [Description("DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation")]
  1003. public bool UseRefLocalsForAccurateOrderOfEvaluation {
  1004. get { return useRefLocalsForAccurateOrderOfEvaluation; }
  1005. set {
  1006. if (useRefLocalsForAccurateOrderOfEvaluation != value)
  1007. {
  1008. useRefLocalsForAccurateOrderOfEvaluation = value;
  1009. OnPropertyChanged();
  1010. }
  1011. }
  1012. }
  1013. bool refExtensionMethods = true;
  1014. /// <summary>
  1015. /// Gets/Sets whether to use C# 7.2 'ref' extension methods.
  1016. /// </summary>
  1017. [Category("C# 7.2 / VS 2017.4")]
  1018. [Description("DecompilerSettings.AllowExtensionMethodSyntaxOnRef")]
  1019. public bool RefExtensionMethods {
  1020. get { return refExtensionMethods; }
  1021. set {
  1022. if (refExtensionMethods != value)
  1023. {
  1024. refExtensionMethods = value;
  1025. OnPropertyChanged();
  1026. }
  1027. }
  1028. }
  1029. bool stringInterpolation = true;
  1030. /// <summary>
  1031. /// Gets/Sets whether to use C# 6.0 string interpolation
  1032. /// </summary>
  1033. [Category("C# 6.0 / VS 2015")]
  1034. [Description("DecompilerSettings.UseStringInterpolation")]
  1035. public bool StringInterpolation {
  1036. get { return stringInterpolation; }
  1037. set {
  1038. if (stringInterpolation != value)
  1039. {
  1040. stringInterpolation = value;
  1041. OnPropertyChanged();
  1042. }
  1043. }
  1044. }
  1045. bool showXmlDocumentation = true;
  1046. /// <summary>
  1047. /// Gets/Sets whether to include XML documentation comments in the decompiled code.
  1048. /// </summary>
  1049. [Category("DecompilerSettings.Other")]
  1050. [Description("DecompilerSettings.IncludeXMLDocumentationCommentsInTheDecompiledCode")]
  1051. public bool ShowXmlDocumentation {
  1052. get { return showXmlDocumentation; }
  1053. set {
  1054. if (showXmlDocumentation != value)
  1055. {
  1056. showXmlDocumentation = value;
  1057. OnPropertyChanged();
  1058. }
  1059. }
  1060. }
  1061. bool foldBraces = false;
  1062. [Browsable(false)]
  1063. public bool FoldBraces {
  1064. get { return foldBraces; }
  1065. set {
  1066. if (foldBraces != value)
  1067. {
  1068. foldBraces = value;
  1069. OnPropertyChanged();
  1070. }
  1071. }
  1072. }
  1073. bool expandMemberDefinitions = false;
  1074. [Browsable(false)]
  1075. public bool ExpandMemberDefinitions {
  1076. get { return expandMemberDefinitions; }
  1077. set {
  1078. if (expandMemberDefinitions != value)
  1079. {
  1080. expandMemberDefinitions = value;
  1081. OnPropertyChanged();
  1082. }
  1083. }
  1084. }
  1085. bool expandUsingDeclarations = false;
  1086. [Browsable(false)]
  1087. public bool ExpandUsingDeclarations {
  1088. get { return expandUsingDeclarations; }
  1089. set {
  1090. if (expandUsingDeclarations != value)
  1091. {
  1092. expandUsingDeclarations = value;
  1093. OnPropertyChanged();
  1094. }
  1095. }
  1096. }
  1097. bool decompileMemberBodies = true;
  1098. /// <summary>
  1099. /// Gets/Sets whether member bodies should be decompiled.
  1100. /// </summary>
  1101. [Category("DecompilerSettings.Other")]
  1102. [Browsable(false)]
  1103. public bool DecompileMemberBodies {
  1104. get { return decompileMemberBodies; }
  1105. set {
  1106. if (decompileMemberBodies != value)
  1107. {
  1108. decompileMemberBodies = value;
  1109. OnPropertyChanged();
  1110. }
  1111. }
  1112. }
  1113. bool useExpressionBodyForCalculatedGetterOnlyProperties = true;
  1114. /// <summary>
  1115. /// Gets/Sets whether simple calculated getter-only property declarations
  1116. /// should use expression body syntax.
  1117. /// </summary>
  1118. [Category("C# 6.0 / VS 2015")]
  1119. [Description("DecompilerSettings.UseExpressionBodiedMemberSyntaxForGetOnlyProperties")]
  1120. public bool UseExpressionBodyForCalculatedGetterOnlyProperties {
  1121. get { return useExpressionBodyForCalculatedGetterOnlyProperties; }
  1122. set {
  1123. if (useExpressionBodyForCalculatedGetterOnlyProperties != value)
  1124. {
  1125. useExpressionBodyForCalculatedGetterOnlyProperties = value;
  1126. OnPropertyChanged();
  1127. }
  1128. }
  1129. }
  1130. bool outVariables = true;
  1131. /// <summary>
  1132. /// Gets/Sets whether out variable declarations should be used when possible.
  1133. /// </summary>
  1134. [Category("C# 7.0 / VS 2017")]
  1135. [Description("DecompilerSettings.UseOutVariableDeclarations")]
  1136. public bool OutVariables {
  1137. get { return outVariables; }
  1138. set {
  1139. if (outVariables != value)
  1140. {
  1141. outVariables = value;
  1142. OnPropertyChanged();
  1143. }
  1144. }
  1145. }
  1146. bool discards = true;
  1147. /// <summary>
  1148. /// Gets/Sets whether discards should be used when possible.
  1149. /// Only has an effect if <see cref="OutVariables"/> is enabled.
  1150. /// </summary>
  1151. [Category("C# 7.0 / VS 2017")]
  1152. [Description("DecompilerSettings.UseDiscards")]
  1153. public bool Discards {
  1154. get { return discards; }
  1155. set {
  1156. if (discards != value)
  1157. {
  1158. discards = value;
  1159. OnPropertyChanged();
  1160. }
  1161. }
  1162. }
  1163. bool introduceRefModifiersOnStructs = true;
  1164. /// <summary>
  1165. /// Gets/Sets whether IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs.
  1166. /// </summary>
  1167. [Category("C# 7.2 / VS 2017.4")]
  1168. [Description("DecompilerSettings.IsByRefLikeAttributeShouldBeReplacedWithRefModifiersOnStructs")]
  1169. public bool IntroduceRefModifiersOnStructs {
  1170. get { return introduceRefModifiersOnStructs; }
  1171. set {
  1172. if (introduceRefModifiersOnStructs != value)
  1173. {
  1174. introduceRefModifiersOnStructs = value;
  1175. OnPropertyChanged();
  1176. }
  1177. }
  1178. }
  1179. bool introduceReadonlyAndInModifiers = true;
  1180. /// <summary>
  1181. /// Gets/Sets whether IsReadOnlyAttribute should be replaced with 'readonly' modifiers on structs
  1182. /// and with the 'in' modifier on parameters.
  1183. /// </summary>
  1184. [Category("C# 7.2 / VS 2017.4")]
  1185. [Description("DecompilerSettings." +
  1186. "IsReadOnlyAttributeShouldBeReplacedWithReadonlyInModifiersOnStructsParameters")]
  1187. public bool IntroduceReadonlyAndInModifiers {
  1188. get { return introduceReadonlyAndInModifiers; }
  1189. set {
  1190. if (introduceReadonlyAndInModifiers != value)
  1191. {
  1192. introduceReadonlyAndInModifiers = value;
  1193. OnPropertyChanged();
  1194. }
  1195. }
  1196. }
  1197. bool readOnlyMethods = true;
  1198. [Category("C# 8.0 / VS 2019")]
  1199. [Description("DecompilerSettings.ReadOnlyMethods")]
  1200. public bool ReadOnlyMethods {
  1201. get { return readOnlyMethods; }
  1202. set {
  1203. if (readOnlyMethods != value)
  1204. {
  1205. readOnlyMethods = value;
  1206. OnPropertyChanged();
  1207. }
  1208. }
  1209. }
  1210. bool asyncUsingAndForEachStatement = true;
  1211. [Category("C# 8.0 / VS 2019")]
  1212. [Description("DecompilerSettings.DetectAsyncUsingAndForeachStatements")]
  1213. public bool AsyncUsingAndForEachStatement {
  1214. get { return asyncUsingAndForEachStatement; }
  1215. set {
  1216. if (asyncUsingAndForEachStatement != value)
  1217. {
  1218. asyncUsingAndForEachStatement = value;
  1219. OnPropertyChanged();
  1220. }
  1221. }
  1222. }
  1223. bool introduceUnmanagedConstraint = true;
  1224. /// <summary>
  1225. /// If this option is active, [IsUnmanagedAttribute] on type parameters
  1226. /// is replaced with "T : unmanaged" constraints.
  1227. /// </summary>
  1228. [Category("C# 7.3 / VS 2017.7")]
  1229. [Description("DecompilerSettings." +
  1230. "IsUnmanagedAttributeOnTypeParametersShouldBeReplacedWithUnmanagedConstraints")]
  1231. public bool IntroduceUnmanagedConstraint {
  1232. get { return introduceUnmanagedConstraint; }
  1233. set {
  1234. if (introduceUnmanagedConstraint != value)
  1235. {
  1236. introduceUnmanagedConstraint = value;
  1237. OnPropertyChanged();
  1238. }
  1239. }
  1240. }
  1241. bool stackAllocInitializers = true;
  1242. /// <summary>
  1243. /// Gets/Sets whether C# 7.3 stackalloc initializers should be used.
  1244. /// </summary>
  1245. [Category("C# 7.3 / VS 2017.7")]
  1246. [Description("DecompilerSettings.UseStackallocInitializerSyntax")]
  1247. public bool StackAllocInitializers {
  1248. get { return stackAllocInitializers; }
  1249. set {
  1250. if (stackAllocInitializers != value)
  1251. {
  1252. stackAllocInitializers = value;
  1253. OnPropertyChanged();
  1254. }
  1255. }
  1256. }
  1257. bool patternBasedFixedStatement = true;
  1258. /// <summary>
  1259. /// Gets/Sets whether C# 7.3 pattern based fixed statement should be used.
  1260. /// </summary>
  1261. [Category("C# 7.3 / VS 2017.7")]
  1262. [Description("DecompilerSettings.UsePatternBasedFixedStatement")]
  1263. public bool PatternBasedFixedStatement {
  1264. get { return patternBasedFixedStatement; }
  1265. set {
  1266. if (patternBasedFixedStatement != value)
  1267. {
  1268. patternBasedFixedStatement = value;
  1269. OnPropertyChanged();
  1270. }
  1271. }
  1272. }
  1273. bool tupleTypes = true;
  1274. /// <summary>
  1275. /// Gets/Sets whether tuple type syntax <c>(int, string)</c>
  1276. /// should be used for <c>System.ValueTuple</c>.
  1277. /// </summary>
  1278. [Category("C# 7.0 / VS 2017")]
  1279. [Description("DecompilerSettings.UseTupleTypeSyntax")]
  1280. public bool TupleTypes {
  1281. get { return tupleTypes; }
  1282. set {
  1283. if (tupleTypes != value)
  1284. {
  1285. tupleTypes = value;
  1286. OnPropertyChanged();
  1287. }
  1288. }
  1289. }
  1290. bool throwExpressions = true;
  1291. /// <summary>
  1292. /// Gets/Sets whether throw expressions should be used.
  1293. /// </summary>
  1294. [Category("C# 7.0 / VS 2017")]
  1295. [Description("DecompilerSettings.UseThrowExpressions")]
  1296. public bool ThrowExpressions {
  1297. get { return throwExpressions; }
  1298. set {
  1299. if (throwExpressions != value)
  1300. {
  1301. throwExpressions = value;
  1302. OnPropertyChanged();
  1303. }
  1304. }
  1305. }
  1306. bool tupleConversions = true;
  1307. /// <summary>
  1308. /// Gets/Sets whether implicit conversions between tuples
  1309. /// should be used in the decompiled output.
  1310. /// </summary>
  1311. [Category("C# 7.0 / VS 2017")]
  1312. [Description("DecompilerSettings.UseImplicitConversionsBetweenTupleTypes")]
  1313. public bool TupleConversions {
  1314. get { return tupleConversions; }
  1315. set {
  1316. if (tupleConversions != value)
  1317. {
  1318. tupleConversions = value;
  1319. OnPropertyChanged();
  1320. }
  1321. }
  1322. }
  1323. bool tupleComparisons = true;
  1324. /// <summary>
  1325. /// Gets/Sets whether tuple comparisons should be detected.
  1326. /// </summary>
  1327. [Category("C# 7.3 / VS 2017.7")]
  1328. [Description("DecompilerSettings.DetectTupleComparisons")]
  1329. public bool TupleComparisons {
  1330. get { return tupleComparisons; }
  1331. set {
  1332. if (tupleComparisons != value)
  1333. {
  1334. tupleComparisons = value;
  1335. OnPropertyChanged();
  1336. }
  1337. }
  1338. }
  1339. bool namedArguments = true;
  1340. /// <summary>
  1341. /// Gets/Sets whether named arguments should be used.
  1342. /// </summary>
  1343. [Category("C# 4.0 / VS 2010")]
  1344. [Description("DecompilerSettings.UseNamedArguments")]
  1345. public bool NamedArguments {
  1346. get { return namedArguments; }
  1347. set {
  1348. if (namedArguments != value)
  1349. {
  1350. namedArguments = value;
  1351. OnPropertyChanged();
  1352. }
  1353. }
  1354. }
  1355. bool nonTrailingNamedArguments = true;
  1356. /// <summary>
  1357. /// Gets/Sets whether C# 7.2 non-trailing named arguments should be used.
  1358. /// </summary>
  1359. [Category("C# 7.2 / VS 2017.4")]
  1360. [Description("DecompilerSettings.UseNonTrailingNamedArguments")]
  1361. public bool NonTrailingNamedArguments {
  1362. get { return nonTrailingNamedArguments; }
  1363. set {
  1364. if (nonTrailingNamedArguments != value)
  1365. {
  1366. nonTrailingNamedArguments = value;
  1367. OnPropertyChanged();
  1368. }
  1369. }
  1370. }
  1371. bool optionalArguments = true;
  1372. /// <summary>
  1373. /// Gets/Sets whether optional arguments should be removed, if possible.
  1374. /// </summary>
  1375. [Category("C# 4.0 / VS 2010")]
  1376. [Description("DecompilerSettings.RemoveOptionalArgumentsIfPossible")]
  1377. public bool OptionalArguments {
  1378. get { return optionalArguments; }
  1379. set {
  1380. if (optionalArguments != value)
  1381. {
  1382. optionalArguments = value;
  1383. OnPropertyChanged();
  1384. }
  1385. }
  1386. }
  1387. bool localFunctions = true;
  1388. /// <summary>
  1389. /// Gets/Sets whether C# 7.0 local functions should be transformed.
  1390. /// </summary>
  1391. [Category("C# 7.0 / VS 2017")]
  1392. [Description("DecompilerSettings.IntroduceLocalFunctions")]
  1393. public bool LocalFunctions {
  1394. get { return localFunctions; }
  1395. set {
  1396. if (localFunctions != value)
  1397. {
  1398. localFunctions = value;
  1399. OnPropertyChanged();
  1400. }
  1401. }
  1402. }
  1403. bool deconstruction = true;
  1404. /// <summary>
  1405. /// Gets/Sets whether C# 7.0 deconstruction should be detected.
  1406. /// </summary>
  1407. [Category("C# 7.0 / VS 2017")]
  1408. [Description("DecompilerSettings.Deconstruction")]
  1409. public bool Deconstruction {
  1410. get { return deconstruction; }
  1411. set {
  1412. if (deconstruction != value)
  1413. {
  1414. deconstruction = value;
  1415. OnPropertyChanged();
  1416. }
  1417. }
  1418. }
  1419. bool patternMatching = true;
  1420. /// <summary>
  1421. /// Gets/Sets whether C# 7.0 pattern matching should be detected.
  1422. /// </summary>
  1423. [Category("C# 7.0 / VS 2017")]
  1424. [Description("DecompilerSettings.PatternMatching")]
  1425. public bool PatternMatching {
  1426. get { return patternMatching; }
  1427. set {
  1428. if (patternMatching != value)
  1429. {
  1430. patternMatching = value;
  1431. OnPropertyChanged();
  1432. }
  1433. }
  1434. }
  1435. bool staticLocalFunctions = true;
  1436. /// <summary>
  1437. /// Gets/Sets whether C# 8.0 static local functions should be transformed.
  1438. /// </summary>
  1439. [Category("C# 8.0 / VS 2019")]
  1440. [Description("DecompilerSettings.IntroduceStaticLocalFunctions")]
  1441. public bool StaticLocalFunctions {
  1442. get { return staticLocalFunctions; }
  1443. set {
  1444. if (staticLocalFunctions != value)
  1445. {
  1446. staticLocalFunctions = value;
  1447. OnPropertyChanged();
  1448. }
  1449. }
  1450. }
  1451. bool ranges = true;
  1452. /// <summary>
  1453. /// Gets/Sets whether C# 8.0 index and range syntax should be used.
  1454. /// </summary>
  1455. [Category("C# 8.0 / VS 2019")]
  1456. [Description("DecompilerSettings.Ranges")]
  1457. public bool Ranges {
  1458. get { return ranges; }
  1459. set {
  1460. if (ranges != value)
  1461. {
  1462. ranges = value;
  1463. OnPropertyChanged();
  1464. }
  1465. }
  1466. }
  1467. bool nullableReferenceTypes = true;
  1468. /// <summary>
  1469. /// Gets/Sets whether C# 8.0 nullable reference types are enabled.
  1470. /// </summary>
  1471. [Category("C# 8.0 / VS 2019")]
  1472. [Description("DecompilerSettings.NullableReferenceTypes")]
  1473. public bool NullableReferenceTypes {
  1474. get { return nullableReferenceTypes; }
  1475. set {
  1476. if (nullableReferenceTypes != value)
  1477. {
  1478. nullableReferenceTypes = value;
  1479. OnPropertyChanged();
  1480. }
  1481. }
  1482. }
  1483. bool showDebugInfo;
  1484. [Category("DecompilerSettings.Other")]
  1485. [Description("DecompilerSettings.ShowInfoFromDebugSymbolsIfAvailable")]
  1486. [Browsable(false)]
  1487. public bool ShowDebugInfo {
  1488. get { return showDebugInfo; }
  1489. set {
  1490. if (showDebugInfo != value)
  1491. {
  1492. showDebugInfo = value;
  1493. OnPropertyChanged();
  1494. }
  1495. }
  1496. }
  1497. #region Options to aid VB decompilation
  1498. bool assumeArrayLengthFitsIntoInt32 = true;
  1499. /// <summary>
  1500. /// Gets/Sets whether the decompiler can assume that 'ldlen; conv.i4.ovf'
  1501. /// does not throw an overflow exception.
  1502. /// </summary>
  1503. [Category("DecompilerSettings.VBSpecificOptions")]
  1504. [Browsable(false)]
  1505. public bool AssumeArrayLengthFitsIntoInt32 {
  1506. get { return assumeArrayLengthFitsIntoInt32; }
  1507. set {
  1508. if (assumeArrayLengthFitsIntoInt32 != value)
  1509. {
  1510. assumeArrayLengthFitsIntoInt32 = value;
  1511. OnPropertyChanged();
  1512. }
  1513. }
  1514. }
  1515. bool introduceIncrementAndDecrement = true;
  1516. /// <summary>
  1517. /// Gets/Sets whether to use increment and decrement operators
  1518. /// </summary>
  1519. [Category("DecompilerSettings.VBSpecificOptions")]
  1520. [Browsable(false)]
  1521. public bool IntroduceIncrementAndDecrement {
  1522. get { return introduceIncrementAndDecrement; }
  1523. set {
  1524. if (introduceIncrementAndDecrement != value)
  1525. {
  1526. introduceIncrementAndDecrement = value;
  1527. OnPropertyChanged();
  1528. }
  1529. }
  1530. }
  1531. bool makeAssignmentExpressions = true;
  1532. /// <summary>
  1533. /// Gets/Sets whether to use assignment expressions such as in while ((count = Do()) != 0) ;
  1534. /// </summary>
  1535. [Category("DecompilerSettings.VBSpecificOptions")]
  1536. [Browsable(false)]
  1537. public bool MakeAssignmentExpressions {
  1538. get { return makeAssignmentExpressions; }
  1539. set {
  1540. if (makeAssignmentExpressions != value)
  1541. {
  1542. makeAssignmentExpressions = value;
  1543. OnPropertyChanged();
  1544. }
  1545. }
  1546. }
  1547. #endregion
  1548. #region Options to aid F# decompilation
  1549. bool removeDeadCode = false;
  1550. [Category("DecompilerSettings.FSpecificOptions")]
  1551. [Description("DecompilerSettings.RemoveDeadAndSideEffectFreeCodeUseWithCaution")]
  1552. public bool RemoveDeadCode {
  1553. get { return removeDeadCode; }
  1554. set {
  1555. if (removeDeadCode != value)
  1556. {
  1557. removeDeadCode = value;
  1558. OnPropertyChanged();
  1559. }
  1560. }
  1561. }
  1562. bool removeDeadStores = false;
  1563. [Category("DecompilerSettings.FSpecificOptions")]
  1564. [Description("DecompilerSettings.RemoveDeadStores")]
  1565. public bool RemoveDeadStores {
  1566. get { return removeDeadStores; }
  1567. set {
  1568. if (removeDeadStores != value)
  1569. {
  1570. removeDeadStores = value;
  1571. OnPropertyChanged();
  1572. }
  1573. }
  1574. }
  1575. #endregion
  1576. #region Assembly Load and Resolve options
  1577. bool loadInMemory = false;
  1578. [Browsable(false)]
  1579. public bool LoadInMemory {
  1580. get { return loadInMemory; }
  1581. set {
  1582. if (loadInMemory != value)
  1583. {
  1584. loadInMemory = value;
  1585. OnPropertyChanged();
  1586. }
  1587. }
  1588. }
  1589. bool throwOnAssemblyResolveErrors = true;
  1590. [Browsable(false)]
  1591. public bool ThrowOnAssemblyResolveErrors {
  1592. get { return throwOnAssemblyResolveErrors; }
  1593. set {
  1594. if (throwOnAssemblyResolveErrors != value)
  1595. {
  1596. throwOnAssemblyResolveErrors = value;
  1597. OnPropertyChanged();
  1598. }
  1599. }
  1600. }
  1601. bool applyWindowsRuntimeProjections = true;
  1602. [Category("DecompilerSettings.Other")]
  1603. [Description("DecompilerSettings.ApplyWindowsRuntimeProjectionsOnLoadedAssemblies")]
  1604. public bool ApplyWindowsRuntimeProjections {
  1605. get { return applyWindowsRuntimeProjections; }
  1606. set {
  1607. if (applyWindowsRuntimeProjections != value)
  1608. {
  1609. applyWindowsRuntimeProjections = value;
  1610. OnPropertyChanged();
  1611. }
  1612. }
  1613. }
  1614. #endregion
  1615. bool forStatement = true;
  1616. /// <summary>
  1617. /// Gets/sets whether the decompiler should produce for loops.
  1618. /// </summary>
  1619. [Category("C# 1.0 / VS .NET")]
  1620. [Description("DecompilerSettings.ForStatement")]
  1621. public bool ForStatement {
  1622. get { return forStatement; }
  1623. set {
  1624. if (forStatement != value)
  1625. {
  1626. forStatement = value;
  1627. OnPropertyChanged();
  1628. }
  1629. }
  1630. }
  1631. bool doWhileStatement = true;
  1632. /// <summary>
  1633. /// Gets/sets whether the decompiler should produce do-while loops.
  1634. /// </summary>
  1635. [Category("C# 1.0 / VS .NET")]
  1636. [Description("DecompilerSettings.DoWhileStatement")]
  1637. public bool DoWhileStatement {
  1638. get { return doWhileStatement; }
  1639. set {
  1640. if (doWhileStatement != value)
  1641. {
  1642. doWhileStatement = value;
  1643. OnPropertyChanged();
  1644. }
  1645. }
  1646. }
  1647. bool separateLocalVariableDeclarations = false;
  1648. /// <summary>
  1649. /// Gets/sets whether the decompiler should separate local variable declarations
  1650. /// from their initialization.
  1651. /// </summary>
  1652. [Category("DecompilerSettings.Other")]
  1653. [Description("DecompilerSettings.SeparateLocalVariableDeclarations")]
  1654. public bool SeparateLocalVariableDeclarations {
  1655. get { return separateLocalVariableDeclarations; }
  1656. set {
  1657. if (separateLocalVariableDeclarations != value)
  1658. {
  1659. separateLocalVariableDeclarations = value;
  1660. OnPropertyChanged();
  1661. }
  1662. }
  1663. }
  1664. bool useSdkStyleProjectFormat = true;
  1665. /// <summary>
  1666. /// Gets or sets a value indicating whether the new SDK style format
  1667. /// shall be used for the generated project files.
  1668. /// </summary>
  1669. [Category("DecompilerSettings.ProjectExport")]
  1670. [Description("DecompilerSettings.UseSdkStyleProjectFormat")]
  1671. public bool UseSdkStyleProjectFormat {
  1672. get { return useSdkStyleProjectFormat; }
  1673. set {
  1674. if (useSdkStyleProjectFormat != value)
  1675. {
  1676. useSdkStyleProjectFormat = value;
  1677. OnPropertyChanged();
  1678. }
  1679. }
  1680. }
  1681. bool useNestedDirectoriesForNamespaces;
  1682. /// <summary>
  1683. /// Gets/sets whether namespaces and namespace-like identifiers should be split at '.'
  1684. /// and each part should produce a new level of nesting in the output directory structure.
  1685. /// </summary>
  1686. [Category("DecompilerSettings.ProjectExport")]
  1687. [Description("DecompilerSettings.UseNestedDirectoriesForNamespaces")]
  1688. public bool UseNestedDirectoriesForNamespaces {
  1689. get { return useNestedDirectoriesForNamespaces; }
  1690. set {
  1691. if (useNestedDirectoriesForNamespaces != value)
  1692. {
  1693. useNestedDirectoriesForNamespaces = value;
  1694. OnPropertyChanged();
  1695. }
  1696. }
  1697. }
  1698. bool aggressiveScalarReplacementOfAggregates = false;
  1699. [Category("DecompilerSettings.Other")]
  1700. [Description("DecompilerSettings.AggressiveScalarReplacementOfAggregates")]
  1701. // TODO : Remove once https://github.com/icsharpcode/ILSpy/issues/2032 is fixed.
  1702. #if !DEBUG
  1703. [Browsable(false)]
  1704. #endif
  1705. public bool AggressiveScalarReplacementOfAggregates {
  1706. get { return aggressiveScalarReplacementOfAggregates; }
  1707. set {
  1708. if (aggressiveScalarReplacementOfAggregates != value)
  1709. {
  1710. aggressiveScalarReplacementOfAggregates = value;
  1711. OnPropertyChanged();
  1712. }
  1713. }
  1714. }
  1715. bool aggressiveInlining = false;
  1716. /// <summary>
  1717. /// If set to false (the default), the decompiler will inline local variables only when they occur
  1718. /// in a context where the C# compiler is known to emit compiler-generated locals.
  1719. /// If set to true, the decompiler will inline local variables whenever possible.
  1720. /// </summary>
  1721. [Category("DecompilerSettings.Other")]
  1722. [Description("DecompilerSettings.AggressiveInlining")]
  1723. public bool AggressiveInlining {
  1724. get { return aggressiveInlining; }
  1725. set {
  1726. if (aggressiveInlining != value)
  1727. {
  1728. aggressiveInlining = value;
  1729. OnPropertyChanged();
  1730. }
  1731. }
  1732. }
  1733. bool alwaysUseGlobal = false;
  1734. /// <summary>
  1735. /// Always fully qualify namespaces using the "global::" prefix.
  1736. /// </summary>
  1737. [Category("DecompilerSettings.Other")]
  1738. [Description("DecompilerSettings.AlwaysUseGlobal")]
  1739. public bool AlwaysUseGlobal {
  1740. get { return alwaysUseGlobal; }
  1741. set {
  1742. if (alwaysUseGlobal != value)
  1743. {
  1744. alwaysUseGlobal = value;
  1745. OnPropertyChanged();
  1746. }
  1747. }
  1748. }
  1749. CSharpFormattingOptions csharpFormattingOptions;
  1750. [Browsable(false)]
  1751. public CSharpFormattingOptions CSharpFormattingOptions {
  1752. get {
  1753. if (csharpFormattingOptions == null)
  1754. {
  1755. csharpFormattingOptions = FormattingOptionsFactory.CreateAllman();
  1756. csharpFormattingOptions.IndentSwitchBody = false;
  1757. csharpFormattingOptions.ArrayInitializerWrapping = Wrapping.WrapIfTooLong;
  1758. csharpFormattingOptions.AutoPropertyFormatting = PropertyFormatting.SingleLine;
  1759. }
  1760. return csharpFormattingOptions;
  1761. }
  1762. set {
  1763. if (value == null)
  1764. throw new ArgumentNullException();
  1765. if (csharpFormattingOptions != value)
  1766. {
  1767. csharpFormattingOptions = value;
  1768. OnPropertyChanged();
  1769. }
  1770. }
  1771. }
  1772. public event PropertyChangedEventHandler PropertyChanged;
  1773. protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  1774. {
  1775. if (PropertyChanged != null)
  1776. {
  1777. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  1778. }
  1779. }
  1780. public DecompilerSettings Clone()
  1781. {
  1782. DecompilerSettings settings = (DecompilerSettings)MemberwiseClone();
  1783. if (csharpFormattingOptions != null)
  1784. settings.csharpFormattingOptions = csharpFormattingOptions.Clone();
  1785. settings.PropertyChanged = null;
  1786. return settings;
  1787. }
  1788. }
  1789. }